From 01b92d759072b3375e2d4500a8d1dac8d699f369 Mon Sep 17 00:00:00 2001 From: Andrew Moore Date: Thu, 12 Jul 2018 15:37:13 -0300 Subject: [PATCH 01/15] Updating version for esdoc. --- package-lock.json | 398 ++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 212 insertions(+), 188 deletions(-) diff --git a/package-lock.json b/package-lock.json index b301f25..02e8704 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/node": { + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.2.tgz", + "integrity": "sha512-m9zXmifkZsMHZBOyxZWilMwmTlpC8x5Ty360JKTiXvlXZfBWYpsg9ZZvP/Ye+iZUh+Q+MxDLjItVTWIsfwz+8Q==", + "dev": true + }, "JSONStream": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.3.tgz", @@ -14,6 +20,10 @@ "through": ">=2.2.7 <3" } }, + "ReconnectingWebSocket": { + "version": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148", + "from": "git+https://github.com/svk31/reconnecting-websocket.git" + }, "abab": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", @@ -79,13 +89,6 @@ "json-schema-traverse": "^0.3.0" } }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true, - "optional": true - }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -1190,17 +1193,17 @@ } }, "cheerio": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz", - "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=", + "version": "1.0.0-rc.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", + "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", "dev": true, "requires": { "css-select": "~1.2.0", "dom-serializer": "~0.1.0", "entities": "~1.1.1", - "htmlparser2": "~3.8.1", - "jsdom": "^7.0.2", - "lodash": "^4.1.0" + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" } }, "chokidar": { @@ -1238,9 +1241,9 @@ "optional": true }, "color-logger": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/color-logger/-/color-logger-0.0.3.tgz", - "integrity": "sha1-2bIt0dlz4Waxi/MT+fSBu6TfIBg=", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/color-logger/-/color-logger-0.0.6.tgz", + "integrity": "sha1-5WJF7ymCJlcRDHy3WpzXhstp7Rs=", "dev": true }, "combine-source-map": { @@ -1491,7 +1494,8 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "dev": true, + "optional": true }, "defined": { "version": "1.0.0", @@ -1594,9 +1598,9 @@ "dev": true }, "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", "dev": true, "requires": { "domelementtype": "1" @@ -1691,9 +1695,9 @@ } }, "escape-html": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.2.tgz", - "integrity": "sha1-130y+pjjjC9BroXpJ44ODmuhAiw=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", "dev": true }, "escape-string-regexp": { @@ -1703,87 +1707,68 @@ "dev": true }, "escodegen": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.7.0.tgz", - "integrity": "sha1-TimdjMMwh7fynBniuehDYqvjVFM=", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.10.0.tgz", + "integrity": "sha512-fjUOf8johsv23WuIKdNQU4P9t9jhQ4Qzx6pC2uW890OloK3Zs1ZAoCNpg/2larNF501jLl3UNy0kIRcF6VI22g==", "dev": true, + "optional": true, "requires": { - "esprima": "^1.2.2", - "estraverse": "^1.9.1", + "esprima": "^3.1.3", + "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.5.0", - "source-map": "~0.2.0" + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "dependencies": { - "esprima": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.5.tgz", - "integrity": "sha1-CZNQL+r2aBODJXVvMPmlH+7sEek=", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } + "optional": true } } }, "esdoc": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/esdoc/-/esdoc-0.4.8.tgz", - "integrity": "sha1-SXLitt6F4rkpozDtVLjF8/3OvTM=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esdoc/-/esdoc-1.1.0.tgz", + "integrity": "sha512-vsUcp52XJkOWg9m1vDYplGZN2iDzvmjDL5M/Mp8qkoDG3p2s0yIQCIjKR5wfPBaM3eV14a6zhQNYiNTCVzPnxA==", "dev": true, "requires": { - "cheerio": "0.20.0", - "color-logger": "0.0.3", - "core-js": "0.9.18", - "escape-html": "1.0.2", - "escodegen": "1.7.0", - "espree": "2.2.0", - "estraverse": "4.1.0", - "fs-extra": "0.26.5", + "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.5", - "minimist": "1.1.1", - "taffydb": "2.7.2" + "marked": "0.3.19", + "minimist": "1.2.0", + "taffydb": "2.7.3" }, "dependencies": { - "core-js": { - "version": "0.9.18", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-0.9.18.tgz", - "integrity": "sha1-E/RY5DAjKw9OwfSA2nwvUojp0JU=", - "dev": true - }, "minimist": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.1.tgz", - "integrity": "sha1-G8K8cWWM3KVxJHVoQ2NhWwtPaVs=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } } }, - "espree": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-2.2.0.tgz", - "integrity": "sha1-AdySen6lCB0ae21hAknmJOf+89Y=", - "dev": true + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true, + "optional": true }, "estraverse": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.0.tgz", - "integrity": "sha1-QPI6dgkgQb5kZ9fyNckztnB2bgU=", - "dev": true + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true, + "optional": true }, "esutils": { "version": "2.0.2", @@ -1874,10 +1859,11 @@ "optional": true }, "fast-levenshtein": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz", - "integrity": "sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk=", - "dev": true + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true, + "optional": true }, "filename-regex": { "version": "2.0.1", @@ -1937,16 +1923,14 @@ } }, "fs-extra": { - "version": "0.26.5", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.5.tgz", - "integrity": "sha1-U6x0Znygg/0twXEsgTA5yjLWmn8=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", "dev": true, "requires": { "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, "fs-readdir-recursive": { @@ -2647,48 +2631,17 @@ "dev": true }, "htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", + "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", "dev": true, "requires": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" - }, - "dependencies": { - "entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } + "domelementtype": "^1.3.0", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" } }, "http-signature": { @@ -2717,6 +2670,82 @@ "requires": { "cheerio": "0.20.0", "color-logger": "0.0.3" + }, + "dependencies": { + "cheerio": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz", + "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=", + "dev": true, + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "~3.8.1", + "jsdom": "^7.0.2", + "lodash": "^4.1.0" + } + }, + "color-logger": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/color-logger/-/color-logger-0.0.3.tgz", + "integrity": "sha1-2bIt0dlz4Waxi/MT+fSBu6TfIBg=", + "dev": true + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + }, + "dependencies": { + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + } + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } } }, "ieee754": { @@ -2986,6 +3015,13 @@ "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", "dev": true, "optional": true + }, + "parse5": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", + "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", + "dev": true, + "optional": true } } }, @@ -3032,9 +3068,9 @@ "dev": true }, "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { "graceful-fs": "^4.1.6" @@ -3074,15 +3110,6 @@ "is-buffer": "^1.1.5" } }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, "labeled-stream-splicer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", @@ -3103,13 +3130,14 @@ } }, "levn": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz", - "integrity": "sha1-uo0znQykphDjo/FFucr0iAcVUFQ=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, + "optional": true, "requires": { - "prelude-ls": "~1.1.0", - "type-check": "~0.3.1" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "lodash": { @@ -3157,9 +3185,9 @@ "dev": true }, "marked": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.5.tgz", - "integrity": "sha1-QROhWsXXvKFYpargciRYe5+hW5Q=", + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", + "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==", "dev": true }, "math-random": { @@ -3440,17 +3468,18 @@ } }, "optionator": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.5.0.tgz", - "integrity": "sha1-t1qJlaLUF98ltuTjhi9QqohlE2g=", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, + "optional": true, "requires": { - "deep-is": "~0.1.2", - "fast-levenshtein": "~1.0.0", - "levn": "~0.2.5", - "prelude-ls": "~1.1.1", - "type-check": "~0.3.1", - "wordwrap": "~0.0.2" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, "options": { @@ -3529,11 +3558,13 @@ } }, "parse5": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", - "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", "dev": true, - "optional": true + "requires": { + "@types/node": "*" + } }, "path-browserify": { "version": "0.0.1", @@ -3577,13 +3608,8 @@ "resolved": "https://registry.npmjs.org/peerplaysjs-ws/-/peerplaysjs-ws-0.1.11.tgz", "integrity": "sha1-6q6x5yXurfWcpgJ8Zx8yDXAlG+8=", "requires": { + "ReconnectingWebSocket": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148", "ws": "^1.1.4" - }, - "dependencies": { - "ReconnectingWebSocket": { - "version": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148", - "from": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148" - } } }, "performance-now": { @@ -3898,15 +3924,6 @@ "path-parse": "^1.0.5" } }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -4130,9 +4147,9 @@ } }, "taffydb": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.7.2.tgz", - "integrity": "sha1-e/gQalwaSCUbPjvAoOFzJIn9Dcg=", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.7.3.tgz", + "integrity": "sha1-KtNxaWKUmPylvIQkMJbTzeDsOjQ=", "dev": true }, "through": { @@ -4269,6 +4286,12 @@ "xtend": "^4.0.1" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", @@ -4371,10 +4394,11 @@ } }, "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true, + "optional": true }, "wrappy": { "version": "1.0.2", diff --git a/package.json b/package.json index 689ed0c..e89293c 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "babel-preset-es2015": "^6.24.1", "babel-preset-es2015-generators-async": "^6.3.13", "browserify": "^13.1.0", - "esdoc": "^0.4.3", + "esdoc": "^1.1.0", "mocha": "^2.5.3", "uglifyjs": "^2.4.10" } From 6248ea80e6f13327f99b138cbed4a67b7f5d34ef Mon Sep 17 00:00:00 2001 From: Andrew Moore Date: Thu, 12 Jul 2018 15:38:21 -0300 Subject: [PATCH 02/15] Fixing typo, sorry jcalfee! --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8939118..014fb81 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Pure JavaScript Bitshares/Graphene library for node.js and browsers. Can be used to construct, sign and broadcast transactions in JavaScript, and to easily obtain data from the blockchain via public apis. -Most of this code was written by [jcalfeee](https://github.com/jcalfee), my work was mostly just repackaging to a discrete npm package. +Most of this code was written by [jcalfee](https://github.com/jcalfee), my work was mostly just repackaging to a discrete npm package. ## Setup From a6f93ba3204f3369ad1735844a37376583ae94b4 Mon Sep 17 00:00:00 2001 From: Andrew Moore Date: Thu, 12 Jul 2018 15:41:47 -0300 Subject: [PATCH 03/15] 0.4.20 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02e8704..24fe245 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "peerplaysjs-lib", - "version": "0.4.19", + "version": "0.4.20", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e89293c..9b521be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "peerplaysjs-lib", - "version": "0.4.19", + "version": "0.4.20", "description": "Pure JavaScript Peerplays/Graphene library for node.js and browsers.", "browser": { "ws": false, From 5b560e33f8c6d694459e76afa4b7042f0520e617 Mon Sep 17 00:00:00 2001 From: mseaward Date: Fri, 1 Feb 2019 14:40:04 -0400 Subject: [PATCH 04/15] Use last known version of ppjs-lib and add function. --- lib/chain/src/ChainStore.js | 28 +++++++++++++++++++++++++++- package-lock.json | 23 ++++++++++++----------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/lib/chain/src/ChainStore.js b/lib/chain/src/ChainStore.js index 9dc0d16..180b156 100644 --- a/lib/chain/src/ChainStore.js +++ b/lib/chain/src/ChainStore.js @@ -735,7 +735,33 @@ class ChainStore { } return null } - + + /** + * + * @returns a promise with a list of all witness ids. Regardless of if they have been voted in or not. + * @memberof ChainStore + */ + fetchWitnessAccounts() { + var _this24 = this; + return new Promise((resolve, reject) => { + Apis.instance().db_api().exec("lookup_witness_accounts", [0, 1000]).then(function (w) { + if (w) { + let witnessArr = []; + + for (let i = 0, length = w.length; i < length; i++) { + witnessArr.push(w[i][1]); // ids only + } + + _this24.witnesses = _this24.witnesses.merge(witnessArr); + _this24._updateObject(witnessArr, true); + resolve(_this24.witnesses); + } else { + resolve(null); + } + }); + }); + } + /** * * @return a promise with the witness object diff --git a/package-lock.json b/package-lock.json index 24fe245..38f6962 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,10 +20,6 @@ "through": ">=2.2.7 <3" } }, - "ReconnectingWebSocket": { - "version": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148", - "from": "git+https://github.com/svk31/reconnecting-websocket.git" - }, "abab": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", @@ -880,7 +876,7 @@ }, "base-x": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w=" }, "base64-js": { @@ -1371,7 +1367,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { "cipher-base": "^1.0.1", @@ -1383,7 +1379,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "requires": { "cipher-base": "^1.0.3", @@ -1454,7 +1450,7 @@ }, "d": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { "es5-ext": "^0.10.9" @@ -3400,7 +3396,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "normalize-path": { @@ -3608,8 +3604,13 @@ "resolved": "https://registry.npmjs.org/peerplaysjs-ws/-/peerplaysjs-ws-0.1.11.tgz", "integrity": "sha1-6q6x5yXurfWcpgJ8Zx8yDXAlG+8=", "requires": { - "ReconnectingWebSocket": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148", "ws": "^1.1.4" + }, + "dependencies": { + "ReconnectingWebSocket": { + "version": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148", + "from": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148" + } } }, "performance-now": { @@ -3966,7 +3967,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { "inherits": "^2.0.1", From 702d4c051b1759ff313908e35d17949c2799d21d Mon Sep 17 00:00:00 2001 From: mseaward Date: Fri, 1 Feb 2019 14:54:21 -0400 Subject: [PATCH 05/15] Uodate scripts --- package.json | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 9b521be..8f1dc30 100644 --- a/package.json +++ b/package.json @@ -7,20 +7,23 @@ "crypto": false }, "scripts": { - "test": "mocha --compilers js:babel-core/register --recursive", - "test:chain": "mocha --compilers js:babel-core/register ./test/chain --recursive", - "test:ecc": "mocha --compilers js:babel-core/register ./test/ecc --recursive", - "test:serializer": "mocha --compilers js:babel-core/register ./test/serializer --recursive", - "test:watch": "npm test -- --watch", - "clean": "rm -rf ./dist/* & rm -rf ./build/*", - "prebuild": "npm run clean", - "build": "babel lib --presets es2015-generators-async --plugins transform-async-to-generator --out-dir dist", - "build:watch": "babel lib --presets es2015-generators-async --out-dir dist --watch", - "prebrowserify": "rm -rf ./build/*", - "browserify": "browserify --full-paths dist/browser.js --standalone steemJS -o build/peerplaysjs-lib.js -d", - "postbrowserify": "uglifyjs --compress --mangle --sequences --drop_console --output build/peerplaysjs-lib.min.js -- build/peerplaysjs-lib.js", - "prepublish": "npm run build", - "doc": "esdoc -c esdoc.json" + "test": "BABEL_ENV=test mocha --compilers js:babel-register --recursive", + "test:chain": "BABEL_ENV=test mocha --compilers js:babel-register ./test/chain --recursive", + "test:ecc": "BABEL_ENV=test mocha --compilers js:babel-register ./test/ecc --recursive", + "test:serializer": "BABEL_ENV=test mocha --compilers js:babel-register ./test/serializer --recursive", + "test:watch": "npm test -- --watch", + "clean": "rm -rf ./dist/* & rm -rf ./build/*", + "prebuild": "npm run clean", + "build": "babel lib -d dist", + "postbuild": "npm run browserify", + "build:watch": "babel lib -d dist --watch", + "prebrowserify": "rm -rf ./build/*", + "browserify": "browserify -t [browserify-package-json --global=true] -p [bundle-collapser/plugin] dist/browser.js --full-path=false --standalone peerplays_js -o build/peerplaysjs-lib.js -d", + "postbrowserify": "uglifyjs --compress --mangle --sequences --drop_console --output build/peerplaysjs-lib.min.js -- build/peerplaysjs-lib.js", + "doc": "esdoc -c esdoc.json", + "example:transfer": "babel-node examples/transfer", + "example:chainStore": "babel-node examples/chainStore", + "example:privKey": "babel-node examples/privKey" }, "repository": { "type": "git", From 6dd1c9d3b9bbbcf0385844d18cf3c0bbc7955592 Mon Sep 17 00:00:00 2001 From: mseaward Date: Fri, 1 Feb 2019 15:18:10 -0400 Subject: [PATCH 06/15] Modify scripts --- build/peerplaysjs-lib.js | 26144 +++++++++++++++++++++++++++++++++ build/peerplaysjs-lib.min.js | 1 + package-lock.json | 2052 ++- package.json | 154 +- 4 files changed, 28062 insertions(+), 289 deletions(-) create mode 100644 build/peerplaysjs-lib.js create mode 100644 build/peerplaysjs-lib.min.js diff --git a/build/peerplaysjs-lib.js b/build/peerplaysjs-lib.js new file mode 100644 index 0000000..d42ed5e --- /dev/null +++ b/build/peerplaysjs-lib.js @@ -0,0 +1,26144 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.peerplays_js = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i} [signer_pubkeys = null] - Optional ["GPHAbc9Def0...", ...]. These are + additional signing keys. Some balance claims require propritary address formats, the + witness node can't tell us which ones are needed so they must be passed in. If the + witness node can figure out a signing key (mostly all other transactions), it should + not be passed in here. + @arg {boolean} [broadcast = false] + */ + + + TransactionBuilder.prototype.process_transaction = function process_transaction(cwallet) { + var _this = this; + + var signer_pubkeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var broadcast = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var wallet_object = cwallet.wallet.wallet_object; + + + if (_peerplaysjsWs.Apis.instance().chain_id !== wallet_object.get('chain_id')) { + var wallet_chain_id = wallet_object.get('chain_id'); + var api_chain_id = _peerplaysjsWs.Apis.instance().chain_id; + + var error = new Error('Mismatched chain_id; expecting ' + wallet_chain_id + ', but got ' + api_chain_id); + + return Promise.reject(error); + } + + return this.set_required_fees().then(function () { + var signer_pubkeys_added = {}; + + if (signer_pubkeys) { + // Balance claims are by address, only the private + // key holder can know about these additional + // potential keys. + var pubkeys = cwallet.getPubkeys_having_PrivateKey(signer_pubkeys); + + if (!pubkeys.length) { + throw new Error('Missing signing key'); + } + + var keys = Object.keys(pubkeys); + + for (var i = 0, len = keys.length; i < len; i++) { + var pubkey_string = pubkeys[i]; + var private_key = cwallet.getPrivateKey(pubkey_string); + _this.add_signer(private_key, pubkey_string); + signer_pubkeys_added[pubkey_string] = true; + } + } + + return _this.get_potential_signatures().then(function (_ref) { + var pubkeys = _ref.pubkeys, + addys = _ref.addys; + + var my_pubkeys = cwallet.getPubkeys_having_PrivateKey(pubkeys, addys); + + return _this.get_required_signatures(my_pubkeys).then(function (required_pubkeys) { + var keys = Object.keys(required_pubkeys); + + for (var _i = 0, _len = keys.length; _i < _len; _i++) { + var _pubkey_string = keys[_i]; + + if (!signer_pubkeys_added[_pubkey_string]) { + var _private_key = cwallet.getPrivateKey(_pubkey_string); + + // This should not happen, get_required_signatures will only + // returned keys from my_pubkeys + if (!_private_key) { + throw new Error('Missing signing key for ' + _pubkey_string); + } + + _this.add_signer(_private_key, _pubkey_string); + } + } + }); + }).then(function () { + return broadcast ? _this.broadcast() : _this.serialize(); + }); + }); + }; + + /** Typically this is called automatically just prior to signing. + * Once finalized this transaction can not be changed. */ + + + TransactionBuilder.prototype.finalize = function finalize() { + var _this2 = this; + + return new Promise(function (resolve) { + if (_this2.tr_buffer) { + throw new Error('already finalized'); + } + + resolve(_peerplaysjsWs.Apis.instance().db_api().exec('get_objects', [['2.1.0']]).then(function (r) { + _this2.head_block_time_string = r[0].time; + + if (_this2.expiration === 0) { + _this2.expiration = _this2.base_expiration_sec() + _peerplaysjsWs.ChainConfig.expire_in_secs; + } + + _this2.ref_block_num = r[0].head_block_number & 0xffff; // eslint-disable-line + _this2.ref_block_prefix = Buffer.from(r[0].head_block_id, 'hex').readUInt32LE(4); + // DEBUG console.log("ref_block",@ref_block_num,@ref_block_prefix,r) + + var iterable = _this2.operations; + + for (var i = 0, len = iterable.length; i < len; i++) { + var op = iterable[i]; + + if (op[1].finalize) { + op[1].finalize(); + } + + var _type = _serializer.ops.operation.st_operations[op[0]]; + var hexBuffer = _type.toBuffer(op[1]).toString('hex'); + console.log('Operation %s: %O => %s (%d bytes)', _type.operation_name, op[1], hexBuffer, hexBuffer.length / 2); + } + + _this2.tr_buffer = _serializer.ops.transaction.toBuffer(_this2); + })); + }); + }; + + /** @return {string} hex transaction ID */ + + + TransactionBuilder.prototype.id = function id() { + if (!this.tr_buffer) { + throw new Error('not finalized'); + } + + return _ecc.hash.sha256(this.tr_buffer).toString('hex').substring(0, 40); + }; + + /** + Typically one will use {@link this.add_type_operation} instead. + @arg {array} operation - [operation_id, operation] + */ + + + TransactionBuilder.prototype.add_operation = function add_operation(operation) { + if (this.tr_buffer) { + throw new Error('already finalized'); + } + + (0, _assert2.default)(operation, 'operation'); + + if (!Array.isArray(operation)) { + throw new Error('Expecting array [operation_id, operation]'); + } + + this.operations.push(operation); + }; + + TransactionBuilder.prototype.get_type_operation = function get_type_operation(name, operation) { + if (this.tr_buffer) { + throw new Error('already finalized'); + } + + (0, _assert2.default)(name, 'name'); + (0, _assert2.default)(operation, 'operation'); + var _type = _serializer.ops[name]; + (0, _assert2.default)(_type, 'Unknown operation ' + name); + var operation_id = _ChainTypes2.default.operations[_type.operation_name]; + + if (operation_id === undefined) { + throw new Error('unknown operation: ' + _type.operation_name); + } + + if (!operation.fee) { + operation.fee = { amount: 0, asset_id: 0 }; + } + + if (name === 'proposal_create') { + /* + * Proposals involving the committee account require a review + * period to be set, look for them here + */ + var requiresReview = false; + var extraReview = 0; + + operation.proposed_ops.forEach(function (op) { + var COMMITTE_ACCOUNT = 0; + var key = void 0; + + switch (op.op[0]) { + case 0: + // transfer + key = 'from'; + break; + + case 6: // account_update + case 17: + // asset_settle + key = 'account'; + break; + + case 10: // asset_create + case 11: // asset_update + case 12: // asset_update_bitasset + case 13: // asset_update_feed_producers + case 14: // asset_issue + case 18: // asset_global_settle + case 43: + // asset_claim_fees + key = 'issuer'; + break; + + case 15: + // asset_reserve + key = 'payer'; + break; + + case 16: + // asset_fund_fee_pool + key = 'from_account'; + break; + + case 22: // proposal_create + case 23: // proposal_update + case 24: + // proposal_delete + key = 'fee_paying_account'; + break; + + case 31: + // committee_member_update_global_parameters + requiresReview = true; + extraReview = 60 * 60 * 24 * 13; // Make the review period 2 weeks total + break; + default: + break; + } + + if (key in op.op[1] && op.op[1][key] === COMMITTE_ACCOUNT) { + requiresReview = true; + } + }); + + if (!operation.expiration_time) { + var experationTime = this.base_expiration_sec(); + operation.expiration_time = experationTime + _peerplaysjsWs.ChainConfig.expire_in_secs_proposal; + } + + if (requiresReview) { + var one_day = 24 * 60 * 60; // One day in seconds + var max = Math.max(this.commitee_min_review, one_day, _peerplaysjsWs.ChainConfig.review_in_secs_committee); + + operation.review_period_seconds = extraReview + max; + /* + * Expiration time must be at least equal to + * now + review_period_seconds, so we add one hour to make sure + */ + operation.expiration_time += 60 * 60 + extraReview; + } + } + + var operation_instance = _type.fromObject(operation); + return [operation_id, operation_instance]; + }; + + /* optional: fetch the current head block */ + + TransactionBuilder.prototype.update_head_block = function update_head_block() { + var _this3 = this; + + return _peerplaysjsWs.Apis.instance().db_api().exec('get_objects', [['2.0.0', '2.1.0']]).then(function (res) { + var g = res[0], + r = res[1]; + + _this3.head_block_time_string = r[0].time; + _this3.committee_min_review = g[0].parameters.committee_proposal_review_period; + }); + }; + + /** optional: there is a deafult expiration */ + + + TransactionBuilder.prototype.set_expire_seconds = function set_expire_seconds(sec) { + if (this.tr_buffer) { + throw new Error('already finalized'); + } + + this.expiration = this.base_expiration_sec() + sec; + + return this.expiration; + }; + + /* Wraps this transaction in a proposal_create transaction */ + + + TransactionBuilder.prototype.propose = function propose(proposal_create_options) { + if (this.tr_buffer) { + throw new Error('already finalized'); + } + + if (!this.operations.length) { + throw new Error('add operation first'); + } + + (0, _assert2.default)(proposal_create_options, 'proposal_create_options'); + (0, _assert2.default)(proposal_create_options.fee_paying_account, 'proposal_create_options.fee_paying_account'); + + var proposed_ops = this.operations.map(function (op) { + return { op: op }; + }); + + this.operations = []; + this.signatures = []; + this.signer_private_keys = []; + proposal_create_options.proposed_ops = proposed_ops; + this.add_type_operation('proposal_create', proposal_create_options); + return this; + }; + + TransactionBuilder.prototype.has_proposed_operation = function has_proposed_operation() { + var hasProposed = false; + + for (var i = 0; i < this.operations.length; i++) { + if ('proposed_ops' in this.operations[i][1]) { + hasProposed = true; + break; + } + } + + return hasProposed; + }; + + /** optional: the fees can be obtained from the witness node */ + + + TransactionBuilder.prototype.set_required_fees = function set_required_fees(asset_id) { + var _this4 = this; + + var fee_pool = void 0; + + if (this.tr_buffer) { + throw new Error('already finalized'); + } + + if (!this.operations.length) { + throw new Error('add operations first'); + } + + var operations = []; + + for (var i = 0, len = this.operations.length; i < len; i++) { + var op = this.operations[i]; + operations.push(_serializer.ops.operation.toObject(op)); + } + + if (!asset_id) { + var op1_fee = operations[0][1].fee; + + if (op1_fee && op1_fee.asset_id !== null) { + asset_id = op1_fee.asset_id; + } else { + asset_id = '1.3.0'; + } + } + + var promises = [_peerplaysjsWs.Apis.instance().db_api().exec('get_required_fees', [operations, asset_id])]; + + if (asset_id !== '1.3.0') { + // This handles the fallback to paying fees in BTS if the fee pool is empty. + promises.push(_peerplaysjsWs.Apis.instance().db_api().exec('get_required_fees', [operations, '1.3.0'])); + promises.push(_peerplaysjsWs.Apis.instance().db_api().exec('get_objects', [[asset_id]])); + } + + return Promise.all(promises).then(function (results) { + var fees = results[0], + coreFees = results[1], + asset = results[2]; + + asset = asset ? asset[0] : null; + + var dynamicPromise = asset_id !== '1.3.0' && asset ? _peerplaysjsWs.Apis.instance().db_api().exec('get_objects', [[asset.dynamic_asset_data_id]]) : new Promise(function (resolve) { + resolve(); + }); + + return dynamicPromise.then(function (dynamicObject) { + if (asset_id !== '1.3.0') { + fee_pool = dynamicObject ? dynamicObject[0].fee_pool : 0; + var totalFees = 0; + + for (var j = 0, fee; j < coreFees.length; j++) { + fee = coreFees[j]; + totalFees += fee.amount; + } + + if (totalFees > parseInt(fee_pool, 10)) { + fees = coreFees; + asset_id = '1.3.0'; + } + } + + // Proposed transactions need to be flattened + var flat_assets = []; + + var flatten = function flatten(obj) { + if (Array.isArray(obj)) { + for (var k = 0, _len2 = obj.length; k < _len2; k++) { + var item = obj[k]; + flatten(item); + } + } else { + flat_assets.push(obj); + } + }; + + flatten(fees); + + var asset_index = 0; + + var set_fee = function set_fee(operation) { + if (!operation.fee || operation.fee.amount === 0 || operation.fee.amount.toString && operation.fee.amount.toString() === '0' // Long + ) { + operation.fee = flat_assets[asset_index]; + // console.log("new operation.fee", operation.fee) + } else { + // console.log("old operation.fee", operation.fee) + } + + asset_index++; + + if (operation.proposed_ops) { + var result = []; + + for (var y = 0; y < operation.proposed_ops.length; y++) { + result.push(set_fee(operation.proposed_ops[y].op[1])); + } + + return result; + } + }; + + for (var _i2 = 0; _i2 < _this4.operations.length; _i2++) { + set_fee(_this4.operations[_i2][1]); + } + }); + // DEBUG console.log('... get_required_fees',operations,asset_id,flat_assets) + }); + }; + + TransactionBuilder.prototype.get_potential_signatures = function get_potential_signatures() { + var tr_object = _serializer.ops.signed_transaction.toObject(this); + return Promise.all([_peerplaysjsWs.Apis.instance().db_api().exec('get_potential_signatures', [tr_object]), _peerplaysjsWs.Apis.instance().db_api().exec('get_potential_address_signatures', [tr_object])]).then(function (results) { + return { pubkeys: results[0], addys: results[1] }; + }); + }; + + TransactionBuilder.prototype.get_required_signatures = function get_required_signatures(available_keys) { + if (!available_keys.length) { + return Promise.resolve([]); + } + + var tr_object = _serializer.ops.signed_transaction.toObject(this); + // DEBUG console.log('... tr_object',tr_object) + return _peerplaysjsWs.Apis.instance().db_api().exec('get_required_signatures', [tr_object, available_keys]).then(function (required_public_keys) { + return required_public_keys; + }); + }; + + TransactionBuilder.prototype.add_signer = function add_signer(private_key) { + var public_key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : private_key.toPublicKey(); + + (0, _assert2.default)(private_key.d, 'required PrivateKey object'); + + if (this.signed) { + throw new Error('already signed'); + } + + if (!public_key.Q) { + public_key = _ecc.PublicKey.fromPublicKeyString(public_key); + } + + // prevent duplicates + var spHex = private_key.toHex(); + + var keys = Object.keys(this.signer_private_keys); + + for (var i = 0, len = keys.length; i < len; i++) { + var sp = this.signer_private_keys[keys[i]]; + + if (sp[0].toHex() === spHex) { + return; + } + } + + this.signer_private_keys.push([private_key, public_key]); + }; + + TransactionBuilder.prototype.sign = function sign() { + var chain_id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.Apis.instance().chain_id; + + if (!this.tr_buffer) { + throw new Error('not finalized'); + } + + if (this.signed) { + throw new Error('already signed'); + } + + if (!this.signer_private_keys.length) { + throw new Error('Transaction was not signed. Do you have a private key? [no_signers]'); + } + + var end = this.signer_private_keys.length; + + for (var i = 0; end > 0 ? i < end : i > end; end > 0 ? i++ : i++) { + var _signer_private_keys$ = this.signer_private_keys[i], + private_key = _signer_private_keys$[0], + public_key = _signer_private_keys$[1]; + + var sig = _ecc.Signature.signBuffer(Buffer.concat([Buffer.from(chain_id, 'hex'), this.tr_buffer]), private_key, public_key); + this.signatures.push(sig.toBuffer()); + } + + this.signer_private_keys = []; + this.signed = true; + }; + + TransactionBuilder.prototype.serialize = function serialize() { + return _serializer.ops.signed_transaction.toObject(this); + }; + + TransactionBuilder.prototype.toObject = function toObject() { + return _serializer.ops.signed_transaction.toObject(this); + }; + + TransactionBuilder.prototype.broadcast = function broadcast(was_broadcast_callback) { + var _this5 = this; + + if (this.tr_buffer) { + return this._broadcast(was_broadcast_callback); + } + + return this.finalize().then(function () { + return _this5._broadcast(was_broadcast_callback); + }); + }; + + TransactionBuilder.prototype._broadcast = function _broadcast(was_broadcast_callback) { + var _this6 = this; + + return new Promise(function (resolve, reject) { + if (!_this6.signed) { + _this6.sign(); + } + + if (!_this6.tr_buffer) { + throw new Error('not finalized'); + } + + if (!_this6.signatures.length) { + throw new Error('not signed'); + } + + if (!_this6.operations.length) { + throw new Error('no operations'); + } + + var tr_object = _serializer.ops.signed_transaction.toObject(_this6); + // console.log('... broadcast_transaction_with_callback !!!') + _peerplaysjsWs.Apis.instance().network_api().exec('broadcast_transaction_with_callback', [function (res) { + return resolve(res); + }, tr_object]).then(function () { + // console.log('... broadcast success, waiting for callback') + if (was_broadcast_callback) { + was_broadcast_callback(); + } + }).catch(function (error) { + // console.log may be redundant for network errors, other errors could occur + console.log(error); + var message = error.message; + + + if (!message) { + message = ''; + } + + reject(new Error(message + '\n' + 'peerplays-crypto ' + (' digest ' + _ecc.hash.sha256(_this6.tr_buffer).toString('hex') + ' transaction ' + _this6.tr_buffer.toString('hex') + ' ' + JSON.stringify(tr_object)))); + }); + }); + }; + + TransactionBuilder.timeStringToDate = function timeStringToDate(time_string) { + if (!time_string) { + time_string = '1970-01-01T00:00:00.000Z'; + } + + if (!/Z$/.test(time_string)) { + // does not end in Z + // https://github.com/cryptonomex/graphene/issues/368 + time_string += 'Z'; + } + + return new Date(time_string); + }; + + TransactionBuilder.prototype.getHeadBlockDate = function getHeadBlockDate() { + return TransactionBuilder.timeStringToDate(this.head_block_time_string); + }; + + TransactionBuilder.prototype.base_expiration_sec = function base_expiration_sec() { + var head_block_sec = Math.ceil(this.getHeadBlockDate().getTime() / 1000); + var now_sec = Math.ceil(Date.now() / 1000); + + // The head block time should be updated every 3 seconds. If it isn't + // then help the transaction to expire (use head_block_sec) + if (now_sec - head_block_sec > 30) { + return head_block_sec; + } + + // If the user's clock is very far behind, use the head block time. + return Math.max(now_sec, head_block_sec); + }; + + return TransactionBuilder; +}(); + +exports.default = TransactionBuilder; +module.exports = exports['default']; +}).call(this,require(35).Buffer) + +},{"19":19,"27":27,"3":3,"35":35,"7":7,"70":70}],6:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; +function get(state) { + return function (key) { + return state[key] || ''; + }; +} + +function set(state) { + var _this = this; + + return function (key, value) { + state[key] = value; + return _this; + }; +} + +exports.get = get; +exports.set = set; +},{}],7:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.key = exports.hash = exports.brainKey = exports.Signature = exports.PublicKey = exports.PrivateKey = exports.Aes = exports.Address = undefined; + +var _address = require(12); + +var _address2 = _interopRequireDefault(_address); + +var _aes = require(13); + +var _aes2 = _interopRequireDefault(_aes); + +var _PrivateKey = require(10); + +var _PrivateKey2 = _interopRequireDefault(_PrivateKey); + +var _PublicKey = require(11); + +var _PublicKey2 = _interopRequireDefault(_PublicKey); + +var _signature = require(18); + +var _signature2 = _interopRequireDefault(_signature); + +var _BrainKey = require(8); + +var _BrainKey2 = _interopRequireDefault(_BrainKey); + +var _hash = require(17); + +var hash = _interopRequireWildcard(_hash); + +var _KeyUtils = require(9); + +var _KeyUtils2 = _interopRequireDefault(_KeyUtils); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.Address = _address2.default; +exports.Aes = _aes2.default; +exports.PrivateKey = _PrivateKey2.default; +exports.PublicKey = _PublicKey2.default; +exports.Signature = _signature2.default; +exports.brainKey = _BrainKey2.default; +exports.hash = hash; +exports.key = _KeyUtils2.default; +},{"10":10,"11":11,"12":12,"13":13,"17":17,"18":18,"8":8,"9":9}],8:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.default = normalize; +function normalize(brainKey) { + if (typeof brainKey !== 'string') { + throw new Error('string required for brainKey'); + } + + brainKey = brainKey.trim(); + return brainKey.split(/[\t\n\v\f\r ]+/).join(' '); +} +module.exports = exports['default']; +},{}],9:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; + +var _secureRandom = require(94); + +var _secureRandom2 = _interopRequireDefault(_secureRandom); + +var _peerplaysjsWs = require(70); + +var _PrivateKey = require(10); + +var _PrivateKey2 = _interopRequireDefault(_PrivateKey); + +var _PublicKey = require(11); + +var _PublicKey2 = _interopRequireDefault(_PublicKey); + +var _address = require(12); + +var _address2 = _interopRequireDefault(_address); + +var _aes = require(13); + +var _aes2 = _interopRequireDefault(_aes); + +var _hash = require(17); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// import dictionary from './dictionary_en'; + +// hash for .25 second +var HASH_POWER_MILLS = 250; + +var key = { + /** Uses 1 second of hashing power to create a key/password checksum. An + implementation can re-call this method with the same password to re-match + the strength of the CPU (either after moving from a desktop to a mobile, + mobile to desktop, or N years from now when CPUs are presumably stronger). + A salt is used for all the normal reasons... + @return object { + aes_private: Aes, + checksum: "{hash_iteration_count},{salt},{checksum}" + } + */ + aes_checksum: function aes_checksum(password) { + if (!(typeof password === 'string')) { + throw new 'password string required'(); + } + + var salt = _secureRandom2.default.randomBuffer(4).toString('hex'); + var iterations = 0; + var secret = salt + password; + // hash for .1 second + var start_t = Date.now(); + + while (Date.now() - start_t < HASH_POWER_MILLS) { + secret = (0, _hash.sha256)(secret); + iterations += 1; + } + + var checksum = (0, _hash.sha256)(secret); + var checksum_string = [iterations, salt.toString('hex'), checksum.slice(0, 4).toString('hex')].join(','); + + return { + aes_private: _aes2.default.fromSeed(secret), + checksum: checksum_string + }; + }, + + + /** Provide a matching password and key_checksum. A "wrong password" + error is thrown if the password does not match. If this method takes + much more or less than 1 second to return, one should consider updating + all encyrpted fields using a new key.key_checksum. + */ + aes_private: function aes_private(password, key_checksum) { + var _key_checksum$split = key_checksum.split(','), + iterations = _key_checksum$split[0], + salt = _key_checksum$split[1], + checksum = _key_checksum$split[2]; + + var secret = salt + password; + + for (var i = 0; iterations > 0 ? i < iterations : i > iterations; iterations > 0 ? i++ : i++) { + secret = (0, _hash.sha256)(secret); + } + + var new_checksum = (0, _hash.sha256)(secret); + + if (!(new_checksum.slice(0, 4).toString('hex') === checksum)) { + throw new Error('wrong password'); + } + + return _aes2.default.fromSeed(secret); + }, + + + /** + A week random number generator can run out of entropy. + This should ensure even the worst random number implementation will be reasonably safe. + @param1 string entropy of at least 32 bytes + */ + random32ByteBuffer: function random32ByteBuffer() { + var entropy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.browserEntropy(); + + if (!(typeof entropy === 'string')) { + throw new Error('string required for entropy'); + } + + if (entropy.length < 32) { + throw new Error('expecting at least 32 bytes of entropy'); + } + + var start_t = Date.now(); + + while (Date.now() - start_t < HASH_POWER_MILLS) { + entropy = (0, _hash.sha256)(entropy); + } + + var hash_array = []; + hash_array.push(entropy); + + // Hashing for 1 second may helps the computer is not low on entropy + // (this method may be called back-to-back). + hash_array.push(_secureRandom2.default.randomBuffer(32)); + + return (0, _hash.sha256)(Buffer.concat(hash_array)); + }, + suggest_brain_key: function suggest_brain_key() { + var dictionary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ','; + var entropy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.browserEntropy(); + + var randomBuffer = this.random32ByteBuffer(entropy); + + var word_count = 16; + var dictionary_lines = dictionary.split(','); + + if (!(dictionary_lines.length === 49744)) { + throw new Error('expecting ' + 49744 + ' but got ' + dictionary_lines.length + ' dictionary words'); + } + + var brainkey = []; + var end = word_count * 2; + + for (var i = 0; i < end; i += 2) { + // randomBuffer has 256 bits / 16 bits per word == 16 words + var num = (randomBuffer[i] << 8) + randomBuffer[i + 1]; // eslint-disable-line + + // convert into a number between 0 and 1 (inclusive) + var rndMultiplier = num / Math.pow(2, 16); + var wordIndex = Math.round(dictionary_lines.length * rndMultiplier); + + brainkey.push(dictionary_lines[wordIndex]); + } + + return this.normalize_brainKey(brainkey.join(' ')); + }, + get_random_key: function get_random_key(entropy) { + return _PrivateKey2.default.fromBuffer(this.random32ByteBuffer(entropy)); + }, + get_brainPrivateKey: function get_brainPrivateKey(brainKey) { + var sequence = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + + if (sequence < 0) { + throw new Error('invalid sequence'); + } + + brainKey = key.normalize_brainKey(brainKey); + return _PrivateKey2.default.fromBuffer((0, _hash.sha256)((0, _hash.sha512)(brainKey + ' ' + sequence))); + }, + + + // Turn invisible space like characters into a single space + normalize_brainKey: function normalize_brainKey(brainKey) { + if (!(typeof brainKey === 'string')) { + throw new Error('string required for brainKey'); + } + + brainKey = brainKey.trim(); + return brainKey.split(/[\t\n\v\f\r ]+/).join(' '); + }, + browserEntropy: function browserEntropy() { + var entropyStr = ''; + + try { + entropyStr = new Date().toString() + ' ' + window.screen.height + ' ' + window.screen.width; + entropyStr = entropyStr + ' ' + window.screen.colorDepth + ' ' + window.screen.availHeight; + entropyStr = entropyStr + ' ' + window.screen.availWidth + ' ' + window.screen.pixelDepth; + entropyStr = entropyStr + ' ' + navigator.language + ' ' + window.location; + entropyStr = entropyStr + ' ' + window.history.length; + + for (var i = 0, len = navigator.mimeTypes.length; i < len; i++) { + var mimeType = navigator.mimeTypes[i]; + entropyStr += mimeType.description + ' ' + mimeType.type + ' ' + mimeType.suffixes + ' '; + } + + console.log('INFO\tbrowserEntropy gathered'); + } catch (error) { + // nodejs:ReferenceError: window is not defined + entropyStr = (0, _hash.sha256)(new Date().toString()); + } + + var b = Buffer.from(entropyStr); + entropyStr += b.toString('binary') + ' ' + new Date().toString(); + return entropyStr; + }, + + + // @return array of 5 legacy addresses for a pubkey string parameter. + addresses: function addresses(pubkey) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _peerplaysjsWs.ChainConfig.address_prefix; + + var public_key = _PublicKey2.default.fromPublicKeyString(pubkey, address_prefix); + // S L O W + var address_string = [_address2.default.fromPublic(public_key, false, 0).toString(address_prefix), // btc_uncompressed + _address2.default.fromPublic(public_key, true, 0).toString(address_prefix), // btc_compressed + _address2.default.fromPublic(public_key, false, 56).toString(address_prefix), // pts_uncompressed + _address2.default.fromPublic(public_key, true, 56).toString(address_prefix), // pts_compressed + public_key.toAddressString(address_prefix) // bts_short, most recent format + ]; + return address_string; + } +}; + +exports.default = key; +module.exports = exports['default']; +}).call(this,require(35).Buffer) + +},{"10":10,"11":11,"12":12,"13":13,"17":17,"35":35,"70":70,"94":94}],10:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; + +var _ecurve = require(59); + +var _bigi = require(32); + +var _bigi2 = _interopRequireDefault(_bigi); + +var _bs = require(37); + +var _deepEqual = require(54); + +var _deepEqual2 = _interopRequireDefault(_deepEqual); + +var _assert = require(27); + +var _assert2 = _interopRequireDefault(_assert); + +var _hash = require(17); + +var _PublicKey = require(11); + +var _PublicKey2 = _interopRequireDefault(_PublicKey); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* global ByteBuffer */ + + +var secp256k1 = (0, _ecurve.getCurveByName)('secp256k1'); +var n = secp256k1.n; + + +function toPublic(data) { + if (!data || data.Q) { + return data; + } + + return _PublicKey2.default.fromStringOrThrow(data); +} + +var PrivateKey = function () { + /** + @private see static functions + @param {BigInteger} + */ + function PrivateKey(d) { + _classCallCheck(this, PrivateKey); + + this.d = d; + } + + PrivateKey.fromBuffer = function fromBuffer(buf) { + if (!Buffer.isBuffer(buf)) { + throw new Error('Expecting paramter to be a Buffer type'); + } + + if (buf.length !== 32) { + console.log('WARN: Expecting 32 bytes, instead got ' + buf.length + ', stack trace:', new Error().stack); + } + + if (buf.length === 0) { + throw new Error('Empty buffer'); + } + + return new PrivateKey(_bigi2.default.fromBuffer(buf)); + }; + + /** @arg {string} seed - any length string. This is private, + * the same seed produces the same private key every time. */ + + + PrivateKey.fromSeed = function fromSeed(seed) { + // generate_private_key + if (!(typeof seed === 'string')) { + throw new Error('seed must be of type string'); + } + + return PrivateKey.fromBuffer((0, _hash.sha256)(seed)); + }; + + /** @return {string} Wallet Import Format (still a secret, Not encrypted) */ + + + PrivateKey.fromWif = function fromWif(_private_wif) { + var private_wif = Buffer.from((0, _bs.decode)(_private_wif)); + var version = private_wif.readUInt8(0); + _assert2.default.equal(0x80, version, 'Expected version ' + 0x80 + ', instead got ' + version); + // checksum includes the version + var private_key = private_wif.slice(0, -4); + var checksum = private_wif.slice(-4); + var new_checksum = (0, _hash.sha256)(private_key); + new_checksum = (0, _hash.sha256)(new_checksum); + new_checksum = new_checksum.slice(0, 4); + var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); // , 'Invalid checksum' + + if (!isEqual) { + throw new Error('Checksum did not match'); + } + + private_key = private_key.slice(1); + private_key = private_key.slice(0, 32); + return PrivateKey.fromBuffer(private_key); + }; + + PrivateKey.prototype.toWif = function toWif() { + var private_key = this.toBuffer(); + // checksum includes the version + private_key = Buffer.concat([Buffer.from([0x80]), private_key]); + var checksum = (0, _hash.sha256)(private_key); + checksum = (0, _hash.sha256)(checksum); + checksum = checksum.slice(0, 4); + var private_wif = Buffer.concat([private_key, checksum]); + return (0, _bs.encode)(private_wif); + }; + + /** + @return {Point} + */ + + + PrivateKey.prototype.toPublicKeyPoint = function toPublicKeyPoint() { + var Q = secp256k1.G.multiply(this.d); + return Q; + }; + + PrivateKey.prototype.toPublicKey = function toPublicKey() { + if (this.public_key) { + return this.public_key; + } + + this.public_key = _PublicKey2.default.fromPoint(this.toPublicKeyPoint()); + + return this.public_key; + }; + + PrivateKey.prototype.toBuffer = function toBuffer() { + return this.d.toBuffer(32); + }; + + /** ECIES */ + + + PrivateKey.prototype.get_shared_secret = function get_shared_secret(public_key) { + var legacy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + public_key = toPublic(public_key); + var KB = public_key.toUncompressed().toBuffer(); + var KBP = _ecurve.Point.fromAffine(secp256k1, _bigi2.default.fromBuffer(KB.slice(1, 33)), // x + _bigi2.default.fromBuffer(KB.slice(33, 65)) // y + ); + var r = this.toBuffer(); + var P = KBP.multiply(_bigi2.default.fromBuffer(r)); + var S = P.affineX.toBuffer({ size: 32 }); + + /* + the input to sha512 must be exactly 32-bytes, to match the c++ implementation + of get_shared_secret. Right now S will be shorter if the most significant + byte(s) is zero. Pad it back to the full 32-bytes + */ + if (!legacy && S.length < 32) { + var pad = Buffer.alloc(32 - S.length, 0); + S = Buffer.concat([pad, S]); + } + + // SHA512 used in ECIES + return (0, _hash.sha512)(S); + }; + + // /** ECIES (does not always match the Point.fromAffine version above) */ + // get_shared_secret(public_key){ + // public_key = toPublic(public_key) + // var P = public_key.Q.multiply( this.d ); + // var S = P.affineX.toBuffer({size: 32}); + // // ECIES, adds an extra sha512 + // return sha512(S); + // } + + /** @throws {Error} - overflow of the key could not be derived */ + + + PrivateKey.prototype.child = function child(offset) { + offset = Buffer.concat([this.toPublicKey().toBuffer(), offset]); + offset = (0, _hash.sha256)(offset); + var c = _bigi2.default.fromBuffer(offset); + + if (c.compareTo(n) >= 0) { + throw new Error('Child offset went out of bounds, try again'); + } + + var derived = this.d.add(c); // .mod(n) + + if (derived.signum() === 0) { + throw new Error('Child offset derived to an invalid key, try again'); + } + + return new PrivateKey(derived); + }; + + /* */ + + PrivateKey.prototype.toByteBuffer = function toByteBuffer() { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + }; + + PrivateKey.fromHex = function fromHex(hex) { + return PrivateKey.fromBuffer(Buffer.from(hex, 'hex')); + }; + + PrivateKey.prototype.toHex = function toHex() { + return this.toBuffer().toString('hex'); + }; + + /* */ + + + return PrivateKey; +}(); + +exports.default = PrivateKey; +module.exports = exports['default']; +}).call(this,require(35).Buffer) + +},{"11":11,"17":17,"27":27,"32":32,"35":35,"37":37,"54":54,"59":59}],11:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; + +var _bigi = require(32); + +var _bigi2 = _interopRequireDefault(_bigi); + +var _ecurve = require(59); + +var _bs = require(37); + +var _peerplaysjsWs = require(70); + +var _assert = require(27); + +var _assert2 = _interopRequireDefault(_assert); + +var _deepEqual = require(54); + +var _deepEqual2 = _interopRequireDefault(_deepEqual); + +var _hash = require(17); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* global ByteBuffer */ + + +var secp256k1 = (0, _ecurve.getCurveByName)('secp256k1'); + +var G = secp256k1.G, + n = secp256k1.n; + +var PublicKey = function () { + /** @param {Point} public key */ + function PublicKey(Q) { + _classCallCheck(this, PublicKey); + + this.Q = Q; + } + + PublicKey.fromBinary = function fromBinary(bin) { + return PublicKey.fromBuffer(Buffer.from(bin, 'binary')); + }; + + PublicKey.fromBuffer = function fromBuffer(buffer) { + if (buffer.toString('hex') === '000000000000000000000000000000000000000000000000000000000000000000') { + return new PublicKey(null); + } + + return new PublicKey(_ecurve.Point.decodeFrom(secp256k1, buffer)); + }; + + PublicKey.prototype.toBuffer = function toBuffer() { + var compressed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.Q ? this.Q.compressed : null; + + if (this.Q === null) { + return Buffer.from('000000000000000000000000000000000000000000000000000000000000000000', 'hex'); + } + + return this.Q.getEncoded(compressed); + }; + + PublicKey.fromPoint = function fromPoint(point) { + return new PublicKey(point); + }; + + PublicKey.prototype.toUncompressed = function toUncompressed() { + var buf = this.Q.getEncoded(false); + var point = _ecurve.Point.decodeFrom(secp256k1, buf); + return PublicKey.fromPoint(point); + }; + + /** bts::blockchain::address (unique but not a full public key) */ + + + PublicKey.prototype.toBlockchainAddress = function toBlockchainAddress() { + var pub_buf = this.toBuffer(); + var pub_sha = (0, _hash.sha512)(pub_buf); + return (0, _hash.ripemd160)(pub_sha); + }; + + /** Alias for {@link toPublicKeyString} */ + + + PublicKey.prototype.toString = function toString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.ChainConfig.address_prefix; + + return this.toPublicKeyString(address_prefix); + }; + + /** + Full public key + {return} string + */ + + + PublicKey.prototype.toPublicKeyString = function toPublicKeyString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.ChainConfig.address_prefix; + + var pub_buf = this.toBuffer(); + var checksum = (0, _hash.ripemd160)(pub_buf); + // Slice from the buffer directly, slicing from the checksum + // Uint8array will return the entire array each time. + var sliced = new Uint8Array(checksum.buffer.slice(0, 4)); + + // concat only accepts buffers so initialize the sliced Uint8array as a Buffer. + var addy = Buffer.concat([pub_buf, Buffer.from(sliced)]); + return address_prefix + (0, _bs.encode)(addy); + }; + + /** + @arg {string} public_key - like GPHXyz... + @arg {string} address_prefix - like GPH + @return PublicKey or `null` (if the public_key string is invalid) + */ + + + PublicKey.fromPublicKeyString = function fromPublicKeyString(public_key) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _peerplaysjsWs.ChainConfig.address_prefix; + + try { + return PublicKey.fromStringOrThrow(public_key, address_prefix); + } catch (e) { + return null; + } + }; + + /** + @arg {string} public_key - like GPHXyz... + @arg {string} address_prefix - like GPH + @throws {Error} if public key is invalid + @return PublicKey + */ + + + PublicKey.fromStringOrThrow = function fromStringOrThrow(public_key) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _peerplaysjsWs.ChainConfig.address_prefix; + + var prefix = public_key.slice(0, address_prefix.length); + _assert2.default.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix); + public_key = public_key.slice(address_prefix.length); + + public_key = Buffer.from((0, _bs.decode)(public_key), 'binary'); + var checksum = public_key.slice(-4); + public_key = public_key.slice(0, -4); + var new_checksum = (0, _hash.ripemd160)(public_key); + new_checksum = new_checksum.slice(0, 4); + var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); // , 'Invalid checksum' + + if (!isEqual) { + throw new Error('Checksum did not match'); + } + + return PublicKey.fromBuffer(public_key); + }; + + PublicKey.prototype.toAddressString = function toAddressString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.ChainConfig.address_prefix; + + var pub_buf = this.toBuffer(); + var pub_sha = (0, _hash.sha512)(pub_buf); + var addy = (0, _hash.ripemd160)(pub_sha); + var checksum = (0, _hash.ripemd160)(addy); + addy = Buffer.concat([addy, checksum.slice(0, 4)]); + return address_prefix + (0, _bs.encode)(addy); + }; + + PublicKey.prototype.toPtsAddy = function toPtsAddy() { + var pub_buf = this.toBuffer(); + var pub_sha = (0, _hash.sha256)(pub_buf); + var addy = (0, _hash.ripemd160)(pub_sha); + addy = Buffer.concat([Buffer.from([0x38]), addy]); // version 56(decimal) + + var checksum = (0, _hash.sha256)(addy); + checksum = (0, _hash.sha256)(checksum); + + addy = Buffer.concat([addy, checksum.slice(0, 4)]); + return (0, _bs.encode)(addy); + }; + + PublicKey.prototype.child = function child(offset) { + (0, _assert2.default)(Buffer.isBuffer(offset), 'Buffer required: offset'); + _assert2.default.equal(offset.length, 32, 'offset length'); + + offset = Buffer.concat([this.toBuffer(), offset]); + offset = (0, _hash.sha256)(offset); + + var c = _bigi2.default.fromBuffer(offset); + + if (c.compareTo(n) >= 0) { + throw new Error('Child offset went out of bounds, try again'); + } + + var cG = G.multiply(c); + var Qprime = this.Q.add(cG); + + if (secp256k1.isInfinity(Qprime)) { + throw new Error('Child offset derived to an invalid key, try again'); + } + + return PublicKey.fromPoint(Qprime); + }; + + /* */ + + PublicKey.prototype.toByteBuffer = function toByteBuffer() { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + }; + + PublicKey.fromHex = function fromHex(hex) { + return PublicKey.fromBuffer(Buffer.from(hex, 'hex')); + }; + + PublicKey.prototype.toHex = function toHex() { + return this.toBuffer().toString('hex'); + }; + + PublicKey.fromPublicKeyStringHex = function fromPublicKeyStringHex(hex) { + return PublicKey.fromPublicKeyString(Buffer.from(hex, 'hex')); + }; + + /* */ + + + return PublicKey; +}(); + +exports.default = PublicKey; +module.exports = exports['default']; +}).call(this,require(35).Buffer) + +},{"17":17,"27":27,"32":32,"35":35,"37":37,"54":54,"59":59,"70":70}],12:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; + +var _assert = require(27); + +var _assert2 = _interopRequireDefault(_assert); + +var _peerplaysjsWs = require(70); + +var _bs = require(37); + +var _deepEqual = require(54); + +var _deepEqual2 = _interopRequireDefault(_deepEqual); + +var _hash2 = require(17); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** Addresses are shortened non-reversable hashes of a public key. The full PublicKey is preferred. + @deprecated +*/ +var Address = function () { + function Address(addy) { + _classCallCheck(this, Address); + + this.addy = addy; + } + + Address.fromBuffer = function fromBuffer(buffer) { + var _hash = (0, _hash2.sha512)(buffer); + var addy = (0, _hash2.ripemd160)(_hash); + return new Address(addy); + }; + + Address.fromString = function fromString(string) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _peerplaysjsWs.ChainConfig.address_prefix; + + var prefix = string.slice(0, address_prefix.length); + _assert2.default.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix); + var addy = string.slice(address_prefix.length); + addy = Buffer.from((0, _bs.decode)(addy), 'binary'); + var checksum = addy.slice(-4); + addy = addy.slice(0, -4); + var new_checksum = (0, _hash2.ripemd160)(addy); + new_checksum = new_checksum.slice(0, 4); + var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); // , 'Invalid checksum' + + if (!isEqual) { + throw new Error('Checksum did not match'); + } + + return new Address(addy); + }; + + /** @return Address - Compressed PTS format (by default) */ + + + Address.fromPublic = function fromPublic(public_key) { + var compressed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var version = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 56; + + var sha2 = (0, _hash2.sha256)(public_key.toBuffer(compressed)); + var rep = (0, _hash2.ripemd160)(sha2); + var versionBuffer = Buffer.alloc(1); + versionBuffer.writeUInt8(0xff & version, 0); // eslint-disable-line + var addr = Buffer.concat([versionBuffer, rep]); + var check = (0, _hash2.sha256)(addr); + check = (0, _hash2.sha256)(check); + var buffer = Buffer.concat([addr, check.slice(0, 4)]); + return new Address((0, _hash2.ripemd160)(buffer)); + }; + + Address.prototype.toBuffer = function toBuffer() { + return this.addy; + }; + + Address.prototype.toString = function toString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.ChainConfig.address_prefix; + + var checksum = (0, _hash2.ripemd160)(this.addy); + var addy = Buffer.concat([this.addy, checksum.slice(0, 4)]); + return address_prefix + (0, _bs.encode)(addy); + }; + + return Address; +}(); + +exports.default = Address; +module.exports = exports['default']; +}).call(this,require(35).Buffer) + +},{"17":17,"27":27,"35":35,"37":37,"54":54,"70":70}],13:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; + +var _aes = require(45); + +var _aes2 = _interopRequireDefault(_aes); + +var _encHex = require(49); + +var _encHex2 = _interopRequireDefault(_encHex); + +var _encBase = require(48); + +var _encBase2 = _interopRequireDefault(_encBase); + +var _assert = require(27); + +var _assert2 = _interopRequireDefault(_assert); + +var _hash2 = require(17); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // https://code.google.com/p/crypto-js + + +/** Provides symetric encrypt and decrypt via AES. */ +var Aes = function () { + /** @private */ + function Aes(iv, key) { + _classCallCheck(this, Aes); + + this.iv = iv; + this.key = key; + } + + /** This is an excellent way to ensure that all references to Aes can not operate anymore + * (example: a wallet becomes locked). An application should ensure there is only one + * Aes object instance for a given secret `seed`. */ + + + Aes.prototype.clear = function clear() { + this.iv = undefined; + this.key = undefined; + return undefined; + }; + + /** @arg {string} seed - secret seed may be used to encrypt or decrypt. */ + + + Aes.fromSeed = function fromSeed(seed) { + if (seed === undefined) { + throw new Error('seed is required'); + } + + var _hash = (0, _hash2.sha512)(seed); + _hash = _hash.toString('hex'); + // DEBUG console.log('... fromSeed _hash',_hash) + return Aes.fromSha512(_hash); + }; + + /** @arg {string} hash - A 128 byte hex string, typically one + * would call {@link fromSeed} instead. */ + + + Aes.fromSha512 = function fromSha512(hash) { + _assert2.default.equal(hash.length, 128, 'A Sha512 in HEX should be 128 characters long, instead got ' + hash.length); + var iv = _encHex2.default.parse(hash.substring(64, 96)); + var key = _encHex2.default.parse(hash.substring(0, 64)); + return new Aes(iv, key); + }; + + Aes.fromBuffer = function fromBuffer(buf) { + (0, _assert2.default)(Buffer.isBuffer(buf), 'Expecting Buffer'); + _assert2.default.equal(buf.length, 64, 'A Sha512 Buffer should be 64 characters long, instead got ' + buf.length); + return Aes.fromSha512(buf.toString('hex')); + }; + + /** + @throws {Error} - "Invalid Key, ..." + @arg {PrivateKey} private_key - required and used for decryption + @arg {PublicKey} public_key - required and used to calcualte the shared secret + @arg {string} [nonce = ""] optional but should always be provided and be unique + when re-using the same private/public keys more than once. This nonce is not a secret. + @arg {string|Buffer} message - Encrypted message containing a checksum + @return {Buffer} + */ + + + Aes.decrypt_with_checksum = function decrypt_with_checksum(private_key, public_key, nonce, message) { + var legacy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + + // Warning: Do not put `nonce = ""` in the arguments, in es6 this will + // not convert "null" into an emtpy string + if (nonce == null) { + nonce = ''; + } + + if (!Buffer.isBuffer(message)) { + message = Buffer.from(message, 'hex'); + } + + var S = private_key.get_shared_secret(public_key, legacy); + // D E B U G + // console.log('decrypt_with_checksum', { + // priv_to_pub: private_key.toPublicKey().toString(), + // pub: public_key.toPublicKeyString(), + // nonce: nonce, + // message: message.length, + // S: S.toString('hex') + // }) + + var aes = Aes.fromSeed(Buffer.concat([ + // A null or empty string nonce will not effect the hash + Buffer.from('' + nonce), Buffer.from(S.toString('hex'))])); + + var planebuffer = aes.decrypt(message); + + if (!(planebuffer.length >= 4)) { + throw new Error('Invalid key, could not decrypt message(1)'); + } + + // DEBUG console.log('... planebuffer',planebuffer) + var checksum = planebuffer.slice(0, 4); + var plaintext = planebuffer.slice(4); + + // console.log('... checksum',checksum.toString('hex')) + // console.log('... plaintext',plaintext.toString()) + + var new_checksum = (0, _hash2.sha256)(plaintext); + new_checksum = new_checksum.slice(0, 4); + new_checksum = new_checksum.toString('hex'); + + if (!(checksum.toString('hex') === new_checksum)) { + throw new Error('Invalid key, could not decrypt message(2)'); + } + + return plaintext; + }; + + /** Identical to {@link decrypt_with_checksum} but used to encrypt. Should not throw an error. + @return {Buffer} message - Encrypted message which includes a checksum + */ + + + Aes.encrypt_with_checksum = function encrypt_with_checksum(private_key, public_key, nonce, message) { + // Warning: Do not put `nonce = ""` in the arguments, in es6 this will + // not convert "null" into an emtpy string + + if (nonce == null) { + nonce = ''; + } + + if (!Buffer.isBuffer(message)) { + message = Buffer.from(message, 'binary'); + } + + var S = private_key.get_shared_secret(public_key); + + // D E B U G + // console.log('encrypt_with_checksum', { + // priv_to_pub: private_key.toPublicKey().toString() + // pub: public_key.toPublicKeyString() + // nonce: nonce + // message: message.length + // S: S.toString('hex') + // }) + + var aes = Aes.fromSeed(Buffer.concat([ + // A null or empty string nonce will not effect the hash + Buffer.from('' + nonce), Buffer.from(S.toString('hex'))])); + // DEBUG console.log('... S',S.toString('hex')) + var checksum = (0, _hash2.sha256)(message).slice(0, 4); + var payload = Buffer.concat([checksum, message]); + // DEBUG console.log('... payload',payload.toString()) + return aes.encrypt(payload); + }; + + /** @private */ + + + Aes.prototype._decrypt_word_array = function _decrypt_word_array(cipher) { + // https://code.google.com/p/crypto-js/#Custom_Key_and_IV + // see wallet_records.cpp master_key::decrypt_key + return _aes2.default.decrypt({ ciphertext: cipher, salt: null }, this.key, { iv: this.iv }); + }; + + /** @private */ + + + Aes.prototype._encrypt_word_array = function _encrypt_word_array(plaintext) { + // https://code.google.com/p/crypto-js/issues/detail?id=85 + var cipher = _aes2.default.encrypt(plaintext, this.key, { iv: this.iv }); + return _encBase2.default.parse(cipher.toString()); + }; + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} ciphertext + @return {Buffer} binary + */ + + + Aes.prototype.decrypt = function decrypt(ciphertext) { + if (typeof ciphertext === 'string') { + ciphertext = Buffer.from(ciphertext, 'binary'); + } + + if (!Buffer.isBuffer(ciphertext)) { + throw new Error('buffer required'); + } + + (0, _assert2.default)(ciphertext, 'Missing cipher text'); + // hex is the only common format + var hex = this.decryptHex(ciphertext.toString('hex')); + return Buffer.from(hex, 'hex'); + }; + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} plaintext + @return {Buffer} binary + */ + + + Aes.prototype.encrypt = function encrypt(plaintext) { + if (typeof plaintext === 'string') { + plaintext = Buffer.from(plaintext, 'binary'); + } + + if (!Buffer.isBuffer(plaintext)) { + throw new Error('buffer required'); + } + + // assert plaintext, "Missing plain text" + // hex is the only common format + var hex = this.encryptHex(plaintext.toString('hex')); + return Buffer.from(hex, 'hex'); + }; + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string|Buffer} plaintext + @return {string} hex + */ + + + Aes.prototype.encryptToHex = function encryptToHex(plaintext) { + if (typeof plaintext === 'string') { + plaintext = Buffer.from(plaintext, 'binary'); + } + + if (!Buffer.isBuffer(plaintext)) { + throw new Error('buffer required'); + } + + // assert plaintext, "Missing plain text" + // hex is the only common format + return this.encryptHex(plaintext.toString('hex')); + }; + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @return {string} binary (could easily be readable text) + */ + + + Aes.prototype.decryptHex = function decryptHex(cipher) { + (0, _assert2.default)(cipher, 'Missing cipher text'); + // Convert data into word arrays (used by Crypto) + var cipher_array = _encHex2.default.parse(cipher); + var plainwords = this._decrypt_word_array(cipher_array); + return _encHex2.default.stringify(plainwords); + }; + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @return {Buffer} encoded as specified by the parameter + */ + + + Aes.prototype.decryptHexToBuffer = function decryptHexToBuffer(cipher) { + (0, _assert2.default)(cipher, 'Missing cipher text'); + // Convert data into word arrays (used by Crypto) + var cipher_array = _encHex2.default.parse(cipher); + var plainwords = this._decrypt_word_array(cipher_array); + var plainhex = _encHex2.default.stringify(plainwords); + return Buffer.from(plainhex, 'hex'); + }; + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @arg {string} [encoding = 'binary'] - a valid Buffer encoding + @return {String} encoded as specified by the parameter + */ + + + Aes.prototype.decryptHexToText = function decryptHexToText(cipher) { + var encoding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'binary'; + + return this.decryptHexToBuffer(cipher).toString(encoding); + }; + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} plainhex - hex format + @return {String} hex + */ + + + Aes.prototype.encryptHex = function encryptHex(plainhex) { + var plain_array = _encHex2.default.parse(plainhex); + var cipher_array = this._encrypt_word_array(plain_array); + return _encHex2.default.stringify(cipher_array); + }; + + return Aes; +}(); + +exports.default = Aes; +module.exports = exports['default']; +}).call(this,require(35).Buffer) + +},{"17":17,"27":27,"35":35,"45":45,"48":48,"49":49}],14:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; +exports.verifyRaw = exports.verify = exports.sign = exports.recoverPubKey = exports.deterministicGenerateK = exports.calcPubKeyRecoveryParam = undefined; + +var _assert = require(27); + +var _assert2 = _interopRequireDefault(_assert); + +var _bigi = require(32); + +var _bigi2 = _interopRequireDefault(_bigi); + +var _hash = require(17); + +var _enforce_types = require(16); + +var _enforce_types2 = _interopRequireDefault(_enforce_types); + +var _ecsignature = require(15); + +var _ecsignature2 = _interopRequireDefault(_ecsignature); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// https://tools.ietf.org/html/rfc6979#section-3.2 + +// from github.com/bitcoinjs/bitcoinjs-lib from github.com/cryptocoinjs/ecdsa +function deterministicGenerateK(curve, hash, d, checkSig, nonce) { + (0, _enforce_types2.default)('Buffer', hash); + (0, _enforce_types2.default)(_bigi2.default, d); + + if (nonce) { + hash = (0, _hash.sha256)(Buffer.concat([hash, Buffer.alloc(nonce)])); + } + + // sanity check + _assert2.default.equal(hash.length, 32, 'Hash must be 256 bit'); + + var x = d.toBuffer(32); + var k = Buffer.alloc(32); + var v = Buffer.alloc(32); + + // Step B + v.fill(1); + + // Step C + k.fill(0); + + // Step D + k = (0, _hash.HmacSHA256)(Buffer.concat([v, Buffer.from([0]), x, hash]), k); + + // Step E + v = (0, _hash.HmacSHA256)(v, k); + + // Step F + k = (0, _hash.HmacSHA256)(Buffer.concat([v, Buffer.from([1]), x, hash]), k); + + // Step G + v = (0, _hash.HmacSHA256)(v, k); + + // Step H1/H2a, ignored as tlen === qlen (256 bit) + // Step H2b + v = (0, _hash.HmacSHA256)(v, k); + + var T = _bigi2.default.fromBuffer(v); + + // Step H3, repeat until T is within the interval [1, n - 1] + while (T.signum() <= 0 || T.compareTo(curve.n) >= 0 || !checkSig(T)) { + k = (0, _hash.HmacSHA256)(Buffer.concat([v, Buffer.from([0])]), k); + v = (0, _hash.HmacSHA256)(v, k); + + // Step H1/H2a, again, ignored as tlen === qlen (256 bit) + // Step H2b again + v = (0, _hash.HmacSHA256)(v, k); + + T = _bigi2.default.fromBuffer(v); + } + + return T; +} + +function sign(curve, hash, d, nonce) { + var e = _bigi2.default.fromBuffer(hash); + var n = curve.n; + var G = curve.G; + + var r = void 0; + var s = void 0; + + deterministicGenerateK(curve, hash, d, function (key) { + // find canonically valid signature + var Q = G.multiply(key); + + if (curve.isInfinity(Q)) { + return false; + } + + r = Q.affineX.mod(n); + + if (r.signum() === 0) { + return false; + } + + s = key.modInverse(n).multiply(e.add(d.multiply(r))).mod(n); + + if (s.signum() === 0) { + return false; + } + + return true; + }, nonce); + + var N_OVER_TWO = n.shiftRight(1); + + // enforce low S values, see bip62: 'low s values in signatures' + if (s.compareTo(N_OVER_TWO) > 0) { + s = n.subtract(s); + } + + return new _ecsignature2.default(r, s); +} + +function verifyRaw(curve, e, signature, Q) { + var n = curve.n; + var G = curve.G; + + var r = signature.r; + var s = signature.s; + + // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] + if (r.signum() <= 0 || r.compareTo(n) >= 0) { + return false; + } + + if (s.signum() <= 0 || s.compareTo(n) >= 0) { + return false; + } + + // c = s^-1 mod n + var c = s.modInverse(n); + + // 1.4.4 Compute u1 = es^−1 mod n + // u2 = rs^−1 mod n + var u1 = e.multiply(c).mod(n); + var u2 = r.multiply(c).mod(n); + + // 1.4.5 Compute R = (xR, yR) = u1G + u2Q + var R = G.multiplyTwo(u1, Q, u2); + + // 1.4.5 (cont.) Enforce R is not at infinity + if (curve.isInfinity(R)) { + return false; + } + + // 1.4.6 Convert the field element R.x to an integer + var xR = R.affineX; + + // 1.4.7 Set v = xR mod n + var v = xR.mod(n); + + // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" + return v.equals(r); +} + +function verify(curve, hash, signature, Q) { + // 1.4.2 H = Hash(M), already done by the user + // 1.4.3 e = H + var e = _bigi2.default.fromBuffer(hash); + return verifyRaw(curve, e, signature, Q); +} + +/** + * Recover a public key from a signature. + * + * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public + * Key Recovery Operation". + * + * http://www.secg.org/download/aid-780/sec1-v2.pdf + */ +function recoverPubKey(curve, e, signature, i) { + _assert2.default.strictEqual(i & 3, i, 'Recovery param is more than two bits'); // eslint-disable-line + + var n = curve.n; + var G = curve.G; + + var r = signature.r; + var s = signature.s; + + (0, _assert2.default)(r.signum() > 0 && r.compareTo(n) < 0, 'Invalid r value'); + (0, _assert2.default)(s.signum() > 0 && s.compareTo(n) < 0, 'Invalid s value'); + + // A set LSB signifies that the y-coordinate is odd + var isYOdd = i & 1; // eslint-disable-line + + // The more significant bit specifies whether we should use the + // first or second candidate key. + var isSecondKey = i >> 1; // eslint-disable-line + + // 1.1 Let x = r + jn + var x = isSecondKey ? r.add(n) : r; + var R = curve.pointFromX(isYOdd, x); + + // 1.4 Check that nR is at infinity + var nR = R.multiply(n); + (0, _assert2.default)(curve.isInfinity(nR), 'nR is not a valid curve point'); + + // Compute -e from e + var eNeg = e.negate().mod(n); + + // 1.6.1 Compute Q = r^-1 (sR - eG) + // Q = r^-1 (sR + -eG) + var rInv = r.modInverse(n); + + var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv); + curve.validate(Q); + + return Q; +} + +/** + * Calculate pubkey extraction parameter. + * + * When extracting a pubkey from a signature, we have to + * distinguish four different cases. Rather than putting this + * burden on the verifier, Bitcoin includes a 2-bit value with the + * signature. + * + * This function simply tries all four cases and returns the value + * that resulted in a successful pubkey recovery. + */ +function calcPubKeyRecoveryParam(curve, e, signature, Q) { + for (var i = 0; i < 4; i++) { + var Qprime = recoverPubKey(curve, e, signature, i); + + // 1.6.2 Verify Q + if (Qprime.equals(Q)) { + return i; + } + } + + throw new Error('Unable to find valid recovery factor'); +} + +exports.calcPubKeyRecoveryParam = calcPubKeyRecoveryParam; +exports.deterministicGenerateK = deterministicGenerateK; +exports.recoverPubKey = recoverPubKey; +exports.sign = sign; +exports.verify = verify; +exports.verifyRaw = verifyRaw; +}).call(this,require(35).Buffer) + +},{"15":15,"16":16,"17":17,"27":27,"32":32,"35":35}],15:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; + +var _assert = require(27); + +var _assert2 = _interopRequireDefault(_assert); + +var _bigi = require(32); + +var _bigi2 = _interopRequireDefault(_bigi); + +var _enforce_types = require(16); + +var _enforce_types2 = _interopRequireDefault(_enforce_types); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// from https://github.com/bitcoinjs/bitcoinjs-lib +function ECSignature(r, s) { + (0, _enforce_types2.default)(_bigi2.default, r); + (0, _enforce_types2.default)(_bigi2.default, s); + + this.r = r; + this.s = s; +} + +// Import operations +/* eslint no-bitwise: "off" */ +ECSignature.parseCompact = function (buffer) { + _assert2.default.equal(buffer.length, 65, 'Invalid signature length'); + var i = buffer.readUInt8(0) - 27; + + // At most 3 bits + _assert2.default.equal(i, i & 7, 'Invalid signature parameter'); + var compressed = !!(i & 4); + + // Recovery param only + i &= 3; + + var r = _bigi2.default.fromBuffer(buffer.slice(1, 33)); + var s = _bigi2.default.fromBuffer(buffer.slice(33)); + + return { + compressed: compressed, + i: i, + signature: new ECSignature(r, s) + }; +}; + +ECSignature.fromDER = function (buffer) { + _assert2.default.equal(buffer.readUInt8(0), 0x30, 'Not a DER sequence'); + _assert2.default.equal(buffer.readUInt8(1), buffer.length - 2, 'Invalid sequence length'); + _assert2.default.equal(buffer.readUInt8(2), 0x02, 'Expected a DER integer'); + + var rLen = buffer.readUInt8(3); + (0, _assert2.default)(rLen > 0, 'R length is zero'); + + var offset = 4 + rLen; + _assert2.default.equal(buffer.readUInt8(offset), 0x02, 'Expected a DER integer (2)'); + + var sLen = buffer.readUInt8(offset + 1); + (0, _assert2.default)(sLen > 0, 'S length is zero'); + + var rB = buffer.slice(4, offset); + var sB = buffer.slice(offset + 2); + offset += 2 + sLen; + + if (rLen > 1 && rB.readUInt8(0) === 0x00) { + (0, _assert2.default)(rB.readUInt8(1) & 0x80, 'R value excessively padded'); + } + + if (sLen > 1 && sB.readUInt8(0) === 0x00) { + (0, _assert2.default)(sB.readUInt8(1) & 0x80, 'S value excessively padded'); + } + + _assert2.default.equal(offset, buffer.length, 'Invalid DER encoding'); + var r = _bigi2.default.fromDERInteger(rB); + var s = _bigi2.default.fromDERInteger(sB); + + (0, _assert2.default)(r.signum() >= 0, 'R value is negative'); + (0, _assert2.default)(s.signum() >= 0, 'S value is negative'); + + return new ECSignature(r, s); +}; + +// FIXME: 0x00, 0x04, 0x80 are SIGHASH_* boundary constants, +// importing Transaction causes a circular dependency +ECSignature.parseScriptSignature = function (buffer) { + var hashType = buffer.readUInt8(buffer.length - 1); + var hashTypeMod = hashType & ~0x80; + + (0, _assert2.default)(hashTypeMod > 0x00 && hashTypeMod < 0x04, 'Invalid hashType'); + + return { + signature: ECSignature.fromDER(buffer.slice(0, -1)), + hashType: hashType + }; +}; + +// Export operations +ECSignature.prototype.toCompact = function toCompact(i, compressed) { + if (compressed) { + i += 4; + } + + i += 27; + + var buffer = Buffer.alloc(65); + buffer.writeUInt8(i, 0); + + this.r.toBuffer(32).copy(buffer, 1); + this.s.toBuffer(32).copy(buffer, 33); + + return buffer; +}; + +ECSignature.prototype.toDER = function toDER() { + var rBa = this.r.toDERInteger(); + var sBa = this.s.toDERInteger(); + + var sequence = []; + + // INTEGER + sequence.push(0x02, rBa.length); + sequence = sequence.concat(rBa); + + // INTEGER + sequence.push(0x02, sBa.length); + sequence = sequence.concat(sBa); + + // SEQUENCE + sequence.unshift(0x30, sequence.length); + + return Buffer.from(sequence); +}; + +ECSignature.prototype.toScriptSignature = function toScriptSignature(hashType) { + var hashTypeBuffer = Buffer.alloc(1); + hashTypeBuffer.writeUInt8(hashType, 0); + + return Buffer.concat([this.toDER(), hashTypeBuffer]); +}; + +exports.default = ECSignature; +module.exports = exports['default']; +}).call(this,require(35).Buffer) + +},{"16":16,"27":27,"32":32,"35":35}],16:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; +exports.default = enforce; + +function getName(fn) { + // Why not fn.name: https://kangax.github.io/compat-table/es6/#function_name_property + var match = fn.toString().match(/function (.*?)\(/); + return match ? match[1] : null; +} + +function enforce(type, value) { + // Copied from https://github.com/bitcoinjs/bitcoinjs-lib + switch (type) { + case 'Array': + { + if (Array.isArray(value)) { + return; + } + + break; + } + + case 'Boolean': + { + if (typeof value === 'boolean') { + return; + } + + break; + } + + case 'Buffer': + { + if (Buffer.isBuffer(value)) { + return; + } + + break; + } + + case 'Number': + { + if (typeof value === 'number') { + return; + } + + break; + } + + case 'String': + { + if (typeof value === 'string') { + return; + } + + break; + } + + default: + { + if (getName(value.constructor) === getName(type)) { + return; + } + } + } + + throw new TypeError('Expected ' + (getName(type) || type) + ', got ' + value); +} +module.exports = exports['default']; +}).call(this,{"isBuffer":require(66)}) + +},{"66":66}],17:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.ripemd160 = exports.HmacSHA256 = exports.sha512 = exports.sha256 = exports.sha1 = undefined; + +var _createHash = require(41); + +var _createHash2 = _interopRequireDefault(_createHash); + +var _createHmac = require(43); + +var _createHmac2 = _interopRequireDefault(_createHmac); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha1(data, encoding) { + return (0, _createHash2.default)('sha1').update(data).digest(encoding); +} + +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha256(data, encoding) { + return (0, _createHash2.default)('sha256').update(data).digest(encoding); +} + +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha512(data, encoding) { + return (0, _createHash2.default)('sha512').update(data).digest(encoding); +} + +function HmacSHA256(buffer, secret) { + return (0, _createHmac2.default)('sha256', secret).update(buffer).digest(); +} + +function ripemd160(data) { + return (0, _createHash2.default)('rmd160').update(data).digest(); +} + +// function hash160(buffer) { +// return ripemd160(sha256(buffer)) +// } +// +// function hash256(buffer) { +// return sha256(sha256(buffer)) +// } + +// +// function HmacSHA512(buffer, secret) { +// return crypto.createHmac('sha512', secret).update(buffer).digest() +// } + +exports.sha1 = sha1; +exports.sha256 = sha256; +exports.sha512 = sha512; +exports.HmacSHA256 = HmacSHA256; +exports.ripemd160 = ripemd160; +},{"41":41,"43":43}],18:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; + +var _ecurve = require(59); + +var _assert = require(27); + +var _assert2 = _interopRequireDefault(_assert); + +var _bigi = require(32); + +var _bigi2 = _interopRequireDefault(_bigi); + +var _hash2 = require(17); + +var _ecdsa = require(14); + +var _PublicKey = require(11); + +var _PublicKey2 = _interopRequireDefault(_PublicKey); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* global ByteBuffer */ + + +var secp256k1 = (0, _ecurve.getCurveByName)('secp256k1'); + +var Signature = function () { + function Signature(r1, s1, i1) { + _classCallCheck(this, Signature); + + this.r = r1; + this.s = s1; + this.i = i1; + _assert2.default.equal(this.r != null, true, 'Missing parameter'); + _assert2.default.equal(this.s != null, true, 'Missing parameter'); + _assert2.default.equal(this.i != null, true, 'Missing parameter'); + } + + Signature.fromBuffer = function fromBuffer(buf) { + var i = void 0; + var r = void 0; + var s = void 0; + _assert2.default.equal(buf.length, 65, 'Invalid signature length'); + i = buf.readUInt8(0); + _assert2.default.equal(i - 27, i - 27 & 7, 'Invalid signature parameter'); // eslint-disable-line + r = _bigi2.default.fromBuffer(buf.slice(1, 33)); + s = _bigi2.default.fromBuffer(buf.slice(33)); + return new Signature(r, s, i); + }; + + Signature.prototype.toBuffer = function toBuffer() { + var buf = void 0; + buf = Buffer.alloc(65); + buf.writeUInt8(this.i, 0); + this.r.toBuffer(32).copy(buf, 1); + this.s.toBuffer(32).copy(buf, 33); + return buf; + }; + + Signature.prototype.recoverPublicKeyFromBuffer = function recoverPublicKeyFromBuffer(buffer) { + return this.recoverPublicKey((0, _hash2.sha256)(buffer)); + }; + + /** + @return {PublicKey} + */ + + + Signature.prototype.recoverPublicKey = function recoverPublicKey(sha256_buffer) { + var Q = void 0; + var e = void 0; + var i = void 0; + e = _bigi2.default.fromBuffer(sha256_buffer); + i = this.i; + i -= 27; + i &= 3; // eslint-disable-line + Q = (0, _ecdsa.recoverPubKey)(secp256k1, e, this, i); + return _PublicKey2.default.fromPoint(Q); + }; + + /** + @param {Buffer} buf + @param {PrivateKey} private_key + @return {Signature} + */ + + + Signature.signBuffer = function signBuffer(buf, private_key) { + var _hash = (0, _hash2.sha256)(buf); + return Signature.signBufferSha256(_hash, private_key); + }; + + /** Sign a buffer of exactally 32 bytes in size (sha256(text)) + @param {Buffer} buf - 32 bytes binary + @param {PrivateKey} private_key + @return {Signature} + */ + + + Signature.signBufferSha256 = function signBufferSha256(buf_sha256, private_key) { + if (buf_sha256.length !== 32 || !Buffer.isBuffer(buf_sha256)) { + throw new Error('buf_sha256: 32 byte buffer requred'); + } + + var der = void 0; + var e = void 0; + var ecsignature = void 0; + var i = void 0; + var lenR = void 0; + var lenS = void 0; + var nonce = void 0; + i = null; + nonce = 0; + e = _bigi2.default.fromBuffer(buf_sha256); + + var loop = true; + + while (loop) { + ecsignature = (0, _ecdsa.sign)(secp256k1, buf_sha256, private_key.d, nonce++); + der = ecsignature.toDER(); + lenR = der[3]; + lenS = der[5 + lenR]; + + if (lenR === 32 && lenS === 32) { + i = (0, _ecdsa.calcPubKeyRecoveryParam)(secp256k1, e, ecsignature, private_key.toPublicKey().Q); + i += 4; // compressed + i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) + loop = false; + break; + } + + if (nonce % 10 === 0) { + console.log('WARN: ' + nonce + ' attempts to find canonical signature'); + } + } + + return new Signature(ecsignature.r, ecsignature.s, i); + }; + + Signature.sign = function sign(string, private_key) { + return Signature.signBuffer(Buffer.from(string), private_key); + }; + + /** + @param {Buffer} un-hashed + @param {./PublicKey} + @return {boolean} + */ + + + Signature.prototype.verifyBuffer = function verifyBuffer(buf, public_key) { + var _hash = (0, _hash2.sha256)(buf); + return this.verifyHash(_hash, public_key); + }; + + Signature.prototype.verifyHash = function verifyHash(hash, public_key) { + _assert2.default.equal(hash.length, 32, 'A SHA 256 should be 32 bytes long, instead got ' + hash.length); + return (0, _ecdsa.verify)(secp256k1, hash, { + r: this.r, + s: this.s + }, public_key.Q); + }; + + /* */ + + Signature.prototype.toByteBuffer = function toByteBuffer() { + var b = void 0; + b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + }; + + Signature.fromHex = function fromHex(hex) { + return Signature.fromBuffer(Buffer.from(hex, 'hex')); + }; + + Signature.prototype.toHex = function toHex() { + return this.toBuffer().toString('hex'); + }; + + Signature.signHex = function signHex(hex, private_key) { + var buf = void 0; + buf = Buffer.from(hex, 'hex'); + return Signature.signBuffer(buf, private_key); + }; + + Signature.prototype.verifyHex = function verifyHex(hex, public_key) { + var buf = void 0; + buf = Buffer.from(hex, 'hex'); + return this.verifyBuffer(buf, public_key); + }; + + return Signature; +}(); + +exports.default = Signature; +module.exports = exports['default']; +}).call(this,require(35).Buffer) + +},{"11":11,"14":14,"17":17,"27":27,"32":32,"35":35,"59":59}],19:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.SerializerValidation = exports.template = exports.ops = exports.types = exports.fp = exports.Serializer = undefined; + +var _serializer = require(24); + +var _serializer2 = _interopRequireDefault(_serializer); + +var _FastParser = require(20); + +var _FastParser2 = _interopRequireDefault(_FastParser); + +var _types = require(26); + +var _types2 = _interopRequireDefault(_types); + +var _operations = require(23); + +var ops = _interopRequireWildcard(_operations); + +var _template = require(25); + +var _template2 = _interopRequireDefault(_template); + +var _SerializerValidation = require(21); + +var _SerializerValidation2 = _interopRequireDefault(_SerializerValidation); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.Serializer = _serializer2.default; +exports.fp = _FastParser2.default; +exports.types = _types2.default; +exports.ops = ops; +exports.template = _template2.default; +exports.SerializerValidation = _SerializerValidation2.default; +},{"20":20,"21":21,"23":23,"24":24,"25":25,"26":26}],20:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.__esModule = true; + +var _PublicKey = require(11); + +var _PublicKey2 = _interopRequireDefault(_PublicKey); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var FastParser = function () { + function FastParser() { + _classCallCheck(this, FastParser); + } + + FastParser.fixed_data = function fixed_data(b, len, buffer) { + if (!b) { + return; + } + if (buffer) { + var data = buffer.slice(0, len).toString('binary'); + b.append(data, 'binary'); + while (len-- > data.length) { + b.writeUint8(0); + } + } else { + var b_copy = b.copy(b.offset, b.offset + len); + b.skip(len); + return Buffer.from(b_copy.toBinary(), 'binary'); + } + }; + + FastParser.public_key = function public_key(b, _public_key) { + var buffer = void 0; + if (!b) { + return; + } + if (_public_key) { + buffer = _public_key.toBuffer(); + b.append(buffer.toString('binary'), 'binary'); + } else { + buffer = FastParser.fixed_data(b, 33); + return _PublicKey2.default.fromBuffer(buffer); + } + }; + + FastParser.ripemd160 = function ripemd160(b, _ripemd) { + if (!b) { + return; + } + if (_ripemd) { + FastParser.fixed_data(b, 20, _ripemd); + } else { + return FastParser.fixed_data(b, 20); + } + }; + + FastParser.sha256 = function sha256(b, _sha) { + if (!b) { + return; + } + if (_sha) { + FastParser.fixed_data(b, 32, _sha); + } else { + return FastParser.fixed_data(b, 32); + } + }; + + FastParser.time_point_sec = function time_point_sec(b, epoch) { + if (epoch) { + epoch = Math.ceil(epoch / 1000); + b.writeInt32(epoch); + } else { + epoch = b.readInt32(); // fc::time_point_sec + return new Date(epoch * 1000); + } + }; + + return FastParser; +}(); + +exports.default = FastParser; +module.exports = exports['default']; +}).call(this,require(35).Buffer) + +},{"11":11,"35":35}],21:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _bytebuffer = require(38); + +var _ChainTypes = require(3); + +var _ChainTypes2 = _interopRequireDefault(_ChainTypes); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var MAX_SAFE_INT = 9007199254740991; +var MIN_SAFE_INT = -9007199254740991; + +/** + Most validations are skipped and the value returned unchanged when an empty string, + null, or undefined is encountered (except "required"). + Validations support a string format for dealing with large numbers. +*/ +var _my = { + is_empty: function is_empty(value) { + return value === null || value === undefined; + }, + required: function required(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + if (this.is_empty(value)) { + throw new Error('value required ' + field_name + ' | ' + value); + } + + return value; + }, + require_long: function require_long(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + if (!_bytebuffer.Long.isLong(value)) { + throw new Error('Long value required ' + field_name + ' | ' + value); + } + + return value; + }, + string: function string(value) { + if (this.is_empty(value)) { + return value; + } + + if (typeof value !== 'string') { + throw new Error('string required: ' + value); + } + + return value; + }, + number: function number(value) { + if (this.is_empty(value)) { + return value; + } + + if (typeof value !== 'number') { + throw new Error('number required: ' + value); + } + + return value; + }, + whole_number: function whole_number(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + if (this.is_empty(value)) { + return value; + } + + if (/\./.test(value)) { + throw new Error('whole number required ' + field_name + ' ' + value); + } + + return value; + }, + unsigned: function unsigned(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + if (this.is_empty(value)) { + return value; + } + + if (/-/.test(value)) { + throw new Error('unsigned required ' + field_name + ' ' + value); + } + + return value; + }, + is_digits: function is_digits(value) { + if (typeof value === 'number') { + return true; + } + + return (/^[0-9]+$/.test(value) + ); + }, + to_number: function to_number(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + if (this.is_empty(value)) { + return value; + } + + this.no_overflow53(value, field_name); + var int_value = function () { + if (typeof value === 'number') { + return value; + } + + return parseInt(value, 10); + }(); + return int_value; + }, + to_long: function to_long(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + if (this.is_empty(value)) { + return value; + } + + if (_bytebuffer.Long.isLong(value)) { + return value; + } + + this.no_overflow64(value, field_name); + + if (typeof value === 'number') { + value = '' + value; + } + + return _bytebuffer.Long.fromString(value); + }, + to_ulong: function to_ulong(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + if (this.is_empty(value)) { + return value; + } + + if (_bytebuffer.Long.isLong(value)) { + return value; + } + + this.no_overflow64(value, field_name, true); + + if (typeof value === 'number') { + value = '' + value; + } + + return _bytebuffer.Long.fromString(value, true); + }, + to_string: function to_string(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + if (this.is_empty(value)) { + return value; + } + + if (typeof value === 'string') { + return value; + } + + if (typeof value === 'number') { + this.no_overflow53(value, field_name); + return '' + value; + } + + if (_bytebuffer.Long.isLong(value)) { + return value.toString(); + } + + throw new Error('unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value); + }, + require_test: function require_test(regex, value) { + var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; + + if (this.is_empty(value)) { + return value; + } + + if (!regex.test(value)) { + throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value); + } + + return value; + }, + require_match: function require_match(regex, value) { + var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; + + if (this.is_empty(value)) { + return value; + } + + var match = value.match(regex); + + if (match === null) { + throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value); + } + + return match; + }, + require_object_id: function require_object_id(value, field_name) { + return this.require_match(/^([0-9]+)\.([0-9]+)\.([0-9]+)$/, value, field_name); + }, + + + // Does not support over 53 bits + require_range: function require_range(min, max, value) { + var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; + + if (this.is_empty(value)) { + return value; + } + + var num = this.to_number(value); + + if (num < min || num > max) { + throw new Error('out of range ' + value + ' ' + field_name + ' ' + value); + } + + return value; + }, + require_object_type: function require_object_type() { + var reserved_spaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + var type = arguments[1]; + var value = arguments[2]; + var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; + + if (this.is_empty(value)) { + return value; + } + + var object_type = _ChainTypes2.default.object_type[type]; + + if (!object_type) { + throw new Error('Unknown object type ' + type + ' ' + field_name + ' ' + value); + } + + var re = new RegExp(reserved_spaces + '.' + object_type + '.[0-9]+$'); + + if (!re.test(value)) { + throw new Error('Expecting ' + type + ' in format ' + (reserved_spaces + '.' + object_type + '.[0-9]+ ') + ('instead of ' + value + ' ' + field_name + ' ' + value)); + } + + return value; + }, + get_instance: function get_instance(reserve_spaces, type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + + this.require_object_type(reserve_spaces, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, + require_relative_type: function require_relative_type(type, value, field_name) { + this.require_object_type(0, type, value, field_name); + return value; + }, + get_relative_instance: function get_relative_instance(type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + + this.require_object_type(0, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, + require_protocol_type: function require_protocol_type(type, value, field_name) { + this.require_object_type(1, type, value, field_name); + return value; + }, + get_protocol_instance: function get_protocol_instance(type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + + this.require_object_type(1, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, + get_protocol_type: function get_protocol_type(value, field_name) { + if (this.is_empty(value)) { + return value; + } + + this.require_object_id(value, field_name); + var values = value.split('.'); + return this.to_number(values[1]); + }, + get_protocol_type_name: function get_protocol_type_name(value, field_name) { + if (this.is_empty(value)) { + return value; + } + + var type_id = this.get_protocol_type(value, field_name); + return Object.keys(_ChainTypes2.default.object_type)[type_id]; + }, + require_implementation_type: function require_implementation_type(type, value, field_name) { + this.require_object_type(2, type, value, field_name); + return value; + }, + get_implementation_instance: function get_implementation_instance(type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + + this.require_object_type(2, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, + + + // signed / unsigned decimal + no_overflow53: function no_overflow53(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + if (typeof value === 'number') { + if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { + throw new Error('overflow ' + field_name + ' ' + value); + } + + return; + } + + if (typeof value === 'string') { + var int = parseInt(value, 10); + + if (int > MAX_SAFE_INT || int < MIN_SAFE_INT) { + throw new Error('overflow ' + field_name + ' ' + int); + } + + return; + } + + if (_bytebuffer.Long.isLong(value)) { + // typeof value.toInt() is 'number' + this.no_overflow53(value.toInt(), field_name); + return; + } + + throw new Error('unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value); + }, + + + // signed / unsigned whole numbers only + no_overflow64: function no_overflow64(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var unsigned = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + // https://github.com/dcodeIO/Long.js/issues/20 + if (_bytebuffer.Long.isLong(value)) { + return; + } + + // BigInteger#isBigInteger https://github.com/cryptocoinjs/bigi/issues/20 + if (value.t !== undefined && value.s !== undefined) { + this.no_overflow64(value.toString(), field_name, unsigned); + + return; + } + + if (typeof value === 'string') { + // remove leading zeros, will cause a false positive + value = value.replace(/^0+/, ''); + + // remove trailing zeros + while (/0$/.test(value)) { + value = value.substring(0, value.length - 1); + } + + if (/\.$/.test(value)) { + // remove trailing dot + value = value.substring(0, value.length - 1); + } + + if (value === '') { + value = '0'; + } + + var long_string = _bytebuffer.Long.fromString(value, unsigned).toString(); + + if (long_string !== value.trim()) { + throw new Error('overflow ' + field_name + ' ' + value); + } + + return; + } + + if (typeof value === 'number') { + if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { + throw new Error('overflow ' + field_name + ' ' + value); + } + + return; + } + + throw new Error('unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value); + } +}; + +exports.default = _my; +module.exports = exports['default']; +},{"3":3,"38":38}],22:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** Exception nesting. */ +var ErrorWithCause = function () { + function ErrorWithCause(message, cause) { + _classCallCheck(this, ErrorWithCause); + + this.message = message; + + if (typeof cause !== 'undefined' && cause !== null ? cause.message : undefined) { + this.message = 'cause\t' + cause.message + '\t' + this.message; + } + + var stack = ''; // (new Error).stack + + if (typeof cause !== 'undefined' && cause !== null ? cause.stack : undefined) { + stack = 'caused by\n\t' + cause.stack + '\t' + stack; + } + + this.stack = this.message + '\n' + stack; + } + + ErrorWithCause.throw = function _throw(message, cause) { + var msg = message; + + if (typeof cause !== 'undefined' && cause !== null ? cause.message : undefined) { + msg += '\t cause: ' + cause.message + ' '; + } + + if (typeof cause !== 'undefined' && cause !== null ? cause.stack : undefined) { + msg += '\n stack: ' + cause.stack + ' '; + } + + throw new Error(msg); + }; + + return ErrorWithCause; +}(); + +exports.default = ErrorWithCause; +module.exports = exports['default']; +},{}],23:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.stealth_memo_data = exports.global_betting_statistics = exports.betting_market_position = exports.bet = exports.betting_market = exports.betting_market_group = exports.betting_market_rules = exports.event = exports.event_group = exports.sport = exports.signed_transaction = exports.transaction = exports.bet_adjusted = exports.betting_market_update = exports.betting_market_group_update = exports.tournament_leave = exports.tournament_payout = exports.payout_type = exports.bet_canceled = exports.bet_cancel = exports.bet_matched = exports.betting_market_group_cancel_unmatched_bets = exports.betting_market_group_resolved = exports.betting_market_group_resolve = exports.betting_market_resolution_type = exports.bet_place = exports.bet_type = exports.betting_market_create = exports.betting_market_group_create = exports.betting_market_rules_update = exports.betting_market_rules_create = exports.event_update = exports.event_create = exports.event_group_update = exports.event_group_create = exports.sport_update = exports.sport_create = exports.asset_dividend_distribution = exports.asset_update_dividend = exports.dividend_asset_options = exports.game_move = exports.rock_paper_scissors_throw_reveal = exports.rock_paper_scissors_throw_commit = exports.rock_paper_scissors_gesture = exports.tournament_join = exports.tournament_create = exports.tournament_options = exports.rock_paper_scissors_game_options = exports.fba_distribute = exports.asset_claim_fees = exports.asset_settle_cancel = exports.transfer_from_blind = exports.blind_transfer = exports.blind_input = exports.transfer_to_blind = exports.blind_output = exports.stealth_confirmation = exports.override_transfer = exports.balance_claim = exports.assert = exports.block_id_predicate = exports.asset_symbol_eq_lit_predicate = exports.account_name_eq_lit_predicate = exports.custom = exports.worker_create = exports.burn_worker_initializer = exports.vesting_balance_worker_initializer = exports.refund_worker_initializer = exports.vesting_balance_withdraw = exports.vesting_balance_create = exports.cdd_vesting_policy_initializer = exports.linear_vesting_policy_initializer = exports.committee_member_update_global_parameters = exports.chain_parameters = exports.committee_member_update = exports.committee_member_create = exports.withdraw_permission_delete = exports.withdraw_permission_claim = exports.withdraw_permission_update = exports.withdraw_permission_create = exports.proposal_delete = exports.proposal_update = exports.proposal_create = exports.op_wrapper = exports.witness_update = exports.witness_create = exports.asset_publish_feed = exports.price_feed = exports.asset_global_settle = exports.asset_settle = exports.asset_fund_fee_pool = exports.asset_reserve = exports.asset_issue = undefined; +exports.asset_update_feed_producers = exports.asset_update_bitasset = exports.asset_update = exports.asset_create = exports.bitasset_options = exports.asset_options = exports.price = exports.account_transfer = exports.account_upgrade = exports.account_whitelist = exports.account_update = exports.account_create = exports.account_options = exports.authority = exports.fill_order = exports.call_order_update = exports.limit_order_cancel = exports.limit_order_create = exports.transfer = exports.memo_data = exports.signed_block_header = exports.block_header = exports.signed_block = exports.processed_transaction = exports.asset = exports.void_result = exports.fee_schedule = exports.bet_adjusted_operation_fee_parameters = exports.betting_market_update_operation_fee_parameters = exports.betting_market_group_update_operation_fee_parameters = exports.tournament_leave_operation_fee_parameters = exports.tournament_payout_operation_fee_parameters = exports.game_move_operation_fee_parameters = exports.tournament_join_operation_fee_parameters = exports.tournament_create_operation_fee_parameters = exports.bet_canceled_operation_fee_parameters = exports.bet_cancel_operation_fee_parameters = exports.bet_matched_operation_fee_parameters = exports.betting_market_group_cancel_unmatched_bets_operation_fee_parameters = exports.betting_market_group_resolved_operation_fee_parameters = exports.betting_market_group_resolve_operation_fee_parameters = exports.bet_place_operation_fee_parameters = exports.betting_market_create_operation_fee_parameters = exports.betting_market_group_create_operation_fee_parameters = exports.betting_market_rules_update_operation_fee_parameters = exports.betting_market_rules_create_operation_fee_parameters = exports.event_update_operation_fee_parameters = exports.event_create_operation_fee_parameters = exports.event_group_update_operation_fee_parameters = exports.event_group_create_operation_fee_parameters = exports.sport_update_operation_fee_parameters = exports.sport_create_operation_fee_parameters = exports.asset_dividend_distribution_operation_fee_parameters = exports.asset_update_dividend_operation_fee_parameters = exports.fba_distribute_operation_fee_parameters = exports.asset_claim_fees_operation_fee_parameters = exports.asset_settle_cancel_operation_fee_parameters = exports.transfer_from_blind_operation_fee_parameters = exports.blind_transfer_operation_fee_parameters = exports.transfer_to_blind_operation_fee_parameters = exports.override_transfer_operation_fee_parameters = exports.balance_claim_operation_fee_parameters = exports.assert_operation_fee_parameters = exports.custom_operation_fee_parameters = exports.worker_create_operation_fee_parameters = exports.vesting_balance_withdraw_operation_fee_parameters = exports.vesting_balance_create_operation_fee_parameters = exports.committee_member_update_global_parameters_operation_fee_parameters = exports.committee_member_update_operation_fee_parameters = exports.committee_member_create_operation_fee_parameters = exports.withdraw_permission_delete_operation_fee_parameters = exports.withdraw_permission_claim_operation_fee_parameters = exports.withdraw_permission_update_operation_fee_parameters = exports.withdraw_permission_create_operation_fee_parameters = exports.proposal_delete_operation_fee_parameters = exports.proposal_update_operation_fee_parameters = exports.proposal_create_operation_fee_parameters = exports.witness_update_operation_fee_parameters = exports.witness_create_operation_fee_parameters = exports.asset_publish_feed_operation_fee_parameters = exports.asset_global_settle_operation_fee_parameters = exports.asset_settle_operation_fee_parameters = exports.asset_fund_fee_pool_operation_fee_parameters = exports.asset_reserve_operation_fee_parameters = exports.asset_issue_operation_fee_parameters = exports.asset_update_feed_producers_operation_fee_parameters = exports.asset_update_bitasset_operation_fee_parameters = exports.asset_update_operation_fee_parameters = exports.asset_create_operation_fee_parameters = exports.account_transfer_operation_fee_parameters = exports.account_upgrade_operation_fee_parameters = exports.account_whitelist_operation_fee_parameters = exports.account_update_operation_fee_parameters = exports.account_create_operation_fee_parameters = exports.fill_order_operation_fee_parameters = exports.call_order_update_operation_fee_parameters = exports.limit_order_cancel_operation_fee_parameters = exports.limit_order_create_operation_fee_parameters = exports.transfer_operation_fee_parameters = exports.operation = undefined; + +var _types = require(26); + +var _types2 = _interopRequireDefault(_types); + +var _serializer = require(24); + +var _serializer2 = _interopRequireDefault(_serializer); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var uint8 = _types2.default.uint8, + uint16 = _types2.default.uint16, + uint32 = _types2.default.uint32, + int64 = _types2.default.int64, + uint64 = _types2.default.uint64, + string = _types2.default.string, + bytes = _types2.default.bytes, + bool = _types2.default.bool, + array = _types2.default.array, + protocol_id_type = _types2.default.protocol_id_type, + object_id_type = _types2.default.object_id_type, + vote_id = _types2.default.vote_id, + implementation_id_type = _types2.default.implementation_id_type, + static_variant = _types2.default.static_variant, + map = _types2.default.map, + set = _types2.default.set, + public_key = _types2.default.public_key, + address = _types2.default.address, + time_point_sec = _types2.default.time_point_sec, + optional = _types2.default.optional, + variant_object = _types2.default.variant_object, + enumeration = _types2.default.enumeration, + sha256 = _types2.default.sha256; + + +var future_extensions = _types2.default.void; + +/* +When updating generated code +Replace: operation = static_variant [ +with: operation.st_operations = [ + +Delete: +public_key = new Serializer( + "public_key" + key_data: bytes 33 +); +*/ + +function Serializer(operation_name, serilization_types_object) { + return new _serializer2.default(operation_name, serilization_types_object); +} +// Place-holder, their are dependencies on "operation" .. The final list of +// operations is not avialble until the very end of the generated code. +// See: operation.st_operations = ... +// module.exports["operation"] = operation; + +var operation = static_variant(); + +// Custom-types follow Generated code: + +// ## Generated code follows +// # programs/js_operation_serializer > npm i -g decaffeinate +// ## ------------------------------- +var transfer_operation_fee_parameters = new Serializer('transfer_operation_fee_parameters', { + fee: uint64, + price_per_kbyte: uint32 +}); + +var limit_order_create_operation_fee_parameters = new Serializer('limit_order_create_operation_fee_parameters', { + fee: uint64 +}); + +var limit_order_cancel_operation_fee_parameters = new Serializer('limit_order_cancel_operation_fee_parameters', { + fee: uint64 +}); + +var call_order_update_operation_fee_parameters = new Serializer('call_order_update_operation_fee_parameters', { + fee: uint64 +}); + +var fill_order_operation_fee_parameters = new Serializer('fill_order_operation_fee_parameters'); + +var account_create_operation_fee_parameters = new Serializer('account_create_operation_fee_parameters', { + basic_fee: uint64, + premium_fee: uint64, + price_per_kbyte: uint32 +}); + +var account_update_operation_fee_parameters = new Serializer('account_update_operation_fee_parameters', { + fee: int64, + price_per_kbyte: uint32 +}); + +var account_whitelist_operation_fee_parameters = new Serializer('account_whitelist_operation_fee_parameters', { + fee: int64 +}); + +var account_upgrade_operation_fee_parameters = new Serializer('account_upgrade_operation_fee_parameters', { + membership_annual_fee: uint64, + membership_lifetime_fee: uint64 +}); + +var account_transfer_operation_fee_parameters = new Serializer('account_transfer_operation_fee_parameters', { + fee: uint64 +}); + +var asset_create_operation_fee_parameters = new Serializer('asset_create_operation_fee_parameters', { + symbol3: uint64, + symbol4: uint64, + long_symbol: uint64, + price_per_kbyte: uint32 +}); + +var asset_update_operation_fee_parameters = new Serializer('asset_update_operation_fee_parameters', { + fee: uint64, + price_per_kbyte: uint32 +}); + +var asset_update_bitasset_operation_fee_parameters = new Serializer('asset_update_bitasset_operation_fee_parameters', { + fee: uint64 +}); + +var asset_update_feed_producers_operation_fee_parameters = new Serializer('asset_update_feed_producers_operation_fee_parameters', { + fee: uint64 +}); + +var asset_issue_operation_fee_parameters = new Serializer('asset_issue_operation_fee_parameters', { + fee: uint64, + price_per_kbyte: uint32 +}); + +var asset_reserve_operation_fee_parameters = new Serializer('asset_reserve_operation_fee_parameters', { + fee: uint64 +}); + +var asset_fund_fee_pool_operation_fee_parameters = new Serializer('asset_fund_fee_pool_operation_fee_parameters', { + fee: uint64 +}); + +var asset_settle_operation_fee_parameters = new Serializer('asset_settle_operation_fee_parameters', { + fee: uint64 +}); + +var asset_global_settle_operation_fee_parameters = new Serializer('asset_global_settle_operation_fee_parameters', { + fee: uint64 +}); + +var asset_publish_feed_operation_fee_parameters = new Serializer('asset_publish_feed_operation_fee_parameters', { + fee: uint64 +}); + +var witness_create_operation_fee_parameters = new Serializer('witness_create_operation_fee_parameters', { + fee: uint64 +}); + +var witness_update_operation_fee_parameters = new Serializer('witness_update_operation_fee_parameters', { + fee: int64 +}); + +var proposal_create_operation_fee_parameters = new Serializer('proposal_create_operation_fee_parameters', { + fee: uint64, + price_per_kbyte: uint32 +}); + +var proposal_update_operation_fee_parameters = new Serializer('proposal_update_operation_fee_parameters', { + fee: uint64, + price_per_kbyte: uint32 +}); + +var proposal_delete_operation_fee_parameters = new Serializer('proposal_delete_operation_fee_parameters', { + fee: uint64 +}); + +var withdraw_permission_create_operation_fee_parameters = new Serializer('withdraw_permission_create_operation_fee_parameters', { + fee: uint64 +}); + +var withdraw_permission_update_operation_fee_parameters = new Serializer('withdraw_permission_update_operation_fee_parameters', { + fee: uint64 +}); + +var withdraw_permission_claim_operation_fee_parameters = new Serializer('withdraw_permission_claim_operation_fee_parameters', { + fee: uint64, + price_per_kbyte: uint32 +}); + +var withdraw_permission_delete_operation_fee_parameters = new Serializer('withdraw_permission_delete_operation_fee_parameters', { + fee: uint64 +}); + +var committee_member_create_operation_fee_parameters = new Serializer('committee_member_create_operation_fee_parameters', { + fee: uint64 +}); + +var committee_member_update_operation_fee_parameters = new Serializer('committee_member_update_operation_fee_parameters', { + fee: uint64 +}); + +var committee_member_update_global_parameters_operation_fee_parameters = new Serializer('committee_member_update_global_parameters_operation_fee_parameters', { + fee: uint64 +}); + +var vesting_balance_create_operation_fee_parameters = new Serializer('vesting_balance_create_operation_fee_parameters', { + fee: uint64 +}); + +var vesting_balance_withdraw_operation_fee_parameters = new Serializer('vesting_balance_withdraw_operation_fee_parameters', { + fee: uint64 +}); + +var worker_create_operation_fee_parameters = new Serializer('worker_create_operation_fee_parameters', { + fee: uint64 +}); + +var custom_operation_fee_parameters = new Serializer('custom_operation_fee_parameters', { + fee: uint64, + price_per_kbyte: uint32 +}); + +var assert_operation_fee_parameters = new Serializer('assert_operation_fee_parameters', { + fee: uint64 +}); + +var balance_claim_operation_fee_parameters = new Serializer('balance_claim_operation_fee_parameters'); + +var override_transfer_operation_fee_parameters = new Serializer('override_transfer_operation_fee_parameters', { + fee: uint64, + price_per_kbyte: uint32 +}); + +var transfer_to_blind_operation_fee_parameters = new Serializer('transfer_to_blind_operation_fee_parameters', { + fee: uint64, + price_per_output: uint32 +}); + +var blind_transfer_operation_fee_parameters = new Serializer('blind_transfer_operation_fee_parameters', { + fee: uint64, + price_per_output: uint32 +}); + +var transfer_from_blind_operation_fee_parameters = new Serializer('transfer_from_blind_operation_fee_parameters', { + fee: uint64 +}); + +var asset_settle_cancel_operation_fee_parameters = new Serializer('asset_settle_cancel_operation_fee_parameters'); + +var asset_claim_fees_operation_fee_parameters = new Serializer('asset_claim_fees_operation_fee_parameters', { + fee: uint64 +}); + +var fba_distribute_operation_fee_parameters = new Serializer('fba_distribute_operation_fee_parameters', {}); + +var asset_update_dividend_operation_fee_parameters = new Serializer('asset_update_dividend_operation_fee_parameters', { + fee: uint64 +}); + +var asset_dividend_distribution_operation_fee_parameters = new Serializer('asset_dividend_distribution_operation_fee_parameters', { + distribution_base_fee: uint64, + distribution_fee_per_holder: uint32 +}); + +var sport_create_operation_fee_parameters = new Serializer('sport_create_operation_fee_parameters', { + fee: uint64 +}); + +var sport_update_operation_fee_parameters = new Serializer('sport_update_operation_fee_parameters', { + fee: uint64 +}); + +var event_group_create_operation_fee_parameters = new Serializer('event_group_create_operation_fee_parameters', { + fee: uint64 +}); + +var event_group_update_operation_fee_parameters = new Serializer('event_group_update_operation_fee_parameters', { + fee: uint64 +}); + +var event_create_operation_fee_parameters = new Serializer('event_create_operation_fee_parameters', { + fee: uint64 +}); + +var event_update_operation_fee_parameters = new Serializer('event_update_operation_fee_parameters', { + fee: uint64 +}); + +var betting_market_rules_create_operation_fee_parameters = new Serializer('betting_market_rules_create_operation_fee_parameters', { + fee: uint64 +}); + +var betting_market_rules_update_operation_fee_parameters = new Serializer('betting_market_rules_update_operation_fee_parameters', { + fee: uint64 +}); + +var betting_market_group_create_operation_fee_parameters = new Serializer('betting_market_group_create_operation_fee_parameters', { + fee: uint64 +}); + +var betting_market_create_operation_fee_parameters = new Serializer('betting_market_create_operation_fee_parameters', { + fee: uint64 +}); + +var bet_place_operation_fee_parameters = new Serializer('bet_place_operation_fee_parameters', { + fee: uint64 +}); + +var betting_market_group_resolve_operation_fee_parameters = new Serializer('betting_market_group_resolve_operation_fee_parameters', { + fee: uint64 +}); + +var betting_market_group_resolved_operation_fee_parameters = new Serializer('betting_market_group_resolved_operation_fee_parameters'); + +var betting_market_group_cancel_unmatched_bets_operation_fee_parameters = new Serializer('betting_market_group_cancel_unmatched_bets_operation_fee_parameters', { + fee: uint64 +}); + +var bet_matched_operation_fee_parameters = new Serializer('bet_matched_operation_fee_parameters'); + +var bet_cancel_operation_fee_parameters = new Serializer('bet_cancel_operation_fee_parameters', { + fee: uint64 +}); + +var bet_canceled_operation_fee_parameters = new Serializer('bet_canceled_operation_fee_parameters'); + +var tournament_create_operation_fee_parameters = new Serializer('tournament_create_operation_fee_parameters', { + fee: int64 +}); + +var tournament_join_operation_fee_parameters = new Serializer('tournament_join_operation_fee_parameters', { + fee: int64 +}); + +var game_move_operation_fee_parameters = new Serializer('game_move_operation_fee_parameters', { + fee: int64 +}); + +var tournament_payout_operation_fee_parameters = new Serializer('tournament_payout_operation_fee_parameters'); + +var tournament_leave_operation_fee_parameters = new Serializer('tournament_leave_operation_fee_parameters', { + fee: int64 +}); + +var betting_market_group_update_operation_fee_parameters = new Serializer('betting_market_group_update_operation_fee_parameters', { + fee: uint64 +}); + +var betting_market_update_operation_fee_parameters = new Serializer('betting_market_update_operation_fee_parameters', { + fee: uint64 +}); + +var bet_adjusted_operation_fee_parameters = new Serializer('bet_adjusted_operation_fee_parameters'); + +var fee_parameters = static_variant([transfer_operation_fee_parameters, limit_order_create_operation_fee_parameters, limit_order_cancel_operation_fee_parameters, call_order_update_operation_fee_parameters, fill_order_operation_fee_parameters, account_create_operation_fee_parameters, account_update_operation_fee_parameters, account_whitelist_operation_fee_parameters, account_upgrade_operation_fee_parameters, account_transfer_operation_fee_parameters, asset_create_operation_fee_parameters, asset_update_operation_fee_parameters, asset_update_bitasset_operation_fee_parameters, asset_update_feed_producers_operation_fee_parameters, asset_issue_operation_fee_parameters, asset_reserve_operation_fee_parameters, asset_fund_fee_pool_operation_fee_parameters, asset_settle_operation_fee_parameters, asset_global_settle_operation_fee_parameters, asset_publish_feed_operation_fee_parameters, witness_create_operation_fee_parameters, witness_update_operation_fee_parameters, proposal_create_operation_fee_parameters, proposal_update_operation_fee_parameters, proposal_delete_operation_fee_parameters, withdraw_permission_create_operation_fee_parameters, withdraw_permission_update_operation_fee_parameters, withdraw_permission_claim_operation_fee_parameters, withdraw_permission_delete_operation_fee_parameters, committee_member_create_operation_fee_parameters, committee_member_update_operation_fee_parameters, committee_member_update_global_parameters_operation_fee_parameters, vesting_balance_create_operation_fee_parameters, vesting_balance_withdraw_operation_fee_parameters, worker_create_operation_fee_parameters, custom_operation_fee_parameters, assert_operation_fee_parameters, balance_claim_operation_fee_parameters, override_transfer_operation_fee_parameters, transfer_to_blind_operation_fee_parameters, blind_transfer_operation_fee_parameters, transfer_from_blind_operation_fee_parameters, asset_settle_cancel_operation_fee_parameters, asset_claim_fees_operation_fee_parameters, fba_distribute_operation_fee_parameters, tournament_create_operation_fee_parameters, tournament_join_operation_fee_parameters, game_move_operation_fee_parameters, asset_update_dividend_operation_fee_parameters, asset_dividend_distribution_operation_fee_parameters, tournament_payout_operation_fee_parameters, tournament_leave_operation_fee_parameters, sport_create_operation_fee_parameters, sport_update_operation_fee_parameters, event_group_create_operation_fee_parameters, event_group_update_operation_fee_parameters, event_create_operation_fee_parameters, event_update_operation_fee_parameters, betting_market_rules_create_operation_fee_parameters, betting_market_rules_update_operation_fee_parameters, betting_market_group_create_operation_fee_parameters, betting_market_create_operation_fee_parameters, bet_place_operation_fee_parameters, betting_market_group_resolve_operation_fee_parameters, betting_market_group_resolved_operation_fee_parameters, bet_adjusted_operation_fee_parameters, betting_market_group_cancel_unmatched_bets_operation_fee_parameters, bet_matched_operation_fee_parameters, bet_cancel_operation_fee_parameters, bet_canceled_operation_fee_parameters, betting_market_group_update_operation_fee_parameters, betting_market_update_operation_fee_parameters +// Missing event_update_status +]); + +var fee_schedule = new Serializer('fee_schedule', { + parameters: set(fee_parameters), + scale: uint32 +}); + +var void_result = new Serializer('void_result'); + +var asset = new Serializer('asset', { + amount: int64, + asset_id: protocol_id_type('asset') +}); + +var operation_result = static_variant([void_result, object_id_type, asset]); + +var processed_transaction = new Serializer('processed_transaction', { + ref_block_num: uint16, + ref_block_prefix: uint32, + expiration: time_point_sec, + operations: array(operation), + extensions: set(future_extensions), + signatures: array(bytes(65)), + operation_results: array(operation_result) +}); + +var signed_block = new Serializer('signed_block', { + previous: bytes(20), + timestamp: time_point_sec, + witness: protocol_id_type('witness'), + next_secret_hash: bytes(20), + previous_secret: bytes(20), + transaction_merkle_root: bytes(20), + extensions: set(future_extensions), + witness_signature: bytes(65), + transactions: array(processed_transaction) +}); + +var block_header = new Serializer('block_header', { + previous: bytes(20), + timestamp: time_point_sec, + witness: protocol_id_type('witness'), + next_secret_hash: bytes(20), + previous_secret: bytes(20), + transaction_merkle_root: bytes(20), + extensions: set(future_extensions) +}); + +var signed_block_header = new Serializer('signed_block_header', { + previous: bytes(20), + timestamp: time_point_sec, + witness: protocol_id_type('witness'), + next_secret_hash: bytes(20), + previous_secret: bytes(20), + transaction_merkle_root: bytes(20), + extensions: set(future_extensions), + witness_signature: bytes(65) +}); + +var memo_data = new Serializer('memo_data', { + from: public_key, + to: public_key, + nonce: uint64, + message: bytes() +}); + +var transfer = new Serializer('transfer', { + fee: asset, + from: protocol_id_type('account'), + to: protocol_id_type('account'), + amount: asset, + memo: optional(memo_data), + extensions: set(future_extensions) +}); + +var limit_order_create = new Serializer('limit_order_create', { + fee: asset, + seller: protocol_id_type('account'), + amount_to_sell: asset, + min_to_receive: asset, + expiration: time_point_sec, + fill_or_kill: bool, + extensions: set(future_extensions) +}); + +var limit_order_cancel = new Serializer('limit_order_cancel', { + fee: asset, + fee_paying_account: protocol_id_type('account'), + order: protocol_id_type('limit_order'), + extensions: set(future_extensions) +}); + +var call_order_update = new Serializer('call_order_update', { + fee: asset, + funding_account: protocol_id_type('account'), + delta_collateral: asset, + delta_debt: asset, + extensions: set(future_extensions) +}); + +var fill_order = new Serializer('fill_order', { + fee: asset, + order_id: object_id_type, + account_id: protocol_id_type('account'), + pays: asset, + receives: asset +}); + +var authority = new Serializer('authority', { + weight_threshold: uint32, + account_auths: map(protocol_id_type('account'), uint16), + key_auths: map(public_key, uint16), + address_auths: map(address, uint16) +}); + +var account_options = new Serializer('account_options', { + memo_key: public_key, + voting_account: protocol_id_type('account'), + num_witness: uint16, + num_committee: uint16, + votes: set(vote_id), + extensions: set(future_extensions) +}); + +var account_create = new Serializer('account_create', { + fee: asset, + registrar: protocol_id_type('account'), + referrer: protocol_id_type('account'), + referrer_percent: uint16, + name: string, + owner: authority, + active: authority, + options: account_options, + extensions: set(future_extensions) +}); + +var account_update = new Serializer('account_update', { + fee: asset, + account: protocol_id_type('account'), + owner: optional(authority), + active: optional(authority), + new_options: optional(account_options), + extensions: set(future_extensions) +}); + +var account_whitelist = new Serializer('account_whitelist', { + fee: asset, + authorizing_account: protocol_id_type('account'), + account_to_list: protocol_id_type('account'), + new_listing: uint8, + extensions: set(future_extensions) +}); + +var account_upgrade = new Serializer('account_upgrade', { + fee: asset, + account_to_upgrade: protocol_id_type('account'), + upgrade_to_lifetime_member: bool, + extensions: set(future_extensions) +}); + +var account_transfer = new Serializer('account_transfer', { + fee: asset, + account_id: protocol_id_type('account'), + new_owner: protocol_id_type('account'), + extensions: set(future_extensions) +}); + +var price = new Serializer('price', { + base: asset, + quote: asset +}); + +var asset_options = new Serializer('asset_options', { + max_supply: int64, + market_fee_percent: uint16, + max_market_fee: int64, + issuer_permissions: uint16, + flags: uint16, + core_exchange_rate: price, + whitelist_authorities: set(protocol_id_type('account')), + blacklist_authorities: set(protocol_id_type('account')), + whitelist_markets: set(protocol_id_type('asset')), + blacklist_markets: set(protocol_id_type('asset')), + description: string, + extensions: set(future_extensions) +}); + +var bitasset_options = new Serializer('bitasset_options', { + feed_lifetime_sec: uint32, + minimum_feeds: uint8, + force_settlement_delay_sec: uint32, + force_settlement_offset_percent: uint16, + maximum_force_settlement_volume: uint16, + short_backing_asset: protocol_id_type('asset'), + extensions: set(future_extensions) +}); + +var asset_create = new Serializer('asset_create', { + fee: asset, + issuer: protocol_id_type('account'), + symbol: string, + precision: uint8, + common_options: asset_options, + bitasset_opts: optional(bitasset_options), + is_prediction_market: bool, + extensions: set(future_extensions) +}); + +var asset_update = new Serializer('asset_update', { + fee: asset, + issuer: protocol_id_type('account'), + asset_to_update: protocol_id_type('asset'), + new_issuer: optional(protocol_id_type('account')), + new_options: asset_options, + extensions: set(future_extensions) +}); + +var asset_update_bitasset = new Serializer('asset_update_bitasset', { + fee: asset, + issuer: protocol_id_type('account'), + asset_to_update: protocol_id_type('asset'), + new_options: bitasset_options, + extensions: set(future_extensions) +}); + +var asset_update_feed_producers = new Serializer('asset_update_feed_producers', { + fee: asset, + issuer: protocol_id_type('account'), + asset_to_update: protocol_id_type('asset'), + new_feed_producers: set(protocol_id_type('account')), + extensions: set(future_extensions) +}); + +var asset_issue = new Serializer('asset_issue', { + fee: asset, + issuer: protocol_id_type('account'), + asset_to_issue: asset, + issue_to_account: protocol_id_type('account'), + memo: optional(memo_data), + extensions: set(future_extensions) +}); + +var asset_reserve = new Serializer('asset_reserve', { + fee: asset, + payer: protocol_id_type('account'), + amount_to_reserve: asset, + extensions: set(future_extensions) +}); + +var asset_fund_fee_pool = new Serializer('asset_fund_fee_pool', { + fee: asset, + from_account: protocol_id_type('account'), + asset_id: protocol_id_type('asset'), + amount: int64, + extensions: set(future_extensions) +}); + +var asset_settle = new Serializer('asset_settle', { + fee: asset, + account: protocol_id_type('account'), + amount: asset, + extensions: set(future_extensions) +}); + +var asset_global_settle = new Serializer('asset_global_settle', { + fee: asset, + issuer: protocol_id_type('account'), + asset_to_settle: protocol_id_type('asset'), + settle_price: price, + extensions: set(future_extensions) +}); + +var price_feed = new Serializer('price_feed', { + settlement_price: price, + maintenance_collateral_ratio: uint16, + maximum_short_squeeze_ratio: uint16, + core_exchange_rate: price +}); + +var asset_publish_feed = new Serializer('asset_publish_feed', { + fee: asset, + publisher: protocol_id_type('account'), + asset_id: protocol_id_type('asset'), + feed: price_feed, + extensions: set(future_extensions) +}); + +var witness_create = new Serializer('witness_create', { + fee: asset, + witness_account: protocol_id_type('account'), + url: string, + block_signing_key: public_key, + initial_secret: bytes(20) +}); + +var witness_update = new Serializer('witness_update', { + fee: asset, + witness: protocol_id_type('witness'), + witness_account: protocol_id_type('account'), + new_url: optional(string), + new_signing_key: optional(public_key), + new_initial_secret: optional(bytes(20)) +}); + +var op_wrapper = new Serializer('op_wrapper', { + op: operation +}); + +var proposal_create = new Serializer('proposal_create', { + fee: asset, + fee_paying_account: protocol_id_type('account'), + expiration_time: time_point_sec, + proposed_ops: array(op_wrapper), + review_period_seconds: optional(uint32), + extensions: set(future_extensions) +}); + +var proposal_update = new Serializer('proposal_update', { + fee: asset, + fee_paying_account: protocol_id_type('account'), + proposal: protocol_id_type('proposal'), + active_approvals_to_add: set(protocol_id_type('account')), + active_approvals_to_remove: set(protocol_id_type('account')), + owner_approvals_to_add: set(protocol_id_type('account')), + owner_approvals_to_remove: set(protocol_id_type('account')), + key_approvals_to_add: set(public_key), + key_approvals_to_remove: set(public_key), + extensions: set(future_extensions) +}); + +var proposal_delete = new Serializer('proposal_delete', { + fee: asset, + fee_paying_account: protocol_id_type('account'), + using_owner_authority: bool, + proposal: protocol_id_type('proposal'), + extensions: set(future_extensions) +}); + +var withdraw_permission_create = new Serializer('withdraw_permission_create', { + fee: asset, + withdraw_from_account: protocol_id_type('account'), + authorized_account: protocol_id_type('account'), + withdrawal_limit: asset, + withdrawal_period_sec: uint32, + periods_until_expiration: uint32, + period_start_time: time_point_sec +}); + +var withdraw_permission_update = new Serializer('withdraw_permission_update', { + fee: asset, + withdraw_from_account: protocol_id_type('account'), + authorized_account: protocol_id_type('account'), + permission_to_update: protocol_id_type('withdraw_permission'), + withdrawal_limit: asset, + withdrawal_period_sec: uint32, + period_start_time: time_point_sec, + periods_until_expiration: uint32 +}); + +var withdraw_permission_claim = new Serializer('withdraw_permission_claim', { + fee: asset, + withdraw_permission: protocol_id_type('withdraw_permission'), + withdraw_from_account: protocol_id_type('account'), + withdraw_to_account: protocol_id_type('account'), + amount_to_withdraw: asset, + memo: optional(memo_data) +}); + +var withdraw_permission_delete = new Serializer('withdraw_permission_delete', { + fee: asset, + withdraw_from_account: protocol_id_type('account'), + authorized_account: protocol_id_type('account'), + withdrawal_permission: protocol_id_type('withdraw_permission') +}); + +var committee_member_create = new Serializer('committee_member_create', { + fee: asset, + committee_member_account: protocol_id_type('account'), + url: string +}); + +var committee_member_update = new Serializer('committee_member_update', { + fee: asset, + committee_member: protocol_id_type('committee_member'), + committee_member_account: protocol_id_type('account'), + new_url: optional(string) +}); + +var chain_parameters = new Serializer('chain_parameters', { + current_fees: fee_schedule, + block_interval: uint8, + maintenance_interval: uint32, + maintenance_skip_slots: uint8, + committee_proposal_review_period: uint32, + maximum_transaction_size: uint32, + maximum_block_size: uint32, + maximum_time_until_expiration: uint32, + maximum_proposal_lifetime: uint32, + maximum_asset_whitelist_authorities: uint8, + maximum_asset_feed_publishers: uint8, + maximum_witness_count: uint16, + maximum_committee_count: uint16, + maximum_authority_membership: uint16, + reserve_percent_of_fee: uint16, + network_percent_of_fee: uint16, + lifetime_referrer_percent_of_fee: uint16, + cashback_vesting_period_seconds: uint32, + cashback_vesting_threshold: int64, + count_non_member_votes: bool, + allow_non_member_whitelists: bool, + witness_pay_per_block: int64, + worker_budget_per_day: int64, + max_predicate_opcode: uint16, + fee_liquidation_threshold: int64, + accounts_per_fee_scale: uint16, + account_fee_scale_bitshifts: uint8, + max_authority_depth: uint8, + min_bet_multiplier: uint32, + max_bet_multiplier: uint32, + betting_rake_fee_percentage: uint16, + permitted_betting_odds_increments: map(uint32, uint32), + witness_schedule_algorithm: uint8, + live_betting_delay_time: uint16, + min_round_delay: uint32, + max_round_delay: uint32, + min_time_per_commit_move: uint32, + max_time_per_commit_move: uint32, + min_time_per_reveal_move: uint32, + max_time_per_reveal_move: uint32, + rake_fee_percentage: uint16, + maximum_registration_deadline: uint32, + maximum_players_in_tournament: uint16, + maximum_tournament_whitelist_length: uint16, + maximum_tournament_start_time_in_future: uint32, + maximum_tournament_start_delay: uint32, + maximum_tournament_number_of_wins: uint16, + extensions: set(future_extensions) +}); + +var committee_member_update_global_parameters = new Serializer('committee_member_update_global_parameters', { + fee: asset, + new_parameters: chain_parameters +}); + +var linear_vesting_policy_initializer = new Serializer('linear_vesting_policy_initializer', { + begin_timestamp: time_point_sec, + vesting_cliff_seconds: uint32, + vesting_duration_seconds: uint32 +}); + +var cdd_vesting_policy_initializer = new Serializer('cdd_vesting_policy_initializer', { + start_claim: time_point_sec, + vesting_seconds: uint32 +}); + +var vesting_policy_initializer = static_variant([linear_vesting_policy_initializer, cdd_vesting_policy_initializer]); + +var vesting_balance_create = new Serializer('vesting_balance_create', { + fee: asset, + creator: protocol_id_type('account'), + owner: protocol_id_type('account'), + amount: asset, + policy: vesting_policy_initializer +}); + +var vesting_balance_withdraw = new Serializer('vesting_balance_withdraw', { + fee: asset, + vesting_balance: protocol_id_type('vesting_balance'), + owner: protocol_id_type('account'), + amount: asset +}); + +var refund_worker_initializer = new Serializer('refund_worker_initializer'); + +var vesting_balance_worker_initializer = new Serializer('vesting_balance_worker_initializer', { + pay_vesting_period_days: uint16 +}); + +var burn_worker_initializer = new Serializer('burn_worker_initializer'); + +var worker_initializer = static_variant([refund_worker_initializer, vesting_balance_worker_initializer, burn_worker_initializer]); + +var worker_create = new Serializer('worker_create', { + fee: asset, + owner: protocol_id_type('account'), + work_begin_date: time_point_sec, + work_end_date: time_point_sec, + daily_pay: int64, + name: string, + url: string, + initializer: worker_initializer +}); + +var custom = new Serializer('custom', { + fee: asset, + payer: protocol_id_type('account'), + required_auths: set(protocol_id_type('account')), + id: uint16, + data: bytes() +}); + +var account_name_eq_lit_predicate = new Serializer('account_name_eq_lit_predicate', { + account_id: protocol_id_type('account'), + name: string +}); + +var asset_symbol_eq_lit_predicate = new Serializer('asset_symbol_eq_lit_predicate', { + asset_id: protocol_id_type('asset'), + symbol: string +}); + +var block_id_predicate = new Serializer('block_id_predicate', { + id: bytes(20) +}); + +var predicate = static_variant([account_name_eq_lit_predicate, asset_symbol_eq_lit_predicate, block_id_predicate]); + +var assert = new Serializer('assert', { + fee: asset, + fee_paying_account: protocol_id_type('account'), + predicates: array(predicate), + required_auths: set(protocol_id_type('account')), + extensions: set(future_extensions) +}); + +var balance_claim = new Serializer('balance_claim', { + fee: asset, + deposit_to_account: protocol_id_type('account'), + balance_to_claim: protocol_id_type('balance'), + balance_owner_key: public_key, + total_claimed: asset +}); + +var override_transfer = new Serializer('override_transfer', { + fee: asset, + issuer: protocol_id_type('account'), + from: protocol_id_type('account'), + to: protocol_id_type('account'), + amount: asset, + memo: optional(memo_data), + extensions: set(future_extensions) +}); + +var stealth_confirmation = new Serializer('stealth_confirmation', { + one_time_key: public_key, + to: optional(public_key), + encrypted_memo: bytes() +}); + +var blind_output = new Serializer('blind_output', { + commitment: bytes(33), + range_proof: bytes(), + owner: authority, + stealth_memo: optional(stealth_confirmation) +}); + +var transfer_to_blind = new Serializer('transfer_to_blind', { + fee: asset, + amount: asset, + from: protocol_id_type('account'), + blinding_factor: bytes(32), + outputs: array(blind_output) +}); + +var blind_input = new Serializer('blind_input', { + commitment: bytes(33), + owner: authority +}); + +var blind_transfer = new Serializer('blind_transfer', { + fee: asset, + inputs: array(blind_input), + outputs: array(blind_output) +}); + +var transfer_from_blind = new Serializer('transfer_from_blind', { + fee: asset, + amount: asset, + to: protocol_id_type('account'), + blinding_factor: bytes(32), + inputs: array(blind_input) +}); + +var asset_settle_cancel = new Serializer('asset_settle_cancel', { + fee: asset, + settlement: protocol_id_type('force_settlement'), + account: protocol_id_type('account'), + amount: asset, + extensions: set(future_extensions) +}); + +var asset_claim_fees = new Serializer('asset_claim_fees', { + fee: asset, + issuer: protocol_id_type('account'), + amount_to_claim: asset, + extensions: set(future_extensions) +}); + +var fba_distribute = new Serializer('fba_distribute', { + fee: asset, + account_id: protocol_id_type('account'), + fba_id: protocol_id_type('fba_accumulator'), + amount: int64 +}); + +var rock_paper_scissors_game_options = new Serializer('rock_paper_scissors_game_options', { + insurance_enabled: bool, + time_per_commit_move: uint32, + time_per_reveal_move: uint32, + number_of_gestures: uint8 +}); + +var game_specific_details = static_variant([rock_paper_scissors_game_options]); + +var tournament_options = new Serializer('tournament_options', { + type_of_game: uint16, + registration_deadline: time_point_sec, + number_of_players: uint32, + buy_in: asset, + whitelist: set(protocol_id_type('account')), + start_time: optional(time_point_sec), + start_delay: optional(uint32), + round_delay: uint32, + number_of_wins: uint32, + meta: variant_object, + game_options: game_specific_details +}); + +var tournament_create = new Serializer('tournament_create', { + fee: asset, + creator: protocol_id_type('account'), + options: tournament_options, + extensions: set(future_extensions) +}); + +var tournament_join = new Serializer('tournament_join', { + fee: asset, + payer_account_id: protocol_id_type('account'), + player_account_id: protocol_id_type('account'), + tournament_id: protocol_id_type('tournament'), + buy_in: asset, + extensions: set(future_extensions) +}); + +var rock_paper_scissors_gesture = enumeration(['rock', 'paper', 'scissors', 'spock', 'lizard']); + +var rock_paper_scissors_throw_commit = new Serializer('rock_paper_scissors_throw_commit', { + nonce1: uint64, + throw_hash: sha256 +}); + +var rock_paper_scissors_throw_reveal = new Serializer('rock_paper_scissors_throw_reveal', { + nonce2: uint64, + gesture: rock_paper_scissors_gesture +}); + +var game_specific_moves = static_variant([rock_paper_scissors_throw_commit, rock_paper_scissors_throw_reveal]); + +var game_move = new Serializer('game_move', { + fee: asset, + game_id: protocol_id_type('game'), + player_account_id: protocol_id_type('account'), + move: game_specific_moves, + extensions: set(future_extensions) +}); + +var dividend_asset_options = new Serializer('dividend_asset_options', { + next_payout_time: optional(time_point_sec), + payout_interval: optional(uint32), + minimum_fee_percentage: uint64, + minimum_distribution_interval: optional(uint32), + extensions: set(future_extensions) +}); + +var asset_update_dividend = new Serializer('asset_update_dividend', { + fee: asset, + issuer: protocol_id_type('account'), + asset_to_update: protocol_id_type('asset'), + new_options: dividend_asset_options, + extensions: set(future_extensions) +}); + +var asset_dividend_distribution = new Serializer('asset_dividend_distribution', { + fee: asset, + dividend_asset_id: protocol_id_type('asset'), + account_id: protocol_id_type('account'), + amounts: set(asset), + extensions: set(future_extensions) +}); + +var sport_create = new Serializer('sport_create', { + fee: asset, + name: map(string, string), + extensions: set(future_extensions) +}); + +var sport_update = new Serializer('sport_update', { + fee: asset, + sport_id: protocol_id_type('sport'), + new_name: optional(map(string, string)), + extensions: set(future_extensions) +}); + +var event_group_create = new Serializer('event_group_create', { + fee: asset, + name: map(string, string), + sport_id: object_id_type, + extensions: set(future_extensions) +}); + +var event_group_update = new Serializer('event_group_update', { + fee: asset, + new_sport_id: optional(protocol_id_type('sport')), + new_name: optional(map(string, string)), + event_group_id: protocol_id_type('event_group'), + extensions: set(future_extensions) +}); + +var event_create = new Serializer('event_create', { + fee: asset, + name: map(string, string), + season: map(string, string), + start_time: optional(time_point_sec), + event_group_id: object_id_type, + extensions: set(future_extensions) +}); + +var event_update = new Serializer('event_update', { + fee: asset, + event_id: protocol_id_type('event'), + new_event_group_id: optional(protocol_id_type('event_group')), + new_name: optional(map(string, string)), + new_season: optional(map(string, string)), + new_start_time: optional(time_point_sec), + is_live_market: optional(bool), + extensions: set(future_extensions) +}); + +var betting_market_rules_create = new Serializer('betting_market_rules_create', { + fee: asset, + name: map(string, string), + description: map(string, string), + extensions: set(future_extensions) +}); + +var betting_market_rules_update = new Serializer('betting_market_rules_update', { + fee: asset, + new_name: optional(map(string, string)), + new_description: optional(map(string, string)), + extensions: set(future_extensions), + betting_market_rules_id: protocol_id_type('betting_market_rules') +}); + +var betting_market_group_create = new Serializer('betting_market_group_create', { + fee: asset, + description: map(string, string), + event_id: object_id_type, + rules_id: object_id_type, + asset_id: protocol_id_type('asset'), + extensions: set(future_extensions) +}); + +var betting_market_create = new Serializer('betting_market_create', { + fee: asset, + group_id: object_id_type, + description: map(string, string), + payout_condition: map(string, string), + extensions: set(future_extensions) +}); + +var bet_type = enumeration(['back', 'lay']); + +var bet_place = new Serializer('bet_place', { + fee: asset, + bettor_id: protocol_id_type('account'), + betting_market_id: protocol_id_type('betting_market'), + amount_to_bet: asset, + backer_multiplier: uint32, + back_or_lay: bet_type, + extensions: set(future_extensions) +}); + +var betting_market_resolution_type = enumeration(['win', 'not_win', 'cancel', 'BETTING_MARKET_RESOLUTION_COUNT']); + +var betting_market_group_resolve = new Serializer('betting_market_group_resolve', { + fee: asset, + betting_market_group_id: protocol_id_type('betting_market_group'), + resolutions: map(protocol_id_type('betting_market'), betting_market_resolution_type), + extensions: set(future_extensions) +}); + +var betting_market_group_resolved = new Serializer('betting_market_group_resolved', { + bettor_id: protocol_id_type('account'), + betting_market_group_id: protocol_id_type('betting_market_group'), + resolutions: map(protocol_id_type('betting_market'), betting_market_resolution_type), + winnings: int64, + fees_paid: int64, + fee: asset +}); + +var betting_market_group_cancel_unmatched_bets = new Serializer('betting_market_group_cancel_unmatched_bets', { + fee: asset, + betting_market_group_id: protocol_id_type('betting_market_group'), + extensions: set(future_extensions) +}); + +var bet_matched = new Serializer('bet_matched', { + bettor_id: protocol_id_type('account'), + bet_id: protocol_id_type('bet'), + betting_market_id: protocol_id_type('betting_market'), + amount_bet: asset, + fees_paid: int64, + backer_multiplier: uint32, + guaranteed_winnings_returned: int64 +}); + +var bet_cancel = new Serializer('bet_cancel', { + fee: asset, + bettor_id: protocol_id_type('account'), + bet_to_cancel: protocol_id_type('bet'), + extensions: set(future_extensions) +}); + +var bet_canceled = new Serializer('bet_canceled', { + bettor_id: protocol_id_type('account'), + bet_id: protocol_id_type('bet'), + stake_returned: asset, + unused_fees_returned: asset +}); + +var payout_type = enumeration(['prize_award', 'buyin_refund', 'rake_fee']); + +var tournament_payout = new Serializer('tournament_payout', { + fee: asset, + payout_account_id: protocol_id_type('account'), + tournament_id: protocol_id_type('tournament'), + payout_amount: asset, + type: payout_type, + extensions: set(future_extensions) +}); + +var tournament_leave = new Serializer('tournament_leave', { + fee: asset, + canceling_account_id: protocol_id_type('account'), + player_account_id: protocol_id_type('account'), + tournament_id: protocol_id_type('tournament'), + extensions: set(future_extensions) +}); + +var betting_market_group_update = new Serializer('betting_market_group_update', { + fee: asset, + betting_market_group_id: protocol_id_type('betting_market_group'), + new_description: optional(map(string, string)), + new_rules_id: optional(protocol_id_type('betting_market_rules')), + freeze: optional(bool), + delay_bets: optional(bool), + extensions: set(future_extensions) +}); + +var betting_market_update = new Serializer('betting_market_update', { + fee: asset, + betting_market_id: protocol_id_type('betting_market'), + new_group_id: optional(protocol_id_type('betting_market_group')), + new_description: optional(map(string, string)), + new_payout_condition: optional(map(string, string)), + extensions: set(future_extensions) +}); + +var bet_adjusted = new Serializer('bet_adjusted', { + bettor_id: protocol_id_type('account'), + bet_id: protocol_id_type('bet'), + stake_returned: asset +}); + +operation.st_operations = [transfer, limit_order_create, limit_order_cancel, call_order_update, fill_order, account_create, account_update, account_whitelist, account_upgrade, account_transfer, asset_create, asset_update, asset_update_bitasset, asset_update_feed_producers, asset_issue, asset_reserve, asset_fund_fee_pool, asset_settle, asset_global_settle, asset_publish_feed, witness_create, witness_update, proposal_create, proposal_update, proposal_delete, withdraw_permission_create, withdraw_permission_update, withdraw_permission_claim, withdraw_permission_delete, committee_member_create, committee_member_update, committee_member_update_global_parameters, vesting_balance_create, vesting_balance_withdraw, worker_create, custom, assert, balance_claim, override_transfer, transfer_to_blind, blind_transfer, transfer_from_blind, asset_settle_cancel, asset_claim_fees, fba_distribute, tournament_create, tournament_join, game_move, asset_update_dividend, asset_dividend_distribution, tournament_payout, tournament_leave, sport_create, sport_update, event_group_create, event_group_update, event_create, event_update, betting_market_rules_create, betting_market_rules_update, betting_market_group_create, betting_market_create, bet_place, betting_market_group_resolve, betting_market_group_resolved, bet_adjusted, betting_market_group_cancel_unmatched_bets, bet_matched, bet_cancel, bet_canceled, betting_market_group_update, betting_market_update]; + +var transaction = new Serializer('transaction', { + ref_block_num: uint16, + ref_block_prefix: uint32, + expiration: time_point_sec, + operations: array(operation), + extensions: set(future_extensions) +}); + +var signed_transaction = new Serializer('signed_transaction', { + ref_block_num: uint16, + ref_block_prefix: uint32, + expiration: time_point_sec, + operations: array(operation), + extensions: set(future_extensions), + signatures: array(bytes(65)) +}); +// # ------------------------------- +// # Generated code end +// # ------------------------------- + +// Betting Objects + +var sport = new Serializer('sport', { + id: protocol_id_type('sport'), + name: map(string, string) +}); + +var event_group = new Serializer('event_group', { + id: protocol_id_type('event_group'), + name: map(string, string), + sport_id: protocol_id_type('sport') +}); + +var event_status = enumeration(['upcoming', 'in_progress', 'frozen', 'finished', 'completed', 'canceled', 'STATUS_COUNT']); + +var betting_market_status = enumeration(['unresolved', 'frozen', 'graded', 'canceled', 'settled']); + +var betting_market_group_status = enumeration(['upcoming', 'in_play', 'closed', 'graded', 're-grading', 'settled', 'frozen', 'canceled']); + +var event = new Serializer('event', { + id: protocol_id_type('event'), + name: map(string, string), + season: map(string, string), + start_time: optional(time_point_sec), + event_group_id: protocol_id_type('event_group'), + is_live_market: bool, + status: event_status, + scores: array(string) +}); + +var betting_market_rules = new Serializer('betting_market_rules', { + id: protocol_id_type('betting_market_rules'), + name: map(string, string), + description: map(string, string) +}); + +var betting_market_group = new Serializer('betting_market_group', { + id: protocol_id_type('betting_market_group'), + description: map(string, string), + event_id: protocol_id_type('event'), + rules_id: protocol_id_type('betting_market_rules'), + asset_id: protocol_id_type('asset'), + total_matched_bets_amount: uint64, + frozen: bool, + delay_bets: bool, + status: betting_market_group_status +}); + +var betting_market = new Serializer('betting_market', { + id: protocol_id_type('betting_market'), + group_id: protocol_id_type('betting_market_group'), + description: map(string, string), + payout_condition: map(string, string), + status: betting_market_status +}); + +var bet = new Serializer('bet', { + id: protocol_id_type('bet'), + bettor_id: protocol_id_type('account'), + betting_market_id: protocol_id_type('betting_market'), + amount_to_bet: asset, + backer_multiplier: uint32, + back_or_lay: bet_type +}); + +var betting_market_position = new Serializer('betting_market_position', { + id: implementation_id_type('betting_market_position'), + bettor_id: protocol_id_type('account'), + betting_market_id: protocol_id_type('betting_market'), + pay_if_payout_condition: int64, + pay_if_not_payout_condition: int64, + pay_if_canceled: int64, + pay_if_not_canceled: int64, + fees_collected: int64 +}); + +var global_betting_statistics = new Serializer('global_betting_statistics', { + id: implementation_id_type('global_betting_statistics'), + number_of_active_events: uint32, + total_amount_staked: map(protocol_id_type('asset'), int64) +}); + +// eof Betting Objects + +// Custom Types + +var stealth_memo_data = new Serializer('stealth_memo_data', { + from: optional(public_key), + amount: asset, + blinding_factor: bytes(32), + commitment: bytes(33), + check: uint32 +}); +// var stealth_confirmation = new Serializer( +// "stealth_confirmation", { +// one_time_key: public_key, +// to: optional( public_key ), +// encrypted_memo: stealth_memo_data +// }) + +exports.operation = operation; +exports.transfer_operation_fee_parameters = transfer_operation_fee_parameters; +exports.limit_order_create_operation_fee_parameters = limit_order_create_operation_fee_parameters; +exports.limit_order_cancel_operation_fee_parameters = limit_order_cancel_operation_fee_parameters; +exports.call_order_update_operation_fee_parameters = call_order_update_operation_fee_parameters; +exports.fill_order_operation_fee_parameters = fill_order_operation_fee_parameters; +exports.account_create_operation_fee_parameters = account_create_operation_fee_parameters; +exports.account_update_operation_fee_parameters = account_update_operation_fee_parameters; +exports.account_whitelist_operation_fee_parameters = account_whitelist_operation_fee_parameters; +exports.account_upgrade_operation_fee_parameters = account_upgrade_operation_fee_parameters; +exports.account_transfer_operation_fee_parameters = account_transfer_operation_fee_parameters; +exports.asset_create_operation_fee_parameters = asset_create_operation_fee_parameters; +exports.asset_update_operation_fee_parameters = asset_update_operation_fee_parameters; +exports.asset_update_bitasset_operation_fee_parameters = asset_update_bitasset_operation_fee_parameters; +exports.asset_update_feed_producers_operation_fee_parameters = asset_update_feed_producers_operation_fee_parameters; +exports.asset_issue_operation_fee_parameters = asset_issue_operation_fee_parameters; +exports.asset_reserve_operation_fee_parameters = asset_reserve_operation_fee_parameters; +exports.asset_fund_fee_pool_operation_fee_parameters = asset_fund_fee_pool_operation_fee_parameters; +exports.asset_settle_operation_fee_parameters = asset_settle_operation_fee_parameters; +exports.asset_global_settle_operation_fee_parameters = asset_global_settle_operation_fee_parameters; +exports.asset_publish_feed_operation_fee_parameters = asset_publish_feed_operation_fee_parameters; +exports.witness_create_operation_fee_parameters = witness_create_operation_fee_parameters; +exports.witness_update_operation_fee_parameters = witness_update_operation_fee_parameters; +exports.proposal_create_operation_fee_parameters = proposal_create_operation_fee_parameters; +exports.proposal_update_operation_fee_parameters = proposal_update_operation_fee_parameters; +exports.proposal_delete_operation_fee_parameters = proposal_delete_operation_fee_parameters; +exports.withdraw_permission_create_operation_fee_parameters = withdraw_permission_create_operation_fee_parameters; +exports.withdraw_permission_update_operation_fee_parameters = withdraw_permission_update_operation_fee_parameters; +exports.withdraw_permission_claim_operation_fee_parameters = withdraw_permission_claim_operation_fee_parameters; +exports.withdraw_permission_delete_operation_fee_parameters = withdraw_permission_delete_operation_fee_parameters; +exports.committee_member_create_operation_fee_parameters = committee_member_create_operation_fee_parameters; +exports.committee_member_update_operation_fee_parameters = committee_member_update_operation_fee_parameters; +exports.committee_member_update_global_parameters_operation_fee_parameters = committee_member_update_global_parameters_operation_fee_parameters; +exports.vesting_balance_create_operation_fee_parameters = vesting_balance_create_operation_fee_parameters; +exports.vesting_balance_withdraw_operation_fee_parameters = vesting_balance_withdraw_operation_fee_parameters; +exports.worker_create_operation_fee_parameters = worker_create_operation_fee_parameters; +exports.custom_operation_fee_parameters = custom_operation_fee_parameters; +exports.assert_operation_fee_parameters = assert_operation_fee_parameters; +exports.balance_claim_operation_fee_parameters = balance_claim_operation_fee_parameters; +exports.override_transfer_operation_fee_parameters = override_transfer_operation_fee_parameters; +exports.transfer_to_blind_operation_fee_parameters = transfer_to_blind_operation_fee_parameters; +exports.blind_transfer_operation_fee_parameters = blind_transfer_operation_fee_parameters; +exports.transfer_from_blind_operation_fee_parameters = transfer_from_blind_operation_fee_parameters; +exports.asset_settle_cancel_operation_fee_parameters = asset_settle_cancel_operation_fee_parameters; +exports.asset_claim_fees_operation_fee_parameters = asset_claim_fees_operation_fee_parameters; +exports.fba_distribute_operation_fee_parameters = fba_distribute_operation_fee_parameters; +exports.asset_update_dividend_operation_fee_parameters = asset_update_dividend_operation_fee_parameters; +exports.asset_dividend_distribution_operation_fee_parameters = asset_dividend_distribution_operation_fee_parameters; +exports.sport_create_operation_fee_parameters = sport_create_operation_fee_parameters; +exports.sport_update_operation_fee_parameters = sport_update_operation_fee_parameters; +exports.event_group_create_operation_fee_parameters = event_group_create_operation_fee_parameters; +exports.event_group_update_operation_fee_parameters = event_group_update_operation_fee_parameters; +exports.event_create_operation_fee_parameters = event_create_operation_fee_parameters; +exports.event_update_operation_fee_parameters = event_update_operation_fee_parameters; +exports.betting_market_rules_create_operation_fee_parameters = betting_market_rules_create_operation_fee_parameters; +exports.betting_market_rules_update_operation_fee_parameters = betting_market_rules_update_operation_fee_parameters; +exports.betting_market_group_create_operation_fee_parameters = betting_market_group_create_operation_fee_parameters; +exports.betting_market_create_operation_fee_parameters = betting_market_create_operation_fee_parameters; +exports.bet_place_operation_fee_parameters = bet_place_operation_fee_parameters; +exports.betting_market_group_resolve_operation_fee_parameters = betting_market_group_resolve_operation_fee_parameters; +exports.betting_market_group_resolved_operation_fee_parameters = betting_market_group_resolved_operation_fee_parameters; +exports.betting_market_group_cancel_unmatched_bets_operation_fee_parameters = betting_market_group_cancel_unmatched_bets_operation_fee_parameters; +exports.bet_matched_operation_fee_parameters = bet_matched_operation_fee_parameters; +exports.bet_cancel_operation_fee_parameters = bet_cancel_operation_fee_parameters; +exports.bet_canceled_operation_fee_parameters = bet_canceled_operation_fee_parameters; +exports.tournament_create_operation_fee_parameters = tournament_create_operation_fee_parameters; +exports.tournament_join_operation_fee_parameters = tournament_join_operation_fee_parameters; +exports.game_move_operation_fee_parameters = game_move_operation_fee_parameters; +exports.tournament_payout_operation_fee_parameters = tournament_payout_operation_fee_parameters; +exports.tournament_leave_operation_fee_parameters = tournament_leave_operation_fee_parameters; +exports.betting_market_group_update_operation_fee_parameters = betting_market_group_update_operation_fee_parameters; +exports.betting_market_update_operation_fee_parameters = betting_market_update_operation_fee_parameters; +exports.bet_adjusted_operation_fee_parameters = bet_adjusted_operation_fee_parameters; +exports.fee_schedule = fee_schedule; +exports.void_result = void_result; +exports.asset = asset; +exports.processed_transaction = processed_transaction; +exports.signed_block = signed_block; +exports.block_header = block_header; +exports.signed_block_header = signed_block_header; +exports.memo_data = memo_data; +exports.transfer = transfer; +exports.limit_order_create = limit_order_create; +exports.limit_order_cancel = limit_order_cancel; +exports.call_order_update = call_order_update; +exports.fill_order = fill_order; +exports.authority = authority; +exports.account_options = account_options; +exports.account_create = account_create; +exports.account_update = account_update; +exports.account_whitelist = account_whitelist; +exports.account_upgrade = account_upgrade; +exports.account_transfer = account_transfer; +exports.price = price; +exports.asset_options = asset_options; +exports.bitasset_options = bitasset_options; +exports.asset_create = asset_create; +exports.asset_update = asset_update; +exports.asset_update_bitasset = asset_update_bitasset; +exports.asset_update_feed_producers = asset_update_feed_producers; +exports.asset_issue = asset_issue; +exports.asset_reserve = asset_reserve; +exports.asset_fund_fee_pool = asset_fund_fee_pool; +exports.asset_settle = asset_settle; +exports.asset_global_settle = asset_global_settle; +exports.price_feed = price_feed; +exports.asset_publish_feed = asset_publish_feed; +exports.witness_create = witness_create; +exports.witness_update = witness_update; +exports.op_wrapper = op_wrapper; +exports.proposal_create = proposal_create; +exports.proposal_update = proposal_update; +exports.proposal_delete = proposal_delete; +exports.withdraw_permission_create = withdraw_permission_create; +exports.withdraw_permission_update = withdraw_permission_update; +exports.withdraw_permission_claim = withdraw_permission_claim; +exports.withdraw_permission_delete = withdraw_permission_delete; +exports.committee_member_create = committee_member_create; +exports.committee_member_update = committee_member_update; +exports.chain_parameters = chain_parameters; +exports.committee_member_update_global_parameters = committee_member_update_global_parameters; +exports.linear_vesting_policy_initializer = linear_vesting_policy_initializer; +exports.cdd_vesting_policy_initializer = cdd_vesting_policy_initializer; +exports.vesting_balance_create = vesting_balance_create; +exports.vesting_balance_withdraw = vesting_balance_withdraw; +exports.refund_worker_initializer = refund_worker_initializer; +exports.vesting_balance_worker_initializer = vesting_balance_worker_initializer; +exports.burn_worker_initializer = burn_worker_initializer; +exports.worker_create = worker_create; +exports.custom = custom; +exports.account_name_eq_lit_predicate = account_name_eq_lit_predicate; +exports.asset_symbol_eq_lit_predicate = asset_symbol_eq_lit_predicate; +exports.block_id_predicate = block_id_predicate; +exports.assert = assert; +exports.balance_claim = balance_claim; +exports.override_transfer = override_transfer; +exports.stealth_confirmation = stealth_confirmation; +exports.blind_output = blind_output; +exports.transfer_to_blind = transfer_to_blind; +exports.blind_input = blind_input; +exports.blind_transfer = blind_transfer; +exports.transfer_from_blind = transfer_from_blind; +exports.asset_settle_cancel = asset_settle_cancel; +exports.asset_claim_fees = asset_claim_fees; +exports.fba_distribute = fba_distribute; +exports.rock_paper_scissors_game_options = rock_paper_scissors_game_options; +exports.tournament_options = tournament_options; +exports.tournament_create = tournament_create; +exports.tournament_join = tournament_join; +exports.rock_paper_scissors_gesture = rock_paper_scissors_gesture; +exports.rock_paper_scissors_throw_commit = rock_paper_scissors_throw_commit; +exports.rock_paper_scissors_throw_reveal = rock_paper_scissors_throw_reveal; +exports.game_move = game_move; +exports.dividend_asset_options = dividend_asset_options; +exports.asset_update_dividend = asset_update_dividend; +exports.asset_dividend_distribution = asset_dividend_distribution; +exports.sport_create = sport_create; +exports.sport_update = sport_update; +exports.event_group_create = event_group_create; +exports.event_group_update = event_group_update; +exports.event_create = event_create; +exports.event_update = event_update; +exports.betting_market_rules_create = betting_market_rules_create; +exports.betting_market_rules_update = betting_market_rules_update; +exports.betting_market_group_create = betting_market_group_create; +exports.betting_market_create = betting_market_create; +exports.bet_type = bet_type; +exports.bet_place = bet_place; +exports.betting_market_resolution_type = betting_market_resolution_type; +exports.betting_market_group_resolve = betting_market_group_resolve; +exports.betting_market_group_resolved = betting_market_group_resolved; +exports.betting_market_group_cancel_unmatched_bets = betting_market_group_cancel_unmatched_bets; +exports.bet_matched = bet_matched; +exports.bet_cancel = bet_cancel; +exports.bet_canceled = bet_canceled; +exports.payout_type = payout_type; +exports.tournament_payout = tournament_payout; +exports.tournament_leave = tournament_leave; +exports.betting_market_group_update = betting_market_group_update; +exports.betting_market_update = betting_market_update; +exports.bet_adjusted = bet_adjusted; +exports.transaction = transaction; +exports.signed_transaction = signed_transaction; +exports.sport = sport; +exports.event_group = event_group; +exports.event = event; +exports.betting_market_rules = betting_market_rules; +exports.betting_market_group = betting_market_group; +exports.betting_market = betting_market; +exports.bet = bet; +exports.betting_market_position = betting_market_position; +exports.global_betting_statistics = global_betting_statistics; +exports.stealth_memo_data = stealth_memo_data; +},{"24":24,"26":26}],24:[function(require,module,exports){ +(function (process,Buffer){ +'use strict'; + +exports.__esModule = true; + +var _bytebuffer = require(38); + +var _bytebuffer2 = _interopRequireDefault(_bytebuffer); + +var _error_with_cause = require(22); + +var _error_with_cause2 = _interopRequireDefault(_error_with_cause); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; + +var Serializer = function () { + function Serializer(operation_name, types) { + _classCallCheck(this, Serializer); + + this.operation_name = operation_name; + this.types = types; + + if (this.types) { + this.keys = Object.keys(this.types); + } + + Serializer.printDebug = true; + } + + Serializer.prototype.fromByteBuffer = function fromByteBuffer(b) { + var object = {}; + var field = null; + + try { + var iterable = this.keys; + + for (var i = 0; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + + try { + if (HEX_DUMP) { + if (type.operation_name) { + console.error(type.operation_name); + } else { + var o1 = b.offset; + type.fromByteBuffer(b); + var o2 = b.offset; + b.offset = o1; + // b.reset() + var _b = b.copy(o1, o2); + console.error(this.operation_name + '.' + field + '\t', _b.toHex()); + } + } + + object[field] = type.fromByteBuffer(b); + } catch (e) { + if (Serializer.printDebug) { + console.error('Error reading ' + this.operation_name + '.' + field + ' in data:'); + b.printDebug(); + } + + throw e; + } + } + } catch (error) { + _error_with_cause2.default.throw(this.operation_name + '.' + field, error); + } + + return object; + }; + + Serializer.prototype.appendByteBuffer = function appendByteBuffer(b, object) { + var field = null; + + try { + var iterable = this.keys; + + for (var i = 0; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + type.appendByteBuffer(b, object[field]); + } + } catch (error) { + try { + _error_with_cause2.default.throw(this.operation_name + '.' + field + ' = ' + JSON.stringify(object[field]), error); + } catch (e) { + // circular ref + _error_with_cause2.default.throw(this.operation_name + '.' + field + ' = ' + object[field], error); + } + } + }; + + Serializer.prototype.fromObject = function fromObject(serialized_object) { + var result = {}; + var field = null; + + try { + var iterable = this.keys; + + for (var i = 0; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + var value = serialized_object[field]; + // DEBUG value = value.resolve if value.resolve + // DEBUG console.log('... value',field,value) + var object = type.fromObject(value); + result[field] = object; + } + } catch (error) { + _error_with_cause2.default.throw(this.operation_name + '.' + field, error); + } + + return result; + }; + + /** + @arg {boolean} [debug.use_default = false] - more template friendly + @arg {boolean} [debug.annotate = false] - add user-friendly information + */ + + + Serializer.prototype.toObject = function toObject() { + var serialized_object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { use_default: false, annotate: false }; + + var result = {}; + var field = null; + + try { + if (!this.types) { + return result; + } + + var iterable = this.keys; + + for (var i = 0; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + var object = type.toObject(typeof serialized_object !== 'undefined' && serialized_object !== null ? serialized_object[field] : undefined, debug); + result[field] = object; + + if (HEX_DUMP) { + var b = new _bytebuffer2.default(_bytebuffer2.default.DEFAULT_CAPACITY, _bytebuffer2.default.LITTLE_ENDIAN); + type.appendByteBuffer(b, typeof serialized_object !== 'undefined' && serialized_object !== null ? serialized_object[field] : undefined); + b = b.copy(0, b.offset); + console.error(this.operation_name + '.' + field, b.toHex()); + } + } + } catch (error) { + _error_with_cause2.default.throw(this.operation_name + '.' + field, error); + } + + return result; + }; + + /** Sort by the first element in a operation */ + + + Serializer.prototype.compare = function compare(a, b) { + var first_key = this.keys[0]; + var first_type = this.types[first_key]; + + var valA = a[first_key]; + var valB = b[first_key]; + + if (first_type.compare) { + return first_type.compare(valA, valB); + } + + if (typeof valA === 'number' && typeof valB === 'number') { + return valA - valB; + } + + var encoding = void 0; + + if (Buffer.isBuffer(valA) && Buffer.isBuffer(valB)) { + // A binary string compare does not work. If localeCompare is well supported that could + // replace HEX. Performanance is very good so comparing HEX works. + encoding = 'hex'; + } + + var strA = valA.toString(encoding); + var strB = valB.toString(encoding); + + var result = 0; + + if (strA > strB) { + result = 1; + } + + if (strA < strB) { + result = -1; + } + + return result; + }; + + // + + Serializer.prototype.fromHex = function fromHex(hex) { + var b = _bytebuffer2.default.fromHex(hex, _bytebuffer2.default.LITTLE_ENDIAN); + return this.fromByteBuffer(b); + }; + + Serializer.prototype.fromBuffer = function fromBuffer(buffer) { + var b = _bytebuffer2.default.fromBinary(buffer.toString('binary'), _bytebuffer2.default.LITTLE_ENDIAN); + return this.fromByteBuffer(b); + }; + + Serializer.prototype.toHex = function toHex(object) { + // return this.toBuffer(object).toString("hex") + var b = this.toByteBuffer(object); + return b.toHex(); + }; + + Serializer.prototype.toByteBuffer = function toByteBuffer(object) { + var b = new _bytebuffer2.default(_bytebuffer2.default.DEFAULT_CAPACITY, _bytebuffer2.default.LITTLE_ENDIAN); + this.appendByteBuffer(b, object); + return b.copy(0, b.offset); + }; + + Serializer.prototype.toBuffer = function toBuffer(object) { + return Buffer.from(this.toByteBuffer(object).toBinary(), 'binary'); + }; + + return Serializer; +}(); + +exports.default = Serializer; +module.exports = exports['default']; +}).call(this,require(77),require(35).Buffer) + +},{"22":22,"35":35,"38":38,"77":77}],25:[function(require,module,exports){ +"use strict"; + +exports.__esModule = true; +exports.default = template; +/** Console print any transaction object with zero default values. */ +function template(op) { + var object = op.toObject(undefined, { use_default: true, annotate: true }); + + // visual (with descriptions) + console.error(JSON.stringify(object, null, 4)); + + // usable in a copy-paste + + object = op.toObject(undefined, { use_default: true, annotate: false }); + + // copy-paste one-lineer + console.error(JSON.stringify(object)); +} +module.exports = exports["default"]; +},{}],26:[function(require,module,exports){ +(function (process,Buffer){ +'use strict'; + +exports.__esModule = true; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // Low-level types that make up operations + +var _peerplaysjsWs = require(70); + +var _SerializerValidation = require(21); + +var _SerializerValidation2 = _interopRequireDefault(_SerializerValidation); + +var _FastParser = require(20); + +var _FastParser2 = _interopRequireDefault(_FastParser); + +var _ChainTypes = require(3); + +var _ChainTypes2 = _interopRequireDefault(_ChainTypes); + +var _ObjectId = require(4); + +var _ObjectId2 = _interopRequireDefault(_ObjectId); + +var _ecc = require(7); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var MIN_SIGNED_32 = -1 * Math.pow(2, 31); +var MAX_SIGNED_32 = Math.pow(2, 31) - 1; + +var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; + +var strCmp = function strCmp(a, b) { + var result = 0; + + if (a > b) { + result = 1; + } + + if (a < b) { + result = -1; + } + + return result; +}; + +var firstEl = function firstEl(el) { + return Array.isArray(el) ? el[0] : el; +}; + +var sortOperation = function sortOperation(array, st_operation) { + if (!st_operation.nosort) { + // If the operation has its own compare function. + if (st_operation.compare) { + return array.sort(function (a, b) { + return st_operation.compare(firstEl(a), firstEl(b)); + }); + } + + return array.sort(function (a, b) { + var aFirst = firstEl(a); + var bFirst = firstEl(b); + + // If both of the first elements are numbers. + if (typeof aFirst === 'number' && typeof bFirst === 'number') { + return aFirst - bFirst; + } + + // If they are both buffers. + if (Buffer.isBuffer(aFirst) && Buffer.isBuffer(bFirst)) { + return strCmp(aFirst.toString('hex'), bFirst.toString('hex')); + } + + // Otherwise + return strCmp(aFirst.toString(), bFirst.toString()); + }); + } + + return array; +}; + +var Types = {}; + +Types.uint8 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint8(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.require_range(0, 0xff, object, 'uint8 ' + object); + b.writeUint8(object); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.require_range(0, 0xff, object, 'uint8 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return 0; + } + + _SerializerValidation2.default.require_range(0, 0xff, object, 'uint8 ' + object); + return parseInt(object, 10); + } +}; + +Types.uint16 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint16(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.require_range(0, 0xffff, object, 'uint16 ' + object); + b.writeUint16(object); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.require_range(0, 0xffff, object, 'uint16 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return 0; + } + + _SerializerValidation2.default.require_range(0, 0xffff, object, 'uint16 ' + object); + return parseInt(object, 10); + } +}; + +Types.uint32 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.require_range(0, 0xffffffff, object, 'uint32 ' + object); + b.writeUint32(object); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.require_range(0, 0xffffffff, object, 'uint32 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return 0; + } + + _SerializerValidation2.default.require_range(0, 0xffffffff, object, 'uint32 ' + object); + return parseInt(object, 10); + } +}; + +Types.varint32 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readVarint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); + b.writeVarint32(object); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return 0; + } + + _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); + return parseInt(object, 10); + } +}; + +Types.int64 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readInt64(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.required(object); + b.writeInt64(_SerializerValidation2.default.to_long(object)); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + return _SerializerValidation2.default.to_long(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return '0'; + } + + _SerializerValidation2.default.required(object); + return _SerializerValidation2.default.to_long(object).toString(); + } +}; + +Types.uint64 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint64(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + b.writeUint64(_SerializerValidation2.default.to_ulong(_SerializerValidation2.default.unsigned(object))); + }, + fromObject: function fromObject(object) { + return _SerializerValidation2.default.to_ulong(_SerializerValidation2.default.unsigned(object)); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return '0'; + } + + return _SerializerValidation2.default.to_ulong(object).toString(); + } +}; + +Types.string = { + fromByteBuffer: function fromByteBuffer(b) { + var b_copy = void 0; + var len = b.readVarint32(); + b_copy = b.copy(b.offset, b.offset + len); + b.skip(len); + return Buffer.from(b_copy.toBinary(), 'binary'); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.required(object); + b.writeVarint32(object.length); + b.append(object.toString('binary'), 'binary'); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + return Buffer.from(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return ''; + } + + return object.toString(); + } +}; + +Types.bytes = function (size) { + var bytes = { + fromByteBuffer: function fromByteBuffer(b) { + if (size === undefined) { + var _b_copy = void 0; + var len = b.readVarint32(); + _b_copy = b.copy(b.offset, b.offset + len); + b.skip(len); + return Buffer.from(_b_copy.toBinary(), 'binary'); + } + + var b_copy = b.copy(b.offset, b.offset + size); + b.skip(size); + return Buffer.from(b_copy.toBinary(), 'binary'); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.required(object); + + if (typeof object === 'string') { + object = Buffer.from(object, 'hex'); + } + + if (size === undefined) { + b.writeVarint32(object.length); + } + + b.append(object.toString('binary'), 'binary'); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + + if (Buffer.isBuffer(object)) { + return object; + } + + return Buffer.from(object, 'hex'); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return new Array(size).join('00'); + } + + _SerializerValidation2.default.required(object); + return object.toString('hex'); + } + }; + + return bytes; +}; + +Types.bool = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint8() === 1; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + // supports boolean or integer + b.writeUint8(JSON.parse(object) ? 1 : 0); + }, + fromObject: function fromObject(object) { + return !!JSON.parse(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return false; + } + + return !!JSON.parse(object); + } +}; + +Types.void = { + fromByteBuffer: function fromByteBuffer() { + throw new Error('(void) undefined type'); + }, + appendByteBuffer: function appendByteBuffer() { + throw new Error('(void) undefined type'); + }, + fromObject: function fromObject() { + throw new Error('(void) undefined type'); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return undefined; + } + + throw new Error('(void) undefined type'); + } +}; + +Types.array = function (st_operation) { + var array = { + fromByteBuffer: function fromByteBuffer(b) { + var size = b.readVarint32(); + + if (HEX_DUMP) { + console.log('varint32 size = ' + size.toString(16)); + } + + var result = []; + + for (var i = 0; size > 0 ? i < size : i > size; size > 0 ? i++ : i++) { + result.push(st_operation.fromByteBuffer(b)); + } + + return sortOperation(result, st_operation); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.required(object); + object = sortOperation(object, st_operation); + b.writeVarint32(object.length); + + for (var i = 0, len = object.length; i < len; i++) { + var o = object[i]; + st_operation.appendByteBuffer(b, o); + } + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + object = sortOperation(object, st_operation); + var result = []; + + for (var i = 0, len = object.length; i < len; i++) { + var o = object[i]; + result.push(st_operation.fromObject(o)); + } + + return result; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [st_operation.toObject(object, debug)]; + } + + _SerializerValidation2.default.required(object); + object = sortOperation(object, st_operation); + + var result = []; + + for (var i = 0, len = object.length; i < len; i++) { + var o = object[i]; + result.push(st_operation.toObject(o, debug)); + } + + return result; + } + }; + + return array; +}; + +Types.time_point_sec = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (typeof object !== 'number') { + object = Types.time_point_sec.fromObject(object); + } + + b.writeUint32(object); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + + if (typeof object === 'number') { + return object; + } + + if (object.getTime) { + return Math.floor(object.getTime() / 1000); + } + + if (typeof object !== 'string') { + throw new Error('Unknown date type: ' + object); + } + + // if(typeof object === "string" && !/Z$/.test(object)) + // object = object + "Z" + + return Math.floor(new Date(object).getTime() / 1000); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return new Date(0).toISOString().split('.')[0]; + } + + _SerializerValidation2.default.required(object); + + if (typeof object === 'string') { + return object; + } + + if (object.getTime) { + return object.toISOString().split('.')[0]; + } + + var int = parseInt(object, 10); + _SerializerValidation2.default.require_range(0, 0xffffffff, int, 'uint32 ' + object); + return new Date(int * 1000).toISOString().split('.')[0]; + } +}; + +Types.set = function (st_operation) { + var set_object = { + validate: function validate(array) { + var dup_map = {}; + + for (var i = 0, len = array.length; i < len; i++) { + var o = array[i]; + var ref = typeof o === 'undefined' ? 'undefined' : _typeof(o); + + if (['string', 'number'].indexOf(ref) >= 0) { + if (dup_map[o] !== undefined) { + throw new Error('duplicate (set)'); + } + + dup_map[o] = true; + } + } + + return sortOperation(array, st_operation); + }, + fromByteBuffer: function fromByteBuffer(b) { + var size = b.readVarint32(); + + if (HEX_DUMP) { + console.log('varint32 size = ' + size.toString(16)); + } + + return this.validate(function () { + var result = []; + + for (var i = 0; size > 0 ? i < size : i > size; size > 0 ? i++ : i++) { + result.push(st_operation.fromByteBuffer(b)); + } + + return result; + }()); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (!object) { + object = []; + } + + b.writeVarint32(object.length); + var iterable = this.validate(object); + + for (var i = 0, len = iterable.length; i < len; i++) { + var o = iterable[i]; + st_operation.appendByteBuffer(b, o); + } + }, + fromObject: function fromObject(object) { + if (!object) { + object = []; + } + + return this.validate(function () { + var result = []; + + for (var i = 0, len = object.length; i < len; i++) { + var o = object[i]; + result.push(st_operation.fromObject(o)); + } + + return result; + }()); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [st_operation.toObject(object, debug)]; + } + + if (!object) { + object = []; + } + + var result = []; + + for (var i = 0, len = object.length; i < len; i++) { + var o = object[i]; + result.push(st_operation.toObject(o, debug)); + } + + return this.validate(result); + } + }; + + return set_object; +}; + +Types.fixed_array = function (count, st_operation) { + var fixed_array = { + fromByteBuffer: function fromByteBuffer(b) { + var results = []; + + for (var i = 0, ref = count; i < ref; i++) { + results.push(st_operation.fromByteBuffer(b)); + } + + return sortOperation(results, st_operation); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (count !== 0) { + _SerializerValidation2.default.required(object); + object = sortOperation(object, st_operation); + } + + for (var i = 0, ref = count; i < ref; i++) { + st_operation.appendByteBuffer(b, object[i]); + } + }, + fromObject: function fromObject(object) { + if (count !== 0) { + _SerializerValidation2.default.required(object); + } + + var results = []; + + for (var i = 0, ref = count; i < ref; i++) { + results.push(st_operation.fromObject(object[i])); + } + + return results; + }, + toObject: function toObject(object, debug) { + if (debug == null) { + debug = {}; + } + + var results = void 0; + + if (debug.use_default && object === undefined) { + results = []; + + for (var i = 0, ref = count; i < ref; i++) { + results.push(st_operation.toObject(undefined, debug)); + } + + return results; + } + + if (count !== 0) { + _SerializerValidation2.default.required(object); + } + + results = []; + + for (var _i = 0, _ref = count; _i < _ref; _i++) { + results.push(st_operation.toObject(object[_i], debug)); + } + + return results; + } + }; + + return fixed_array; +}; + +/* Supports instance numbers (11) or object types (1.2.11). Object type +Validation is enforced when an object type is used. */ +Types.id_type = function (reserved_spaces, object_type) { + _SerializerValidation2.default.required(reserved_spaces, 'reserved_spaces'); + _SerializerValidation2.default.required(object_type, 'object_type'); + + var id_type_object = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readVarint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.required(object); + + if (object.resolve !== undefined) { + object = object.resolve; + } + + // convert 1.2.n into just n + if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { + object = _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object); + } + + b.writeVarint32(_SerializerValidation2.default.to_number(object)); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + + if (object.resolve !== undefined) { + object = object.resolve; + } + + if (_SerializerValidation2.default.is_digits(object)) { + return _SerializerValidation2.default.to_number(object); + } + + return _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var object_type_id = _ChainTypes2.default.object_type[object_type]; + + if (debug.use_default && object === undefined) { + return reserved_spaces + '.' + object_type_id + '.0'; + } + + _SerializerValidation2.default.required(object); + + if (object.resolve !== undefined) { + object = object.resolve; + } + + if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { + object = _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object); + } + + return reserved_spaces + '.' + object_type_id + '.' + object; + } + }; + + return id_type_object; +}; + +Types.protocol_id_type = function (name) { + _SerializerValidation2.default.required(name, 'name'); + return Types.id_type(_ChainTypes2.default.reserved_spaces.protocol_ids, name); +}; + +Types.implementation_id_type = function (name) { + var result = Types.id_type(_ChainTypes2.default.reserved_spaces.implementation_ids, name); + return result; +}; + +Types.object_id_type = { + fromByteBuffer: function fromByteBuffer(b) { + return _ObjectId2.default.fromByteBuffer(b); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.required(object); + + if (object.resolve !== undefined) { + object = object.resolve; + } + + object = _ObjectId2.default.fromString(object); + object.appendByteBuffer(b); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + + if (object.resolve !== undefined) { + object = object.resolve; + } + + return _ObjectId2.default.fromString(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return '0.0.0'; + } + + _SerializerValidation2.default.required(object); + + if (object.resolve !== undefined) { + object = object.resolve; + } + + object = _ObjectId2.default.fromString(object); + return object.toString(); + } +}; + +Types.vote_id = { + TYPE: 0x000000ff, + ID: 0xffffff00, + fromByteBuffer: function fromByteBuffer(b) { + var value = b.readUint32(); + return { + type: value & this.TYPE, // eslint-disable-line + id: value & this.ID // eslint-disable-line + }; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.required(object); + + if (object === 'string') { + object = Types.vote_id.fromObject(object); + } + + var value = object.id << 8 | object.type; // eslint-disable-line + b.writeUint32(value); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object, '(type vote_id)'); + + if ((typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object') { + _SerializerValidation2.default.required(object.type, 'type'); + _SerializerValidation2.default.required(object.id, 'id'); + return object; + } + + _SerializerValidation2.default.require_test(/^[0-9]+:[0-9]+$/, object, 'vote_id format ' + object); + + var _object$split = object.split(':'), + type = _object$split[0], + id = _object$split[1]; + + _SerializerValidation2.default.require_range(0, 0xff, type, 'vote type ' + object); + _SerializerValidation2.default.require_range(0, 0xffffff, id, 'vote id ' + object); + return { type: type, id: id }; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return '0:0'; + } + + _SerializerValidation2.default.required(object); + + if (typeof object === 'string') { + object = Types.vote_id.fromObject(object); + } + + return object.type + ':' + object.id; + }, + compare: function compare(a, b) { + if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) !== 'object') { + a = Types.vote_id.fromObject(a); + } + + if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) !== 'object') { + b = Types.vote_id.fromObject(b); + } + + return parseInt(a.id, 10) - parseInt(b.id, 10); + } +}; + +Types.optional = function (st_operation) { + _SerializerValidation2.default.required(st_operation, 'st_operation'); + return { + fromByteBuffer: function fromByteBuffer(b) { + if (!(b.readUint8() === 1)) { + return undefined; + } + + return st_operation.fromByteBuffer(b); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (object !== null && object !== undefined) { + b.writeUint8(1); + st_operation.appendByteBuffer(b, object); + } else { + b.writeUint8(0); + } + }, + fromObject: function fromObject(object) { + if (object === undefined) { + return undefined; + } + + return st_operation.fromObject(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + // toObject is only null save if use_default is true + var result_object = function () { + if (!debug.use_default && object === undefined) { + return undefined; + } + + return st_operation.toObject(object, debug); + }(); + + if (debug.annotate) { + if ((typeof result_object === 'undefined' ? 'undefined' : _typeof(result_object)) === 'object') { + result_object.__optional = 'parent is optional'; + } else { + result_object = { __optional: result_object }; + } + } + + return result_object; + } + }; +}; + +Types.static_variant = function (_st_operations) { + var static_variant = { + nosort: true, + st_operations: _st_operations, + fromByteBuffer: function fromByteBuffer(b) { + var type_id = b.readVarint32(); + var st_operation = this.st_operations[type_id]; + + if (HEX_DUMP) { + console.error('static_variant id 0x' + type_id.toString(16) + ' (' + type_id + ')'); + } + + _SerializerValidation2.default.required(st_operation, 'operation ' + type_id); + return [type_id, st_operation.fromByteBuffer(b)]; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.required(object); + var type_id = object[0]; + var st_operation = this.st_operations[type_id]; + _SerializerValidation2.default.required(st_operation, 'operation ' + type_id); + b.writeVarint32(type_id); + st_operation.appendByteBuffer(b, object[1]); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + var type_id = object[0]; + var st_operation = this.st_operations[type_id]; + + _SerializerValidation2.default.required(st_operation, 'operation ' + type_id); + return [type_id, st_operation.fromObject(object[1])]; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [0, this.st_operations[0].toObject(undefined, debug)]; + } + + _SerializerValidation2.default.required(object); + var type_id = object[0]; + var st_operation = this.st_operations[type_id]; + _SerializerValidation2.default.required(st_operation, 'operation ' + type_id); + return [type_id, st_operation.toObject(object[1], debug)]; + } + }; + + return static_variant; +}; + +Types.map = function (key_st_operation, value_st_operation) { + var map_object = { + validate: function validate(array) { + if (!Array.isArray(array)) { + throw new Error('expecting array'); + } + + var dup_map = {}; + + for (var i = 0, len = array.length; i < len; i++) { + var o = array[i]; + var ref = void 0; + + if (!(o.length === 2)) { + throw new Error('expecting two elements'); + } + + ref = _typeof(o[0]); + + if (ref && ['number', 'string'].indexOf(ref) >= 0) { + if (dup_map[o[0]] !== undefined) { + throw new Error('duplicate (map)'); + } + + dup_map[o[0]] = true; + } + } + + return sortOperation(array, key_st_operation); + }, + fromByteBuffer: function fromByteBuffer(b) { + var result = []; + var end = b.readVarint32(); + + for (var i = 0; end > 0 ? i < end : i > end; end > 0 ? i++ : i++) { + result.push([key_st_operation.fromByteBuffer(b), value_st_operation.fromByteBuffer(b)]); + } + + return this.validate(result); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + this.validate(object); + b.writeVarint32(object.length); + + for (var i = 0, len = object.length; i < len; i++) { + var o = object[i]; + key_st_operation.appendByteBuffer(b, o[0]); + value_st_operation.appendByteBuffer(b, o[1]); + } + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + var result = []; + + for (var i = 0, len = object.length; i < len; i++) { + var o = object[i]; + result.push([key_st_operation.fromObject(o[0]), value_st_operation.fromObject(o[1])]); + } + + return this.validate(result); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [[key_st_operation.toObject(undefined, debug), value_st_operation.toObject(undefined, debug)]]; + } + + _SerializerValidation2.default.required(object); + object = this.validate(object); + var result = []; + + for (var i = 0, len = object.length; i < len; i++) { + var o = object[i]; + result.push([key_st_operation.toObject(o[0], debug), value_st_operation.toObject(o[1], debug)]); + } + + return result; + } + }; + + return map_object; +}; + +Types.public_key = { + toPublic: function toPublic(object) { + if (object.resolve !== undefined) { + object = object.resolve; + } + + if (object instanceof _ecc.PublicKey) { + return object; + } + + var result = object; + + if (!object) { + return null; + } + + if (!object.Q) { + result = _ecc.PublicKey.fromStringOrThrow(object); + } + + return result; + }, + fromByteBuffer: function fromByteBuffer(b) { + return _FastParser2.default.public_key(b); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _SerializerValidation2.default.required(object); + _FastParser2.default.public_key(b, Types.public_key.toPublic(object)); + }, + fromObject: function fromObject(object) { + _SerializerValidation2.default.required(object); + + if (object.Q) { + return object; + } + + return Types.public_key.toPublic(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return _peerplaysjsWs.ChainConfig.address_prefix + '859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2HqhToVM'; + } + + _SerializerValidation2.default.required(object); + return object.toString(); + }, + compare: function compare(a, b) { + return strCmp(a.toAddressString(), b.toAddressString()); + } +}; + +Types.address = { + _to_address: function _to_address(object) { + _SerializerValidation2.default.required(object); + + if (object.addy) { + return object; + } + + return _ecc.Address.fromString(object); + }, + fromByteBuffer: function fromByteBuffer(b) { + return new _ecc.Address(_FastParser2.default.ripemd160(b)); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + _FastParser2.default.ripemd160(b, Types.address._to_address(object).toBuffer()); + }, + fromObject: function fromObject(object) { + return Types.address._to_address(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return _peerplaysjsWs.ChainConfig.address_prefix + '664KmHxSuQyDsfwo4WEJvWpzg1QKdg67S'; + } + + return Types.address._to_address(object).toString(); + }, + compare: function compare(a, b) { + return strCmp(a.toString(), b.toString()); + } +}; + +Types.variant = { + fromByteBuffer: function fromByteBuffer(b) { + var type = b.readUint8(); + + switch (type) { + case 0: + return null; + case 1: + return Types.int64.fromByteBuffer(b); + case 2: + return Types.uint64.fromByteBuffer(b); + case 3: + return b.readDouble(); + case 4: + return Types.bool.fromByteBuffer(b); + case 5: + return Types.string.fromByteBuffer(b); + case 6: + return Types.array(Types.variant).fromByteBuffer(b); + case 7: + default: + return Types.variant_object.fromByteBuffer(b); + } + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (typeof object === 'number') { + if (Number.isInteger(object)) { + if (object >= 0) { + b.writeUint8(2); + Types.uint64.appendByteBuffer(b, object); + } else { + b.writeUint8(1); + Types.int64.appendByteBuffer(b, object); + } + } else { + b.writeUint8(3); + b.writeDouble(Number.parseFloat(object)); + } + } else if (typeof object === 'boolean') { + b.writeUint8(4); + Types.bool.appendByteBuffer(b, object); + } else if (typeof object === 'string') { + b.writeUint8(5); + Types.string.appendByteBuffer(b, object); + } else if (Array.isArray(object)) { + b.writeUint8(6); + Types.array(Types.variant).appendByteBuffer(b, object); + } else { + b.writeUint8(7); + Types.variant_object.appendByteBuffer(b, object); + } + }, + fromObject: function fromObject(object) { + return JSON.parse(object); + }, + toObject: function toObject(object) { + return JSON.parse(object); + } +}; + +Types.variant_object = { + fromByteBuffer: function fromByteBuffer(b) { + var count = b.readVarint32(); + var result = {}; + + for (var i = 0; i < count; ++i) { + var key = Types.string.fromByteBuffer(b); + result[key] = Types.variant.fromByteBuffer(b); + } + + return result; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + var keys = Object.keys(object); + + b.writeVarint32(keys.length); // number of key/value pairs + + for (var i = 0, len = keys.length; i < len; i++) { + var key = keys[i]; + Types.string.appendByteBuffer(b, key); + Types.variant.appendByteBuffer(b, object[key]); + } + }, + fromObject: function fromObject(object) { + var newObject = {}; + + var keys = Object.keys(object); + + for (var i = 0, len = keys.length; i < len; i++) { + var key = keys[i]; + newObject[key] = object[key]; + } + + return newObject; + }, + toObject: function toObject(object) { + var newObject = {}; + + var keys = Object.keys(object); + + for (var i = 0, len = keys.length; i < len; i++) { + var key = keys[i]; + newObject[key] = object[key]; + } + + return newObject; + } +}; + +Types.enumeration = function (values) { + var enumeration = { + fromByteBuffer: function fromByteBuffer(b) { + return values[b.readVarint32ZigZag()]; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + b.writeVarint32ZigZag(values.indexOf(object)); + }, + fromObject: function fromObject(object) { + return object; + }, + toObject: function toObject(object) { + return object; + } + }; + + return enumeration; +}; + +Types.sha256 = Types.bytes(32); + +exports.default = Types; +module.exports = exports['default']; +}).call(this,require(77),require(35).Buffer) + +},{"20":20,"21":21,"3":3,"35":35,"4":4,"7":7,"70":70,"77":77}],27:[function(require,module,exports){ +(function (global){ +'use strict'; + +// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js +// original notice: + +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +function compare(a, b) { + if (a === b) { + return 0; + } + + var x = a.length; + var y = b.length; + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i]; + y = b[i]; + break; + } + } + + if (x < y) { + return -1; + } + if (y < x) { + return 1; + } + return 0; +} +function isBuffer(b) { + if (global.Buffer && typeof global.Buffer.isBuffer === 'function') { + return global.Buffer.isBuffer(b); + } + return !!(b != null && b._isBuffer); +} + +// based on node assert, original notice: + +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// 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 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. + +var util = require(108); +var hasOwn = Object.prototype.hasOwnProperty; +var pSlice = Array.prototype.slice; +var functionsHaveNames = (function () { + return function foo() {}.name === 'foo'; +}()); +function pToString (obj) { + return Object.prototype.toString.call(obj); +} +function isView(arrbuf) { + if (isBuffer(arrbuf)) { + return false; + } + if (typeof global.ArrayBuffer !== 'function') { + return false; + } + if (typeof ArrayBuffer.isView === 'function') { + return ArrayBuffer.isView(arrbuf); + } + if (!arrbuf) { + return false; + } + if (arrbuf instanceof DataView) { + return true; + } + if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) { + return true; + } + return false; +} +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +var regex = /\s*function\s+([^\(\s]*)\s*/; +// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js +function getName(func) { + if (!util.isFunction(func)) { + return; + } + if (functionsHaveNames) { + return func.name; + } + var str = func.toString(); + var match = str.match(regex); + return match && match[1]; +} +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = getName(stackStartFunction); + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function truncate(s, n) { + if (typeof s === 'string') { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} +function inspect(something) { + if (functionsHaveNames || !util.isFunction(something)) { + return util.inspect(something); + } + var rawname = getName(something); + var name = rawname ? ': ' + rawname : ''; + return '[Function' + name + ']'; +} +function getMessage(self) { + return truncate(inspect(self.actual), 128) + ' ' + + self.operator + ' ' + + truncate(inspect(self.expected), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected, false)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { + if (!_deepEqual(actual, expected, true)) { + fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual); + } +}; + +function _deepEqual(actual, expected, strict, memos) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + } else if (isBuffer(actual) && isBuffer(expected)) { + return compare(actual, expected) === 0; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if ((actual === null || typeof actual !== 'object') && + (expected === null || typeof expected !== 'object')) { + return strict ? actual === expected : actual == expected; + + // If both values are instances of typed arrays, wrap their underlying + // ArrayBuffers in a Buffer each to increase performance + // This optimization requires the arrays to have the same type as checked by + // Object.prototype.toString (aka pToString). Never perform binary + // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their + // bit patterns are not identical. + } else if (isView(actual) && isView(expected) && + pToString(actual) === pToString(expected) && + !(actual instanceof Float32Array || + actual instanceof Float64Array)) { + return compare(new Uint8Array(actual.buffer), + new Uint8Array(expected.buffer)) === 0; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else if (isBuffer(actual) !== isBuffer(expected)) { + return false; + } else { + memos = memos || {actual: [], expected: []}; + + var actualIndex = memos.actual.indexOf(actual); + if (actualIndex !== -1) { + if (actualIndex === memos.expected.indexOf(expected)) { + return true; + } + } + + memos.actual.push(actual); + memos.expected.push(expected); + + return objEquiv(actual, expected, strict, memos); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b, strict, actualVisitedObjects) { + if (a === null || a === undefined || b === null || b === undefined) + return false; + // if one is a primitive, the other must be same + if (util.isPrimitive(a) || util.isPrimitive(b)) + return a === b; + if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) + return false; + var aIsArgs = isArguments(a); + var bIsArgs = isArguments(b); + if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) + return false; + if (aIsArgs) { + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b, strict); + } + var ka = objectKeys(a); + var kb = objectKeys(b); + var key, i; + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length !== kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] !== kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) + return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected, false)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +assert.notDeepStrictEqual = notDeepStrictEqual; +function notDeepStrictEqual(actual, expected, message) { + if (_deepEqual(actual, expected, true)) { + fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); + } +} + + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } + + try { + if (actual instanceof expected) { + return true; + } + } catch (e) { + // Ignore. The instanceof check doesn't work for arrow functions. + } + + if (Error.isPrototypeOf(expected)) { + return false; + } + + return expected.call({}, actual) === true; +} + +function _tryBlock(block) { + var error; + try { + block(); + } catch (e) { + error = e; + } + return error; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (typeof block !== 'function') { + throw new TypeError('"block" argument must be a function'); + } + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + actual = _tryBlock(block); + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + var userProvidedMessage = typeof message === 'string'; + var isUnwantedException = !shouldThrow && util.isError(actual); + var isUnexpectedException = !shouldThrow && actual && !expected; + + if ((isUnwantedException && + userProvidedMessage && + expectedException(actual, expected)) || + isUnexpectedException) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws(true, block, error, message); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { + _throws(false, block, error, message); +}; + +assert.ifError = function(err) { if (err) throw err; }; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"108":108}],28:[function(require,module,exports){ +// base-x encoding +// Forked from https://github.com/cryptocoinjs/bs58 +// Originally written by Mike Hearn for BitcoinJ +// Copyright (c) 2011 Google Inc +// Ported to JavaScript by Stefan Thomas +// Merged Buffer refactorings from base58-native by Stephen Pair +// Copyright (c) 2013 BitPay Inc + +module.exports = function base (ALPHABET) { + var ALPHABET_MAP = {} + var BASE = ALPHABET.length + var LEADER = ALPHABET.charAt(0) + + // pre-compute lookup table + for (var i = 0; i < ALPHABET.length; i++) { + ALPHABET_MAP[ALPHABET.charAt(i)] = i + } + + function encode (source) { + if (source.length === 0) return '' + + var digits = [0] + for (var i = 0; i < source.length; ++i) { + for (var j = 0, carry = source[i]; j < digits.length; ++j) { + carry += digits[j] << 8 + digits[j] = carry % BASE + carry = (carry / BASE) | 0 + } + + while (carry > 0) { + digits.push(carry % BASE) + carry = (carry / BASE) | 0 + } + } + + var string = '' + + // deal with leading zeros + for (var k = 0; source[k] === 0 && k < source.length - 1; ++k) string += ALPHABET[0] + // convert digits to a string + for (var q = digits.length - 1; q >= 0; --q) string += ALPHABET[digits[q]] + + return string + } + + function decodeUnsafe (string) { + if (string.length === 0) return [] + + var bytes = [0] + for (var i = 0; i < string.length; i++) { + var value = ALPHABET_MAP[string[i]] + if (value === undefined) return + + for (var j = 0, carry = value; j < bytes.length; ++j) { + carry += bytes[j] * BASE + bytes[j] = carry & 0xff + carry >>= 8 + } + + while (carry > 0) { + bytes.push(carry & 0xff) + carry >>= 8 + } + } + + // deal with leading zeros + for (var k = 0; string[k] === LEADER && k < string.length - 1; ++k) { + bytes.push(0) + } + + return bytes.reverse() + } + + function decode (string) { + var array = decodeUnsafe(string) + if (array) return array + + throw new Error('Non-base' + BASE + ' character') + } + + return { + encode: encode, + decodeUnsafe: decodeUnsafe, + decode: decode + } +} + +},{}],29:[function(require,module,exports){ +'use strict' + +exports.byteLength = byteLength +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray + +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array + +var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' +for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i +} + +// Support decoding URL-safe base64 strings, as Node.js does. +// See: https://en.wikipedia.org/wiki/Base64#URL_applications +revLookup['-'.charCodeAt(0)] = 62 +revLookup['_'.charCodeAt(0)] = 63 + +function getLens (b64) { + var len = b64.length + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // Trim off extra bytes after placeholder bytes are found + // See: https://github.com/beatgammit/base64-js/issues/42 + var validLen = b64.indexOf('=') + if (validLen === -1) validLen = len + + var placeHoldersLen = validLen === len + ? 0 + : 4 - (validLen % 4) + + return [validLen, placeHoldersLen] +} + +// base64 is 4/3 + up to two characters of the original data +function byteLength (b64) { + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} + +function _byteLength (b64, validLen, placeHoldersLen) { + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} + +function toByteArray (b64) { + var tmp + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + + var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) + + var curByte = 0 + + // if there are placeholders, only get up to the last complete 4 chars + var len = placeHoldersLen > 0 + ? validLen - 4 + : validLen + + for (var i = 0; i < len; i += 4) { + tmp = + (revLookup[b64.charCodeAt(i)] << 18) | + (revLookup[b64.charCodeAt(i + 1)] << 12) | + (revLookup[b64.charCodeAt(i + 2)] << 6) | + revLookup[b64.charCodeAt(i + 3)] + arr[curByte++] = (tmp >> 16) & 0xFF + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF + } + + if (placeHoldersLen === 2) { + tmp = + (revLookup[b64.charCodeAt(i)] << 2) | + (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[curByte++] = tmp & 0xFF + } + + if (placeHoldersLen === 1) { + tmp = + (revLookup[b64.charCodeAt(i)] << 10) | + (revLookup[b64.charCodeAt(i + 1)] << 4) | + (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + + lookup[num >> 12 & 0x3F] + + lookup[num >> 6 & 0x3F] + + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = + ((uint8[i] << 16) & 0xFF0000) + + ((uint8[i + 1] << 8) & 0xFF00) + + (uint8[i + 2] & 0xFF) + output.push(tripletToBase64(tmp)) + } + return output.join('') +} + +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk( + uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength) + )) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + parts.push( + lookup[tmp >> 2] + + lookup[(tmp << 4) & 0x3F] + + '==' + ) + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + uint8[len - 1] + parts.push( + lookup[tmp >> 10] + + lookup[(tmp >> 4) & 0x3F] + + lookup[(tmp << 2) & 0x3F] + + '=' + ) + } + + return parts.join('') +} + +},{}],30:[function(require,module,exports){ +// (public) Constructor +function BigInteger(a, b, c) { + if (!(this instanceof BigInteger)) + return new BigInteger(a, b, c) + + if (a != null) { + if ("number" == typeof a) this.fromNumber(a, b, c) + else if (b == null && "string" != typeof a) this.fromString(a, 256) + else this.fromString(a, b) + } +} + +var proto = BigInteger.prototype + +// duck-typed isBigInteger +proto.__bigi = require(33).version +BigInteger.isBigInteger = function (obj, check_ver) { + return obj && obj.__bigi && (!check_ver || obj.__bigi === proto.__bigi) +} + +// Bits per digit +var dbits + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c + c = Math.floor(v / 0x4000000) + w[j++] = v & 0x3ffffff + } + return c +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff, + xh = x >> 15 + while (--n >= 0) { + var l = this[i] & 0x7fff + var h = this[i++] >> 15 + var m = xh * l + h * xl + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff) + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30) + w[j++] = l & 0x3fffffff + } + return c +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff, + xh = x >> 14 + while (--n >= 0) { + var l = this[i] & 0x3fff + var h = this[i++] >> 14 + var m = xh * l + h * xl + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c + c = (l >> 28) + (m >> 14) + xh * h + w[j++] = l & 0xfffffff + } + return c +} + +// wtf? +BigInteger.prototype.am = am1 +dbits = 26 + +BigInteger.prototype.DB = dbits +BigInteger.prototype.DM = ((1 << dbits) - 1) +var DV = BigInteger.prototype.DV = (1 << dbits) + +var BI_FP = 52 +BigInteger.prototype.FV = Math.pow(2, BI_FP) +BigInteger.prototype.F1 = BI_FP - dbits +BigInteger.prototype.F2 = 2 * dbits - BI_FP + +// Digit conversions +var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz" +var BI_RC = new Array() +var rr, vv +rr = "0".charCodeAt(0) +for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv +rr = "a".charCodeAt(0) +for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv +rr = "A".charCodeAt(0) +for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv + +function int2char(n) { + return BI_RM.charAt(n) +} + +function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)] + return (c == null) ? -1 : c +} + +// (protected) copy this to r +function bnpCopyTo(r) { + for (var i = this.t - 1; i >= 0; --i) r[i] = this[i] + r.t = this.t + r.s = this.s +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1 + this.s = (x < 0) ? -1 : 0 + if (x > 0) this[0] = x + else if (x < -1) this[0] = x + DV + else this.t = 0 +} + +// return bigint initialized to value +function nbv(i) { + var r = new BigInteger() + r.fromInt(i) + return r +} + +// (protected) set from string and radix +function bnpFromString(s, b) { + var self = this + + var k + if (b == 16) k = 4 + else if (b == 8) k = 3 + else if (b == 256) k = 8; // byte array + else if (b == 2) k = 1 + else if (b == 32) k = 5 + else if (b == 4) k = 2 + else { + self.fromRadix(s, b) + return + } + self.t = 0 + self.s = 0 + var i = s.length, + mi = false, + sh = 0 + while (--i >= 0) { + var x = (k == 8) ? s[i] & 0xff : intAt(s, i) + if (x < 0) { + if (s.charAt(i) == "-") mi = true + continue + } + mi = false + if (sh == 0) + self[self.t++] = x + else if (sh + k > self.DB) { + self[self.t - 1] |= (x & ((1 << (self.DB - sh)) - 1)) << sh + self[self.t++] = (x >> (self.DB - sh)) + } else + self[self.t - 1] |= x << sh + sh += k + if (sh >= self.DB) sh -= self.DB + } + if (k == 8 && (s[0] & 0x80) != 0) { + self.s = -1 + if (sh > 0) self[self.t - 1] |= ((1 << (self.DB - sh)) - 1) << sh + } + self.clamp() + if (mi) BigInteger.ZERO.subTo(self, self) +} + +// (protected) clamp off excess high words +function bnpClamp() { + var c = this.s & this.DM + while (this.t > 0 && this[this.t - 1] == c)--this.t +} + +// (public) return string representation in given radix +function bnToString(b) { + var self = this + if (self.s < 0) return "-" + self.negate() + .toString(b) + var k + if (b == 16) k = 4 + else if (b == 8) k = 3 + else if (b == 2) k = 1 + else if (b == 32) k = 5 + else if (b == 4) k = 2 + else return self.toRadix(b) + var km = (1 << k) - 1, + d, m = false, + r = "", + i = self.t + var p = self.DB - (i * self.DB) % k + if (i-- > 0) { + if (p < self.DB && (d = self[i] >> p) > 0) { + m = true + r = int2char(d) + } + while (i >= 0) { + if (p < k) { + d = (self[i] & ((1 << p) - 1)) << (k - p) + d |= self[--i] >> (p += self.DB - k) + } else { + d = (self[i] >> (p -= k)) & km + if (p <= 0) { + p += self.DB + --i + } + } + if (d > 0) m = true + if (m) r += int2char(d) + } + } + return m ? r : "0" +} + +// (public) -this +function bnNegate() { + var r = new BigInteger() + BigInteger.ZERO.subTo(this, r) + return r +} + +// (public) |this| +function bnAbs() { + return (this.s < 0) ? this.negate() : this +} + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s - a.s + if (r != 0) return r + var i = this.t + r = i - a.t + if (r != 0) return (this.s < 0) ? -r : r + while (--i >= 0) + if ((r = this[i] - a[i]) != 0) return r + return 0 +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, + t + if ((t = x >>> 16) != 0) { + x = t + r += 16 + } + if ((t = x >> 8) != 0) { + x = t + r += 8 + } + if ((t = x >> 4) != 0) { + x = t + r += 4 + } + if ((t = x >> 2) != 0) { + x = t + r += 2 + } + if ((t = x >> 1) != 0) { + x = t + r += 1 + } + return r +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if (this.t <= 0) return 0 + return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)) +} + +// (public) return the number of bytes in "this" +function bnByteLength() { + return this.bitLength() >> 3 +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n, r) { + var i + for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i] + for (i = n - 1; i >= 0; --i) r[i] = 0 + r.t = this.t + n + r.s = this.s +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n, r) { + for (var i = n; i < this.t; ++i) r[i - n] = this[i] + r.t = Math.max(this.t - n, 0) + r.s = this.s +} + +// (protected) r = this << n +function bnpLShiftTo(n, r) { + var self = this + var bs = n % self.DB + var cbs = self.DB - bs + var bm = (1 << cbs) - 1 + var ds = Math.floor(n / self.DB), + c = (self.s << bs) & self.DM, + i + for (i = self.t - 1; i >= 0; --i) { + r[i + ds + 1] = (self[i] >> cbs) | c + c = (self[i] & bm) << bs + } + for (i = ds - 1; i >= 0; --i) r[i] = 0 + r[ds] = c + r.t = self.t + ds + 1 + r.s = self.s + r.clamp() +} + +// (protected) r = this >> n +function bnpRShiftTo(n, r) { + var self = this + r.s = self.s + var ds = Math.floor(n / self.DB) + if (ds >= self.t) { + r.t = 0 + return + } + var bs = n % self.DB + var cbs = self.DB - bs + var bm = (1 << bs) - 1 + r[0] = self[ds] >> bs + for (var i = ds + 1; i < self.t; ++i) { + r[i - ds - 1] |= (self[i] & bm) << cbs + r[i - ds] = self[i] >> bs + } + if (bs > 0) r[self.t - ds - 1] |= (self.s & bm) << cbs + r.t = self.t - ds + r.clamp() +} + +// (protected) r = this - a +function bnpSubTo(a, r) { + var self = this + var i = 0, + c = 0, + m = Math.min(a.t, self.t) + while (i < m) { + c += self[i] - a[i] + r[i++] = c & self.DM + c >>= self.DB + } + if (a.t < self.t) { + c -= a.s + while (i < self.t) { + c += self[i] + r[i++] = c & self.DM + c >>= self.DB + } + c += self.s + } else { + c += self.s + while (i < a.t) { + c -= a[i] + r[i++] = c & self.DM + c >>= self.DB + } + c -= a.s + } + r.s = (c < 0) ? -1 : 0 + if (c < -1) r[i++] = self.DV + c + else if (c > 0) r[i++] = c + r.t = i + r.clamp() +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a, r) { + var x = this.abs(), + y = a.abs() + var i = x.t + r.t = i + y.t + while (--i >= 0) r[i] = 0 + for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t) + r.s = 0 + r.clamp() + if (this.s != a.s) BigInteger.ZERO.subTo(r, r) +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs() + var i = r.t = 2 * x.t + while (--i >= 0) r[i] = 0 + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1) + if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { + r[i + x.t] -= x.DV + r[i + x.t + 1] = 1 + } + } + if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1) + r.s = 0 + r.clamp() +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m, q, r) { + var self = this + var pm = m.abs() + if (pm.t <= 0) return + var pt = self.abs() + if (pt.t < pm.t) { + if (q != null) q.fromInt(0) + if (r != null) self.copyTo(r) + return + } + if (r == null) r = new BigInteger() + var y = new BigInteger(), + ts = self.s, + ms = m.s + var nsh = self.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { + pm.lShiftTo(nsh, y) + pt.lShiftTo(nsh, r) + } else { + pm.copyTo(y) + pt.copyTo(r) + } + var ys = y.t + var y0 = y[ys - 1] + if (y0 == 0) return + var yt = y0 * (1 << self.F1) + ((ys > 1) ? y[ys - 2] >> self.F2 : 0) + var d1 = self.FV / yt, + d2 = (1 << self.F1) / yt, + e = 1 << self.F2 + var i = r.t, + j = i - ys, + t = (q == null) ? new BigInteger() : q + y.dlShiftTo(j, t) + if (r.compareTo(t) >= 0) { + r[r.t++] = 1 + r.subTo(t, r) + } + BigInteger.ONE.dlShiftTo(ys, t) + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) y[y.t++] = 0 + while (--j >= 0) { + // Estimate quotient digit + var qd = (r[--i] == y0) ? self.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2) + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out + y.dlShiftTo(j, t) + r.subTo(t, r) + while (r[i] < --qd) r.subTo(t, r) + } + } + if (q != null) { + r.drShiftTo(ys, q) + if (ts != ms) BigInteger.ZERO.subTo(q, q) + } + r.t = ys + r.clamp() + if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder + if (ts < 0) BigInteger.ZERO.subTo(r, r) +} + +// (public) this mod a +function bnMod(a) { + var r = new BigInteger() + this.abs() + .divRemTo(a, null, r) + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r) + return r +} + +// Modular reduction using "classic" algorithm +function Classic(m) { + this.m = m +} + +function cConvert(x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m) + else return x +} + +function cRevert(x) { + return x +} + +function cReduce(x) { + x.divRemTo(this.m, null, x) +} + +function cMulTo(x, y, r) { + x.multiplyTo(y, r) + this.reduce(r) +} + +function cSqrTo(x, r) { + x.squareTo(r) + this.reduce(r) +} + +Classic.prototype.convert = cConvert +Classic.prototype.revert = cRevert +Classic.prototype.reduce = cReduce +Classic.prototype.mulTo = cMulTo +Classic.prototype.sqrTo = cSqrTo + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if (this.t < 1) return 0 + var x = this[0] + if ((x & 1) == 0) return 0 + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y > 0) ? this.DV - y : -y +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m + this.mp = m.invDigit() + this.mpl = this.mp & 0x7fff + this.mph = this.mp >> 15 + this.um = (1 << (m.DB - 15)) - 1 + this.mt2 = 2 * m.t +} + +// xR mod m +function montConvert(x) { + var r = new BigInteger() + x.abs() + .dlShiftTo(this.m.t, r) + r.divRemTo(this.m, null, r) + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r) + return r +} + +// x/R mod m +function montRevert(x) { + var r = new BigInteger() + x.copyTo(r) + this.reduce(r) + return r +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while (x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0 + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff + var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM + // use am to combine the multiply-shift-add into one call + j = i + this.m.t + x[j] += this.m.am(0, u0, x, i, 0, this.m.t) + // propagate carry + while (x[j] >= x.DV) { + x[j] -= x.DV + x[++j]++ + } + } + x.clamp() + x.drShiftTo(this.m.t, x) + if (x.compareTo(this.m) >= 0) x.subTo(this.m, x) +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x, r) { + x.squareTo(r) + this.reduce(r) +} + +// r = "xy/R mod m"; x,y != r +function montMulTo(x, y, r) { + x.multiplyTo(y, r) + this.reduce(r) +} + +Montgomery.prototype.convert = montConvert +Montgomery.prototype.revert = montRevert +Montgomery.prototype.reduce = montReduce +Montgomery.prototype.mulTo = montMulTo +Montgomery.prototype.sqrTo = montSqrTo + +// (protected) true iff this is even +function bnpIsEven() { + return ((this.t > 0) ? (this[0] & 1) : this.s) == 0 +} + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e, z) { + if (e > 0xffffffff || e < 1) return BigInteger.ONE + var r = new BigInteger(), + r2 = new BigInteger(), + g = z.convert(this), + i = nbits(e) - 1 + g.copyTo(r) + while (--i >= 0) { + z.sqrTo(r, r2) + if ((e & (1 << i)) > 0) z.mulTo(r2, g, r) + else { + var t = r + r = r2 + r2 = t + } + } + return z.revert(r) +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e, m) { + var z + if (e < 256 || m.isEven()) z = new Classic(m) + else z = new Montgomery(m) + return this.exp(e, z) +} + +// protected +proto.copyTo = bnpCopyTo +proto.fromInt = bnpFromInt +proto.fromString = bnpFromString +proto.clamp = bnpClamp +proto.dlShiftTo = bnpDLShiftTo +proto.drShiftTo = bnpDRShiftTo +proto.lShiftTo = bnpLShiftTo +proto.rShiftTo = bnpRShiftTo +proto.subTo = bnpSubTo +proto.multiplyTo = bnpMultiplyTo +proto.squareTo = bnpSquareTo +proto.divRemTo = bnpDivRemTo +proto.invDigit = bnpInvDigit +proto.isEven = bnpIsEven +proto.exp = bnpExp + +// public +proto.toString = bnToString +proto.negate = bnNegate +proto.abs = bnAbs +proto.compareTo = bnCompareTo +proto.bitLength = bnBitLength +proto.byteLength = bnByteLength +proto.mod = bnMod +proto.modPowInt = bnModPowInt + +// (public) +function bnClone() { + var r = new BigInteger() + this.copyTo(r) + return r +} + +// (public) return value as integer +function bnIntValue() { + if (this.s < 0) { + if (this.t == 1) return this[0] - this.DV + else if (this.t == 0) return -1 + } else if (this.t == 1) return this[0] + else if (this.t == 0) return 0 + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0] +} + +// (public) return value as byte +function bnByteValue() { + return (this.t == 0) ? this.s : (this[0] << 24) >> 24 +} + +// (public) return value as short (assumes DB>=16) +function bnShortValue() { + return (this.t == 0) ? this.s : (this[0] << 16) >> 16 +} + +// (protected) return x s.t. r^x < DV +function bnpChunkSize(r) { + return Math.floor(Math.LN2 * this.DB / Math.log(r)) +} + +// (public) 0 if this == 0, 1 if this > 0 +function bnSigNum() { + if (this.s < 0) return -1 + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0 + else return 1 +} + +// (protected) convert to radix string +function bnpToRadix(b) { + if (b == null) b = 10 + if (this.signum() == 0 || b < 2 || b > 36) return "0" + var cs = this.chunkSize(b) + var a = Math.pow(b, cs) + var d = nbv(a), + y = new BigInteger(), + z = new BigInteger(), + r = "" + this.divRemTo(d, y, z) + while (y.signum() > 0) { + r = (a + z.intValue()) + .toString(b) + .substr(1) + r + y.divRemTo(d, y, z) + } + return z.intValue() + .toString(b) + r +} + +// (protected) convert from radix string +function bnpFromRadix(s, b) { + var self = this + self.fromInt(0) + if (b == null) b = 10 + var cs = self.chunkSize(b) + var d = Math.pow(b, cs), + mi = false, + j = 0, + w = 0 + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i) + if (x < 0) { + if (s.charAt(i) == "-" && self.signum() == 0) mi = true + continue + } + w = b * w + x + if (++j >= cs) { + self.dMultiply(d) + self.dAddOffset(w, 0) + j = 0 + w = 0 + } + } + if (j > 0) { + self.dMultiply(Math.pow(b, j)) + self.dAddOffset(w, 0) + } + if (mi) BigInteger.ZERO.subTo(self, self) +} + +// (protected) alternate constructor +function bnpFromNumber(a, b, c) { + var self = this + if ("number" == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) self.fromInt(1) + else { + self.fromNumber(a, c) + if (!self.testBit(a - 1)) // force MSB set + self.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, self) + if (self.isEven()) self.dAddOffset(1, 0); // force odd + while (!self.isProbablePrime(b)) { + self.dAddOffset(2, 0) + if (self.bitLength() > a) self.subTo(BigInteger.ONE.shiftLeft(a - 1), self) + } + } + } else { + // new BigInteger(int,RNG) + var x = new Array(), + t = a & 7 + x.length = (a >> 3) + 1 + b.nextBytes(x) + if (t > 0) x[0] &= ((1 << t) - 1) + else x[0] = 0 + self.fromString(x, 256) + } +} + +// (public) convert to bigendian byte array +function bnToByteArray() { + var self = this + var i = self.t, + r = new Array() + r[0] = self.s + var p = self.DB - (i * self.DB) % 8, + d, k = 0 + if (i-- > 0) { + if (p < self.DB && (d = self[i] >> p) != (self.s & self.DM) >> p) + r[k++] = d | (self.s << (self.DB - p)) + while (i >= 0) { + if (p < 8) { + d = (self[i] & ((1 << p) - 1)) << (8 - p) + d |= self[--i] >> (p += self.DB - 8) + } else { + d = (self[i] >> (p -= 8)) & 0xff + if (p <= 0) { + p += self.DB + --i + } + } + if ((d & 0x80) != 0) d |= -256 + if (k === 0 && (self.s & 0x80) != (d & 0x80))++k + if (k > 0 || d != self.s) r[k++] = d + } + } + return r +} + +function bnEquals(a) { + return (this.compareTo(a) == 0) +} + +function bnMin(a) { + return (this.compareTo(a) < 0) ? this : a +} + +function bnMax(a) { + return (this.compareTo(a) > 0) ? this : a +} + +// (protected) r = this op a (bitwise) +function bnpBitwiseTo(a, op, r) { + var self = this + var i, f, m = Math.min(a.t, self.t) + for (i = 0; i < m; ++i) r[i] = op(self[i], a[i]) + if (a.t < self.t) { + f = a.s & self.DM + for (i = m; i < self.t; ++i) r[i] = op(self[i], f) + r.t = self.t + } else { + f = self.s & self.DM + for (i = m; i < a.t; ++i) r[i] = op(f, a[i]) + r.t = a.t + } + r.s = op(self.s, a.s) + r.clamp() +} + +// (public) this & a +function op_and(x, y) { + return x & y +} + +function bnAnd(a) { + var r = new BigInteger() + this.bitwiseTo(a, op_and, r) + return r +} + +// (public) this | a +function op_or(x, y) { + return x | y +} + +function bnOr(a) { + var r = new BigInteger() + this.bitwiseTo(a, op_or, r) + return r +} + +// (public) this ^ a +function op_xor(x, y) { + return x ^ y +} + +function bnXor(a) { + var r = new BigInteger() + this.bitwiseTo(a, op_xor, r) + return r +} + +// (public) this & ~a +function op_andnot(x, y) { + return x & ~y +} + +function bnAndNot(a) { + var r = new BigInteger() + this.bitwiseTo(a, op_andnot, r) + return r +} + +// (public) ~this +function bnNot() { + var r = new BigInteger() + for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i] + r.t = this.t + r.s = ~this.s + return r +} + +// (public) this << n +function bnShiftLeft(n) { + var r = new BigInteger() + if (n < 0) this.rShiftTo(-n, r) + else this.lShiftTo(n, r) + return r +} + +// (public) this >> n +function bnShiftRight(n) { + var r = new BigInteger() + if (n < 0) this.lShiftTo(-n, r) + else this.rShiftTo(n, r) + return r +} + +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if (x == 0) return -1 + var r = 0 + if ((x & 0xffff) == 0) { + x >>= 16 + r += 16 + } + if ((x & 0xff) == 0) { + x >>= 8 + r += 8 + } + if ((x & 0xf) == 0) { + x >>= 4 + r += 4 + } + if ((x & 3) == 0) { + x >>= 2 + r += 2 + } + if ((x & 1) == 0)++r + return r +} + +// (public) returns index of lowest 1-bit (or -1 if none) +function bnGetLowestSetBit() { + for (var i = 0; i < this.t; ++i) + if (this[i] != 0) return i * this.DB + lbit(this[i]) + if (this.s < 0) return this.t * this.DB + return -1 +} + +// return number of 1 bits in x +function cbit(x) { + var r = 0 + while (x != 0) { + x &= x - 1 + ++r + } + return r +} + +// (public) return number of set bits +function bnBitCount() { + var r = 0, + x = this.s & this.DM + for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x) + return r +} + +// (public) true iff nth bit is set +function bnTestBit(n) { + var j = Math.floor(n / this.DB) + if (j >= this.t) return (this.s != 0) + return ((this[j] & (1 << (n % this.DB))) != 0) +} + +// (protected) this op (1<>= self.DB + } + if (a.t < self.t) { + c += a.s + while (i < self.t) { + c += self[i] + r[i++] = c & self.DM + c >>= self.DB + } + c += self.s + } else { + c += self.s + while (i < a.t) { + c += a[i] + r[i++] = c & self.DM + c >>= self.DB + } + c += a.s + } + r.s = (c < 0) ? -1 : 0 + if (c > 0) r[i++] = c + else if (c < -1) r[i++] = self.DV + c + r.t = i + r.clamp() +} + +// (public) this + a +function bnAdd(a) { + var r = new BigInteger() + this.addTo(a, r) + return r +} + +// (public) this - a +function bnSubtract(a) { + var r = new BigInteger() + this.subTo(a, r) + return r +} + +// (public) this * a +function bnMultiply(a) { + var r = new BigInteger() + this.multiplyTo(a, r) + return r +} + +// (public) this^2 +function bnSquare() { + var r = new BigInteger() + this.squareTo(r) + return r +} + +// (public) this / a +function bnDivide(a) { + var r = new BigInteger() + this.divRemTo(a, r, null) + return r +} + +// (public) this % a +function bnRemainder(a) { + var r = new BigInteger() + this.divRemTo(a, null, r) + return r +} + +// (public) [this/a,this%a] +function bnDivideAndRemainder(a) { + var q = new BigInteger(), + r = new BigInteger() + this.divRemTo(a, q, r) + return new Array(q, r) +} + +// (protected) this *= n, this >= 0, 1 < n < DV +function bnpDMultiply(n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t) + ++this.t + this.clamp() +} + +// (protected) this += n << w words, this >= 0 +function bnpDAddOffset(n, w) { + if (n == 0) return + while (this.t <= w) this[this.t++] = 0 + this[w] += n + while (this[w] >= this.DV) { + this[w] -= this.DV + if (++w >= this.t) this[this.t++] = 0 + ++this[w] + } +} + +// A "null" reducer +function NullExp() {} + +function nNop(x) { + return x +} + +function nMulTo(x, y, r) { + x.multiplyTo(y, r) +} + +function nSqrTo(x, r) { + x.squareTo(r) +} + +NullExp.prototype.convert = nNop +NullExp.prototype.revert = nNop +NullExp.prototype.mulTo = nMulTo +NullExp.prototype.sqrTo = nSqrTo + +// (public) this^e +function bnPow(e) { + return this.exp(e, new NullExp()) +} + +// (protected) r = lower n words of "this * a", a.t <= n +// "this" should be the larger one if appropriate. +function bnpMultiplyLowerTo(a, n, r) { + var i = Math.min(this.t + a.t, n) + r.s = 0; // assumes a,this >= 0 + r.t = i + while (i > 0) r[--i] = 0 + var j + for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t) + for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i) + r.clamp() +} + +// (protected) r = "this * a" without lower n words, n > 0 +// "this" should be the larger one if appropriate. +function bnpMultiplyUpperTo(a, n, r) { + --n + var i = r.t = this.t + a.t - n + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) r[i] = 0 + for (i = Math.max(n - this.t, 0); i < a.t; ++i) + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n) + r.clamp() + r.drShiftTo(1, r) +} + +// Barrett modular reduction +function Barrett(m) { + // setup Barrett + this.r2 = new BigInteger() + this.q3 = new BigInteger() + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2) + this.mu = this.r2.divide(m) + this.m = m +} + +function barrettConvert(x) { + if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m) + else if (x.compareTo(this.m) < 0) return x + else { + var r = new BigInteger() + x.copyTo(r) + this.reduce(r) + return r + } +} + +function barrettRevert(x) { + return x +} + +// x = x mod m (HAC 14.42) +function barrettReduce(x) { + var self = this + x.drShiftTo(self.m.t - 1, self.r2) + if (x.t > self.m.t + 1) { + x.t = self.m.t + 1 + x.clamp() + } + self.mu.multiplyUpperTo(self.r2, self.m.t + 1, self.q3) + self.m.multiplyLowerTo(self.q3, self.m.t + 1, self.r2) + while (x.compareTo(self.r2) < 0) x.dAddOffset(1, self.m.t + 1) + x.subTo(self.r2, x) + while (x.compareTo(self.m) >= 0) x.subTo(self.m, x) +} + +// r = x^2 mod m; x != r +function barrettSqrTo(x, r) { + x.squareTo(r) + this.reduce(r) +} + +// r = x*y mod m; x,y != r +function barrettMulTo(x, y, r) { + x.multiplyTo(y, r) + this.reduce(r) +} + +Barrett.prototype.convert = barrettConvert +Barrett.prototype.revert = barrettRevert +Barrett.prototype.reduce = barrettReduce +Barrett.prototype.mulTo = barrettMulTo +Barrett.prototype.sqrTo = barrettSqrTo + +// (public) this^e % m (HAC 14.85) +function bnModPow(e, m) { + var i = e.bitLength(), + k, r = nbv(1), + z + if (i <= 0) return r + else if (i < 18) k = 1 + else if (i < 48) k = 3 + else if (i < 144) k = 4 + else if (i < 768) k = 5 + else k = 6 + if (i < 8) + z = new Classic(m) + else if (m.isEven()) + z = new Barrett(m) + else + z = new Montgomery(m) + + // precomputation + var g = new Array(), + n = 3, + k1 = k - 1, + km = (1 << k) - 1 + g[1] = z.convert(this) + if (k > 1) { + var g2 = new BigInteger() + z.sqrTo(g[1], g2) + while (n <= km) { + g[n] = new BigInteger() + z.mulTo(g2, g[n - 2], g[n]) + n += 2 + } + } + + var j = e.t - 1, + w, is1 = true, + r2 = new BigInteger(), + t + i = nbits(e[j]) - 1 + while (j >= 0) { + if (i >= k1) w = (e[j] >> (i - k1)) & km + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i) + if (j > 0) w |= e[j - 1] >> (this.DB + i - k1) + } + + n = k + while ((w & 1) == 0) { + w >>= 1 + --n + } + if ((i -= n) < 0) { + i += this.DB + --j + } + if (is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r) + is1 = false + } else { + while (n > 1) { + z.sqrTo(r, r2) + z.sqrTo(r2, r) + n -= 2 + } + if (n > 0) z.sqrTo(r, r2) + else { + t = r + r = r2 + r2 = t + } + z.mulTo(r2, g[w], r) + } + + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2) + t = r + r = r2 + r2 = t + if (--i < 0) { + i = this.DB - 1 + --j + } + } + } + return z.revert(r) +} + +// (public) gcd(this,a) (HAC 14.54) +function bnGCD(a) { + var x = (this.s < 0) ? this.negate() : this.clone() + var y = (a.s < 0) ? a.negate() : a.clone() + if (x.compareTo(y) < 0) { + var t = x + x = y + y = t + } + var i = x.getLowestSetBit(), + g = y.getLowestSetBit() + if (g < 0) return x + if (i < g) g = i + if (g > 0) { + x.rShiftTo(g, x) + y.rShiftTo(g, y) + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x) + if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y) + if (x.compareTo(y) >= 0) { + x.subTo(y, x) + x.rShiftTo(1, x) + } else { + y.subTo(x, y) + y.rShiftTo(1, y) + } + } + if (g > 0) y.lShiftTo(g, y) + return y +} + +// (protected) this % n, n < 2^26 +function bnpModInt(n) { + if (n <= 0) return 0 + var d = this.DV % n, + r = (this.s < 0) ? n - 1 : 0 + if (this.t > 0) + if (d == 0) r = this[0] % n + else + for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n + return r +} + +// (public) 1/this % m (HAC 14.61) +function bnModInverse(m) { + var ac = m.isEven() + if (this.signum() === 0) throw new Error('division by zero') + if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO + var u = m.clone(), + v = this.clone() + var a = nbv(1), + b = nbv(0), + c = nbv(0), + d = nbv(1) + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u) + if (ac) { + if (!a.isEven() || !b.isEven()) { + a.addTo(this, a) + b.subTo(m, b) + } + a.rShiftTo(1, a) + } else if (!b.isEven()) b.subTo(m, b) + b.rShiftTo(1, b) + } + while (v.isEven()) { + v.rShiftTo(1, v) + if (ac) { + if (!c.isEven() || !d.isEven()) { + c.addTo(this, c) + d.subTo(m, d) + } + c.rShiftTo(1, c) + } else if (!d.isEven()) d.subTo(m, d) + d.rShiftTo(1, d) + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u) + if (ac) a.subTo(c, a) + b.subTo(d, b) + } else { + v.subTo(u, v) + if (ac) c.subTo(a, c) + d.subTo(b, d) + } + } + if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO + while (d.compareTo(m) >= 0) d.subTo(m, d) + while (d.signum() < 0) d.addTo(m, d) + return d +} + +var lowprimes = [ + 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, + 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, + 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, + 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, + 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, + 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, + 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, + 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, + 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, + 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, + 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997 +] + +var lplim = (1 << 26) / lowprimes[lowprimes.length - 1] + +// (public) test primality with certainty >= 1-.5^t +function bnIsProbablePrime(t) { + var i, x = this.abs() + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) + if (x[0] == lowprimes[i]) return true + return false + } + if (x.isEven()) return false + i = 1 + while (i < lowprimes.length) { + var m = lowprimes[i], + j = i + 1 + while (j < lowprimes.length && m < lplim) m *= lowprimes[j++] + m = x.modInt(m) + while (i < j) if (m % lowprimes[i++] == 0) return false + } + return x.millerRabin(t) +} + +// (protected) true if probably prime (HAC 4.24, Miller-Rabin) +function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE) + var k = n1.getLowestSetBit() + if (k <= 0) return false + var r = n1.shiftRight(k) + t = (t + 1) >> 1 + if (t > lowprimes.length) t = lowprimes.length + var a = new BigInteger(null) + var j, bases = [] + for (var i = 0; i < t; ++i) { + for (;;) { + j = lowprimes[Math.floor(Math.random() * lowprimes.length)] + if (bases.indexOf(j) == -1) break + } + bases.push(j) + a.fromInt(j) + var y = a.modPow(r, this) + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1 + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this) + if (y.compareTo(BigInteger.ONE) == 0) return false + } + if (y.compareTo(n1) != 0) return false + } + } + return true +} + +// protected +proto.chunkSize = bnpChunkSize +proto.toRadix = bnpToRadix +proto.fromRadix = bnpFromRadix +proto.fromNumber = bnpFromNumber +proto.bitwiseTo = bnpBitwiseTo +proto.changeBit = bnpChangeBit +proto.addTo = bnpAddTo +proto.dMultiply = bnpDMultiply +proto.dAddOffset = bnpDAddOffset +proto.multiplyLowerTo = bnpMultiplyLowerTo +proto.multiplyUpperTo = bnpMultiplyUpperTo +proto.modInt = bnpModInt +proto.millerRabin = bnpMillerRabin + +// public +proto.clone = bnClone +proto.intValue = bnIntValue +proto.byteValue = bnByteValue +proto.shortValue = bnShortValue +proto.signum = bnSigNum +proto.toByteArray = bnToByteArray +proto.equals = bnEquals +proto.min = bnMin +proto.max = bnMax +proto.and = bnAnd +proto.or = bnOr +proto.xor = bnXor +proto.andNot = bnAndNot +proto.not = bnNot +proto.shiftLeft = bnShiftLeft +proto.shiftRight = bnShiftRight +proto.getLowestSetBit = bnGetLowestSetBit +proto.bitCount = bnBitCount +proto.testBit = bnTestBit +proto.setBit = bnSetBit +proto.clearBit = bnClearBit +proto.flipBit = bnFlipBit +proto.add = bnAdd +proto.subtract = bnSubtract +proto.multiply = bnMultiply +proto.divide = bnDivide +proto.remainder = bnRemainder +proto.divideAndRemainder = bnDivideAndRemainder +proto.modPow = bnModPow +proto.modInverse = bnModInverse +proto.pow = bnPow +proto.gcd = bnGCD +proto.isProbablePrime = bnIsProbablePrime + +// JSBN-specific extension +proto.square = bnSquare + +// constants +BigInteger.ZERO = nbv(0) +BigInteger.ONE = nbv(1) +BigInteger.valueOf = nbv + +module.exports = BigInteger + +},{"33":33}],31:[function(require,module,exports){ +(function (Buffer){ +// FIXME: Kind of a weird way to throw exceptions, consider removing +var assert = require(27) +var BigInteger = require(30) + +/** + * Turns a byte array into a big integer. + * + * This function will interpret a byte array as a big integer in big + * endian notation. + */ +BigInteger.fromByteArrayUnsigned = function(byteArray) { + // BigInteger expects a DER integer conformant byte array + if (byteArray[0] & 0x80) { + return new BigInteger([0].concat(byteArray)) + } + + return new BigInteger(byteArray) +} + +/** + * Returns a byte array representation of the big integer. + * + * This returns the absolute of the contained value in big endian + * form. A value of zero results in an empty array. + */ +BigInteger.prototype.toByteArrayUnsigned = function() { + var byteArray = this.toByteArray() + return byteArray[0] === 0 ? byteArray.slice(1) : byteArray +} + +BigInteger.fromDERInteger = function(byteArray) { + return new BigInteger(byteArray) +} + +/* + * Converts BigInteger to a DER integer representation. + * + * The format for this value uses the most significant bit as a sign + * bit. If the most significant bit is already set and the integer is + * positive, a 0x00 is prepended. + * + * Examples: + * + * 0 => 0x00 + * 1 => 0x01 + * -1 => 0xff + * 127 => 0x7f + * -127 => 0x81 + * 128 => 0x0080 + * -128 => 0x80 + * 255 => 0x00ff + * -255 => 0xff01 + * 16300 => 0x3fac + * -16300 => 0xc054 + * 62300 => 0x00f35c + * -62300 => 0xff0ca4 +*/ +BigInteger.prototype.toDERInteger = BigInteger.prototype.toByteArray + +BigInteger.fromBuffer = function(buffer) { + // BigInteger expects a DER integer conformant byte array + if (buffer[0] & 0x80) { + var byteArray = Array.prototype.slice.call(buffer) + + return new BigInteger([0].concat(byteArray)) + } + + return new BigInteger(buffer) +} + +BigInteger.fromHex = function(hex) { + if (hex === '') return BigInteger.ZERO + + assert.equal(hex, hex.match(/^[A-Fa-f0-9]+/), 'Invalid hex string') + assert.equal(hex.length % 2, 0, 'Incomplete hex') + return new BigInteger(hex, 16) +} + +BigInteger.prototype.toBuffer = function(size) { + var byteArray = this.toByteArrayUnsigned() + var zeros = [] + + var padding = size - byteArray.length + while (zeros.length < padding) zeros.push(0) + + return new Buffer(zeros.concat(byteArray)) +} + +BigInteger.prototype.toHex = function(size) { + return this.toBuffer(size).toString('hex') +} + +}).call(this,require(35).Buffer) + +},{"27":27,"30":30,"35":35}],32:[function(require,module,exports){ +var BigInteger = require(30) + +//addons +require(31) + +module.exports = BigInteger +},{"30":30,"31":31}],33:[function(require,module,exports){ +module.exports={ + "bugs": { + "url": "https://github.com/cryptocoinjs/bigi/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Big integers.", + "devDependencies": { + "coveralls": "^2.11.2", + "istanbul": "^0.3.5", + "jshint": "^2.5.1", + "mocha": "^2.1.0", + "mochify": "^2.1.0" + }, + "homepage": "https://github.com/cryptocoinjs/bigi#readme", + "keywords": [ + "cryptography", + "math", + "bitcoin", + "arbitrary", + "precision", + "arithmetic", + "big", + "integer", + "int", + "number", + "biginteger", + "bigint", + "bignumber", + "decimal", + "float" + ], + "main": "./lib/index.js", + "name": "bigi", + "repository": { + "url": "git+https://github.com/cryptocoinjs/bigi.git", + "type": "git" + }, + "scripts": { + "browser-test": "mochify --wd -R spec", + "coverage": "istanbul cover ./node_modules/.bin/_mocha -- --reporter list test/*.js", + "coveralls": "npm run-script coverage && node ./node_modules/.bin/coveralls < coverage/lcov.info", + "jshint": "jshint --config jshint.json lib/*.js ; true", + "test": "_mocha -- test/*.js", + "unit": "mocha" + }, + "testling": { + "files": "test/*.js", + "harness": "mocha", + "browsers": [ + "ie/9..latest", + "firefox/latest", + "chrome/latest", + "safari/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.4.2" +} +},{}],34:[function(require,module,exports){ + +},{}],35:[function(require,module,exports){ +(function (global){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +/* eslint-disable no-proto */ + +'use strict' + +var base64 = require(29) +var ieee754 = require(64) +var isArray = require(67) + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined + ? global.TYPED_ARRAY_SUPPORT + : typedArraySupport() + +/* + * Export kMaxLength after typed array support is determined. + */ +exports.kMaxLength = kMaxLength() + +function typedArraySupport () { + try { + var arr = new Uint8Array(1) + arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} + return arr.foo() === 42 && // typed array instances can be augmented + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } +} + +function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff +} + +function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length) + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length) + } + that.length = length + } + + return that +} + +/** + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. + * + * The `Uint8Array` prototype remains unmodified. + */ + +function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } + + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) + } + return allocUnsafe(this, arg) + } + return from(this, arg, encodingOrOffset, length) +} + +Buffer.poolSize = 8192 // not used by this implementation + +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype + return arr +} + +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } + + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } + + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } + + return fromObject(that, value) +} + +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) +} + +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype + Buffer.__proto__ = Uint8Array + if (typeof Symbol !== 'undefined' && Symbol.species && + Buffer[Symbol.species] === Buffer) { + // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 + Object.defineProperty(Buffer, Symbol.species, { + value: null, + configurable: true + }) + } +} + +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } else if (size < 0) { + throw new RangeError('"size" argument must not be negative') + } +} + +function alloc (that, size, fill, encoding) { + assertSize(size) + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) +} + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) +} + +function allocUnsafe (that, size) { + assertSize(size) + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; ++i) { + that[i] = 0 + } + } + return that +} + +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) +} +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) +} + +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8' + } + + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') + } + + var length = byteLength(string, encoding) | 0 + that = createBuffer(that, length) + + var actual = that.write(string, encoding) + + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + that = that.slice(0, actual) + } + + return that +} + +function fromArrayLike (that, array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0 + that = createBuffer(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength // this throws if `array` is not a valid ArrayBuffer + + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } + + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } + + if (byteOffset === undefined && length === undefined) { + array = new Uint8Array(array) + } else if (length === undefined) { + array = new Uint8Array(array, byteOffset) + } else { + array = new Uint8Array(array, byteOffset, length) + } + + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + that = fromArrayLike(that, array) + } + return that +} + +function fromObject (that, obj) { + if (Buffer.isBuffer(obj)) { + var len = checked(obj.length) | 0 + that = createBuffer(that, len) + + if (that.length === 0) { + return that + } + + obj.copy(that, 0, 0, len) + return that + } + + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } + + if (obj.type === 'Buffer' && isArray(obj.data)) { + return fromArrayLike(that, obj.data) + } + } + + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') +} + +function checked (length) { + // Note: cannot use `length < kMaxLength()` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (length) { + if (+length != length) { // eslint-disable-line eqeqeq + length = 0 + } + return Buffer.alloc(+length) +} + +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i] + y = b[i] + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer.alloc(0) + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; ++i) { + length += list[i].length + } + } + + var buffer = Buffer.allocUnsafe(length) + var pos = 0 + for (i = 0; i < list.length; ++i) { + var buf = list[i] + if (!Buffer.isBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos) + pos += buf.length + } + return buffer +} + +function byteLength (string, encoding) { + if (Buffer.isBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string + } + + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength + +function slowToString (encoding, start, end) { + var loweredCase = false + + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. + + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0 + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } + + if (end === undefined || end > this.length) { + end = this.length + } + + if (end <= 0) { + return '' + } + + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0 + start >>>= 0 + + if (end <= start) { + return '' + } + + if (!encoding) encoding = 'utf8' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect +// Buffer instances. +Buffer.prototype._isBuffer = true + +function swap (b, n, m) { + var i = b[n] + b[n] = b[m] + b[m] = i +} + +Buffer.prototype.swap16 = function swap16 () { + var len = this.length + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1) + } + return this +} + +Buffer.prototype.swap32 = function swap32 () { + var len = this.length + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3) + swap(this, i + 1, i + 2) + } + return this +} + +Buffer.prototype.swap64 = function swap64 () { + var len = this.length + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7) + swap(this, i + 1, i + 6) + swap(this, i + 2, i + 5) + swap(this, i + 3, i + 4) + } + return this +} + +Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '' +} + +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!Buffer.isBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } + + if (start === undefined) { + start = 0 + } + if (end === undefined) { + end = target ? target.length : 0 + } + if (thisStart === undefined) { + thisStart = 0 + } + if (thisEnd === undefined) { + thisEnd = this.length + } + + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } + + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } + + start >>>= 0 + end >>>= 0 + thisStart >>>= 0 + thisEnd >>>= 0 + + if (this === target) return 0 + + var x = thisEnd - thisStart + var y = end - start + var len = Math.min(x, y) + + var thisCopy = this.slice(thisStart, thisEnd) + var targetCopy = target.slice(start, end) + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i] + y = targetCopy[i] + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant is val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) return -1 + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset + byteOffset = 0 + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000 + } + byteOffset = +byteOffset // Coerce to Number. + if (isNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1) + } + + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = buffer.length + byteOffset + if (byteOffset >= buffer.length) { + if (dir) return -1 + else byteOffset = buffer.length - 1 + } else if (byteOffset < 0) { + if (dir) byteOffset = 0 + else return -1 + } + + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding) + } + + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (Buffer.isBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF // Search for a byte value [0-255] + if (Buffer.TYPED_ARRAY_SUPPORT && + typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } + } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) + } + + throw new TypeError('val must be string, number or Buffer') +} + +function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1 + var arrLength = arr.length + var valLength = val.length + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase() + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2 + arrLength /= 2 + valLength /= 2 + byteOffset /= 2 + } + } + + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) + } + } + + var i + if (dir) { + var foundIndex = -1 + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === valLength) return foundIndex * indexSize + } else { + if (foundIndex !== -1) i -= i - foundIndex + foundIndex = -1 + } + } + } else { + if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength + for (i = byteOffset; i >= 0; i--) { + var found = true + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false + break + } + } + if (found) return i + } + } + + return -1 +} + +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 +} + +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) +} + +Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) return i + buf[offset + i] = parsed + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) + } + + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] + + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } + + res.push(codePoint) + i += bytesPerSequence + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000 + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function latin1Slice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; ++i) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end) + newBuf.__proto__ = Buffer.prototype + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; ++i) { + newBuf[i] = this[i + start] + } + } + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val +} + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val +} + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') + if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') + if (offset + ext > buf.length) throw new RangeError('Index out of range') +} + +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = (value & 0xff) + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1 + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + var sub = 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1 + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = (value & 0xff) + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) throw new RangeError('Index out of range') + if (offset < 0) throw new RangeError('Index out of range') +} + +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; ++i) { + target[i + targetStart] = this[i + start] + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ) + } + + return len +} + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start + start = 0 + end = this.length + } else if (typeof end === 'string') { + encoding = end + end = this.length + } + if (val.length === 1) { + var code = val.charCodeAt(0) + if (code < 256) { + val = code + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255 + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } + + if (end <= start) { + return this + } + + start = start >>> 0 + end = end === undefined ? this.length : end >>> 0 + + if (!val) val = 0 + + var i + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val + } + } else { + var bytes = Buffer.isBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()) + var len = bytes.length + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len] + } + } + + return this +} + +// HELPER FUNCTIONS +// ================ + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"29":29,"64":64,"67":67}],36:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +var Buffer = require(35).Buffer; + +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } + + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. CESU-8 is handled as part of the UTF-8 encoding. +// +// @TODO Handling all encodings inside a single object makes it very difficult +// to reason about this code, so it should be split up in the future. +// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code +// points as used by CESU-8. +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + // Enough space to store all bytes of a single character. UTF-8 needs 4 + // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). + this.charBuffer = new Buffer(6); + // Number of bytes received for the current incomplete multi-byte character. + this.charReceived = 0; + // Number of bytes expected for the current incomplete multi-byte character. + this.charLength = 0; +}; + + +// write decodes the given buffer and returns it as JS string that is +// guaranteed to not contain any partial multi-byte characters. Any partial +// character found at the end of the buffer is buffered up, and will be +// returned when calling write again with the remaining bytes. +// +// Note: Converting a Buffer containing an orphan surrogate to a String +// currently works, but converting a String to a Buffer (via `new Buffer`, or +// Buffer#write) will replace incomplete surrogates with the unicode +// replacement character. See https://codereview.chromium.org/121173009/ . +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var available = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; + + // if there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; + } + + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); + end -= this.charReceived; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + buffer.copy(this.charBuffer, 0, 0, size); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +// detectIncompleteChar determines if there is an incomplete UTF-8 character at +// the end of the given buffer. If so, it sets this.charLength to the byte +// length that character, and sets this.charReceived to the number of bytes +// that are available for this character. +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + this.charReceived = i; +}; + +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 2; + this.charLength = this.charReceived ? 2 : 0; +} + +function base64DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 3; + this.charLength = this.charReceived ? 3 : 0; +} + +},{"35":35}],37:[function(require,module,exports){ +var basex = require(28) +var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' + +module.exports = basex(ALPHABET) + +},{"28":28}],38:[function(require,module,exports){ +/* + Copyright 2013-2014 Daniel Wirtz + + 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. + */ + +/** + * @license bytebuffer.js (c) 2015 Daniel Wirtz + * Backing buffer: ArrayBuffer, Accessor: Uint8Array + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/bytebuffer.js for details + */ +(function(global, factory) { + + /* AMD */ if (typeof define === 'function' && define["amd"]) + define(["long"], factory); + /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"]) + module['exports'] = (function() { + var Long; try { Long = require(68); } catch (e) {} + return factory(Long); + })(); + /* Global */ else + (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]); + +})(this, function(Long) { + "use strict"; + + /** + * Constructs a new ByteBuffer. + * @class The swiss army knife for binary data in JavaScript. + * @exports ByteBuffer + * @constructor + * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}. + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @expose + */ + var ByteBuffer = function(capacity, littleEndian, noAssert) { + if (typeof capacity === 'undefined') + capacity = ByteBuffer.DEFAULT_CAPACITY; + if (typeof littleEndian === 'undefined') + littleEndian = ByteBuffer.DEFAULT_ENDIAN; + if (typeof noAssert === 'undefined') + noAssert = ByteBuffer.DEFAULT_NOASSERT; + if (!noAssert) { + capacity = capacity | 0; + if (capacity < 0) + throw RangeError("Illegal capacity"); + littleEndian = !!littleEndian; + noAssert = !!noAssert; + } + + /** + * Backing ArrayBuffer. + * @type {!ArrayBuffer} + * @expose + */ + this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity); + + /** + * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`. + * @type {?Uint8Array} + * @expose + */ + this.view = capacity === 0 ? null : new Uint8Array(this.buffer); + + /** + * Absolute read/write offset. + * @type {number} + * @expose + * @see ByteBuffer#flip + * @see ByteBuffer#clear + */ + this.offset = 0; + + /** + * Marked offset. + * @type {number} + * @expose + * @see ByteBuffer#mark + * @see ByteBuffer#reset + */ + this.markedOffset = -1; + + /** + * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation. + * @type {number} + * @expose + * @see ByteBuffer#flip + * @see ByteBuffer#clear + */ + this.limit = capacity; + + /** + * Whether to use little endian byte order, defaults to `false` for big endian. + * @type {boolean} + * @expose + */ + this.littleEndian = littleEndian; + + /** + * Whether to skip assertions of offsets and values, defaults to `false`. + * @type {boolean} + * @expose + */ + this.noAssert = noAssert; + }; + + /** + * ByteBuffer version. + * @type {string} + * @const + * @expose + */ + ByteBuffer.VERSION = "5.0.1"; + + /** + * Little endian constant that can be used instead of its boolean value. Evaluates to `true`. + * @type {boolean} + * @const + * @expose + */ + ByteBuffer.LITTLE_ENDIAN = true; + + /** + * Big endian constant that can be used instead of its boolean value. Evaluates to `false`. + * @type {boolean} + * @const + * @expose + */ + ByteBuffer.BIG_ENDIAN = false; + + /** + * Default initial capacity of `16`. + * @type {number} + * @expose + */ + ByteBuffer.DEFAULT_CAPACITY = 16; + + /** + * Default endianess of `false` for big endian. + * @type {boolean} + * @expose + */ + ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN; + + /** + * Default no assertions flag of `false`. + * @type {boolean} + * @expose + */ + ByteBuffer.DEFAULT_NOASSERT = false; + + /** + * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded + * and int64 support is not available. + * @type {?Long} + * @const + * @see https://github.com/dcodeIO/long.js + * @expose + */ + ByteBuffer.Long = Long || null; + + /** + * @alias ByteBuffer.prototype + * @inner + */ + var ByteBufferPrototype = ByteBuffer.prototype; + + /** + * An indicator used to reliably determine if an object is a ByteBuffer or not. + * @type {boolean} + * @const + * @expose + * @private + */ + ByteBufferPrototype.__isByteBuffer__; + + Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", { + value: true, + enumerable: false, + configurable: false + }); + + // helpers + + /** + * @type {!ArrayBuffer} + * @inner + */ + var EMPTY_BUFFER = new ArrayBuffer(0); + + /** + * String.fromCharCode reference for compile-time renaming. + * @type {function(...number):string} + * @inner + */ + var stringFromCharCode = String.fromCharCode; + + /** + * Creates a source function for a string. + * @param {string} s String to read from + * @returns {function():number|null} Source function returning the next char code respectively `null` if there are + * no more characters left. + * @throws {TypeError} If the argument is invalid + * @inner + */ + function stringSource(s) { + var i=0; return function() { + return i < s.length ? s.charCodeAt(i++) : null; + }; + } + + /** + * Creates a destination function for a string. + * @returns {function(number=):undefined|string} Destination function successively called with the next char code. + * Returns the final string when called without arguments. + * @inner + */ + function stringDestination() { + var cs = [], ps = []; return function() { + if (arguments.length === 0) + return ps.join('')+stringFromCharCode.apply(String, cs); + if (cs.length + arguments.length > 1024) + ps.push(stringFromCharCode.apply(String, cs)), + cs.length = 0; + Array.prototype.push.apply(cs, arguments); + }; + } + + /** + * Gets the accessor type. + * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes) + * @expose + */ + ByteBuffer.accessor = function() { + return Uint8Array; + }; + /** + * Allocates a new ByteBuffer backed by a buffer of the specified capacity. + * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}. + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} + * @expose + */ + ByteBuffer.allocate = function(capacity, littleEndian, noAssert) { + return new ByteBuffer(capacity, littleEndian, noAssert); + }; + + /** + * Concatenates multiple ByteBuffers into one. + * @param {!Array.} buffers Buffers to concatenate + * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary", + * defaults to "utf8") + * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults + * to {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} Concatenated ByteBuffer + * @expose + */ + ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) { + if (typeof encoding === 'boolean' || typeof encoding !== 'string') { + noAssert = littleEndian; + littleEndian = encoding; + encoding = undefined; + } + var capacity = 0; + for (var i=0, k=buffers.length, length; i 0) capacity += length; + } + if (capacity === 0) + return new ByteBuffer(0, littleEndian, noAssert); + var bb = new ByteBuffer(capacity, littleEndian, noAssert), + bi; + i=0; while (i} buffer Anything that can be wrapped + * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to + * "utf8") + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer` + * @expose + */ + ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) { + if (typeof encoding !== 'string') { + noAssert = littleEndian; + littleEndian = encoding; + encoding = undefined; + } + if (typeof buffer === 'string') { + if (typeof encoding === 'undefined') + encoding = "utf8"; + switch (encoding) { + case "base64": + return ByteBuffer.fromBase64(buffer, littleEndian); + case "hex": + return ByteBuffer.fromHex(buffer, littleEndian); + case "binary": + return ByteBuffer.fromBinary(buffer, littleEndian); + case "utf8": + return ByteBuffer.fromUTF8(buffer, littleEndian); + case "debug": + return ByteBuffer.fromDebug(buffer, littleEndian); + default: + throw Error("Unsupported encoding: "+encoding); + } + } + if (buffer === null || typeof buffer !== 'object') + throw TypeError("Illegal buffer"); + var bb; + if (ByteBuffer.isByteBuffer(buffer)) { + bb = ByteBufferPrototype.clone.call(buffer); + bb.markedOffset = -1; + return bb; + } + if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array + bb = new ByteBuffer(0, littleEndian, noAssert); + if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER + bb.buffer = buffer.buffer; + bb.offset = buffer.byteOffset; + bb.limit = buffer.byteOffset + buffer.byteLength; + bb.view = new Uint8Array(buffer.buffer); + } + } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer + bb = new ByteBuffer(0, littleEndian, noAssert); + if (buffer.byteLength > 0) { + bb.buffer = buffer; + bb.offset = 0; + bb.limit = buffer.byteLength; + bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null; + } + } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets + bb = new ByteBuffer(buffer.length, littleEndian, noAssert); + bb.limit = buffer.length; + for (var i=0; i} value Array of booleans to write + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. + * @returns {!ByteBuffer} + * @expose + */ + ByteBufferPrototype.writeBitSet = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (!(value instanceof Array)) + throw TypeError("Illegal BitSet: Not an array"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + + var start = offset, + bits = value.length, + bytes = (bits >> 3), + bit = 0, + k; + + offset += this.writeVarint32(bits,offset); + + while(bytes--) { + k = (!!value[bit++] & 1) | + ((!!value[bit++] & 1) << 1) | + ((!!value[bit++] & 1) << 2) | + ((!!value[bit++] & 1) << 3) | + ((!!value[bit++] & 1) << 4) | + ((!!value[bit++] & 1) << 5) | + ((!!value[bit++] & 1) << 6) | + ((!!value[bit++] & 1) << 7); + this.writeByte(k,offset++); + } + + if(bit < bits) { + var m = 0; k = 0; + while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++)); + this.writeByte(k,offset++); + } + + if (relative) { + this.offset = offset; + return this; + } + return offset - start; + } + + /** + * Reads a BitSet as an array of booleans. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. + * @returns {Array + * @expose + */ + ByteBufferPrototype.readBitSet = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + + var ret = this.readVarint32(offset), + bits = ret.value, + bytes = (bits >> 3), + bit = 0, + value = [], + k; + + offset += ret.length; + + while(bytes--) { + k = this.readByte(offset++); + value[bit++] = !!(k & 0x01); + value[bit++] = !!(k & 0x02); + value[bit++] = !!(k & 0x04); + value[bit++] = !!(k & 0x08); + value[bit++] = !!(k & 0x10); + value[bit++] = !!(k & 0x20); + value[bit++] = !!(k & 0x40); + value[bit++] = !!(k & 0x80); + } + + if(bit < bits) { + var m = 0; + k = this.readByte(offset++); + while(bit < bits) value[bit++] = !!((k >> (m++)) & 1); + } + + if (relative) { + this.offset = offset; + } + return value; + } + /** + * Reads the specified number of bytes. + * @param {number} length Number of bytes to read + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. + * @returns {!ByteBuffer} + * @expose + */ + ByteBufferPrototype.readBytes = function(length, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + length > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength); + } + var slice = this.slice(offset, offset + length); + if (relative) this.offset += length; + return slice; + }; + + /** + * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}. + * @function + * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets + * will be modified according to the performed read operation. + * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeBytes = ByteBufferPrototype.append; + + // types/ints/int8 + + /** + * Writes an 8bit signed integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeInt8 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 1; + var capacity0 = this.buffer.byteLength; + if (offset > capacity0) + this.resize((capacity0 *= 2) > offset ? capacity0 : offset); + offset -= 1; + this.view[offset] = value; + if (relative) this.offset += 1; + return this; + }; + + /** + * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8; + + /** + * Reads an 8bit signed integer. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readInt8 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var value = this.view[offset]; + if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed + if (relative) this.offset += 1; + return value; + }; + + /** + * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}. + * @function + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8; + + /** + * Writes an 8bit unsigned integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeUint8 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value >>>= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 1; + var capacity1 = this.buffer.byteLength; + if (offset > capacity1) + this.resize((capacity1 *= 2) > offset ? capacity1 : offset); + offset -= 1; + this.view[offset] = value; + if (relative) this.offset += 1; + return this; + }; + + /** + * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8; + + /** + * Reads an 8bit unsigned integer. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readUint8 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var value = this.view[offset]; + if (relative) this.offset += 1; + return value; + }; + + /** + * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}. + * @function + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8; + + // types/ints/int16 + + /** + * Writes a 16bit signed integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @throws {TypeError} If `offset` or `value` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.writeInt16 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 2; + var capacity2 = this.buffer.byteLength; + if (offset > capacity2) + this.resize((capacity2 *= 2) > offset ? capacity2 : offset); + offset -= 2; + if (this.littleEndian) { + this.view[offset+1] = (value & 0xFF00) >>> 8; + this.view[offset ] = value & 0x00FF; + } else { + this.view[offset] = (value & 0xFF00) >>> 8; + this.view[offset+1] = value & 0x00FF; + } + if (relative) this.offset += 2; + return this; + }; + + /** + * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @throws {TypeError} If `offset` or `value` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16; + + /** + * Reads a 16bit signed integer. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @returns {number} Value read + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.readInt16 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 2 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength); + } + var value = 0; + if (this.littleEndian) { + value = this.view[offset ]; + value |= this.view[offset+1] << 8; + } else { + value = this.view[offset ] << 8; + value |= this.view[offset+1]; + } + if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed + if (relative) this.offset += 2; + return value; + }; + + /** + * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}. + * @function + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @returns {number} Value read + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16; + + /** + * Writes a 16bit unsigned integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @throws {TypeError} If `offset` or `value` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.writeUint16 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value >>>= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 2; + var capacity3 = this.buffer.byteLength; + if (offset > capacity3) + this.resize((capacity3 *= 2) > offset ? capacity3 : offset); + offset -= 2; + if (this.littleEndian) { + this.view[offset+1] = (value & 0xFF00) >>> 8; + this.view[offset ] = value & 0x00FF; + } else { + this.view[offset] = (value & 0xFF00) >>> 8; + this.view[offset+1] = value & 0x00FF; + } + if (relative) this.offset += 2; + return this; + }; + + /** + * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @throws {TypeError} If `offset` or `value` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16; + + /** + * Reads a 16bit unsigned integer. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @returns {number} Value read + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.readUint16 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 2 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength); + } + var value = 0; + if (this.littleEndian) { + value = this.view[offset ]; + value |= this.view[offset+1] << 8; + } else { + value = this.view[offset ] << 8; + value |= this.view[offset+1]; + } + if (relative) this.offset += 2; + return value; + }; + + /** + * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}. + * @function + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @returns {number} Value read + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16; + + // types/ints/int32 + + /** + * Writes a 32bit signed integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @expose + */ + ByteBufferPrototype.writeInt32 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 4; + var capacity4 = this.buffer.byteLength; + if (offset > capacity4) + this.resize((capacity4 *= 2) > offset ? capacity4 : offset); + offset -= 4; + if (this.littleEndian) { + this.view[offset+3] = (value >>> 24) & 0xFF; + this.view[offset+2] = (value >>> 16) & 0xFF; + this.view[offset+1] = (value >>> 8) & 0xFF; + this.view[offset ] = value & 0xFF; + } else { + this.view[offset ] = (value >>> 24) & 0xFF; + this.view[offset+1] = (value >>> 16) & 0xFF; + this.view[offset+2] = (value >>> 8) & 0xFF; + this.view[offset+3] = value & 0xFF; + } + if (relative) this.offset += 4; + return this; + }; + + /** + * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @expose + */ + ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32; + + /** + * Reads a 32bit signed integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readInt32 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 4 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); + } + var value = 0; + if (this.littleEndian) { + value = this.view[offset+2] << 16; + value |= this.view[offset+1] << 8; + value |= this.view[offset ]; + value += this.view[offset+3] << 24 >>> 0; + } else { + value = this.view[offset+1] << 16; + value |= this.view[offset+2] << 8; + value |= this.view[offset+3]; + value += this.view[offset ] << 24 >>> 0; + } + value |= 0; // Cast to signed + if (relative) this.offset += 4; + return value; + }; + + /** + * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32; + + /** + * Writes a 32bit unsigned integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @expose + */ + ByteBufferPrototype.writeUint32 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value >>>= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 4; + var capacity5 = this.buffer.byteLength; + if (offset > capacity5) + this.resize((capacity5 *= 2) > offset ? capacity5 : offset); + offset -= 4; + if (this.littleEndian) { + this.view[offset+3] = (value >>> 24) & 0xFF; + this.view[offset+2] = (value >>> 16) & 0xFF; + this.view[offset+1] = (value >>> 8) & 0xFF; + this.view[offset ] = value & 0xFF; + } else { + this.view[offset ] = (value >>> 24) & 0xFF; + this.view[offset+1] = (value >>> 16) & 0xFF; + this.view[offset+2] = (value >>> 8) & 0xFF; + this.view[offset+3] = value & 0xFF; + } + if (relative) this.offset += 4; + return this; + }; + + /** + * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @expose + */ + ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32; + + /** + * Reads a 32bit unsigned integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readUint32 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 4 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); + } + var value = 0; + if (this.littleEndian) { + value = this.view[offset+2] << 16; + value |= this.view[offset+1] << 8; + value |= this.view[offset ]; + value += this.view[offset+3] << 24 >>> 0; + } else { + value = this.view[offset+1] << 16; + value |= this.view[offset+2] << 8; + value |= this.view[offset+3]; + value += this.view[offset ] << 24 >>> 0; + } + if (relative) this.offset += 4; + return value; + }; + + /** + * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}. + * @function + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32; + + // types/ints/int64 + + if (Long) { + + /** + * Writes a 64bit signed integer. + * @param {number|!Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeInt64 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + else if (!(value && value instanceof Long)) + throw TypeError("Illegal value: "+value+" (not an integer or Long)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + offset += 8; + var capacity6 = this.buffer.byteLength; + if (offset > capacity6) + this.resize((capacity6 *= 2) > offset ? capacity6 : offset); + offset -= 8; + var lo = value.low, + hi = value.high; + if (this.littleEndian) { + this.view[offset+3] = (lo >>> 24) & 0xFF; + this.view[offset+2] = (lo >>> 16) & 0xFF; + this.view[offset+1] = (lo >>> 8) & 0xFF; + this.view[offset ] = lo & 0xFF; + offset += 4; + this.view[offset+3] = (hi >>> 24) & 0xFF; + this.view[offset+2] = (hi >>> 16) & 0xFF; + this.view[offset+1] = (hi >>> 8) & 0xFF; + this.view[offset ] = hi & 0xFF; + } else { + this.view[offset ] = (hi >>> 24) & 0xFF; + this.view[offset+1] = (hi >>> 16) & 0xFF; + this.view[offset+2] = (hi >>> 8) & 0xFF; + this.view[offset+3] = hi & 0xFF; + offset += 4; + this.view[offset ] = (lo >>> 24) & 0xFF; + this.view[offset+1] = (lo >>> 16) & 0xFF; + this.view[offset+2] = (lo >>> 8) & 0xFF; + this.view[offset+3] = lo & 0xFF; + } + if (relative) this.offset += 8; + return this; + }; + + /** + * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}. + * @param {number|!Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64; + + /** + * Reads a 64bit signed integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!Long} + * @expose + */ + ByteBufferPrototype.readInt64 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 8 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); + } + var lo = 0, + hi = 0; + if (this.littleEndian) { + lo = this.view[offset+2] << 16; + lo |= this.view[offset+1] << 8; + lo |= this.view[offset ]; + lo += this.view[offset+3] << 24 >>> 0; + offset += 4; + hi = this.view[offset+2] << 16; + hi |= this.view[offset+1] << 8; + hi |= this.view[offset ]; + hi += this.view[offset+3] << 24 >>> 0; + } else { + hi = this.view[offset+1] << 16; + hi |= this.view[offset+2] << 8; + hi |= this.view[offset+3]; + hi += this.view[offset ] << 24 >>> 0; + offset += 4; + lo = this.view[offset+1] << 16; + lo |= this.view[offset+2] << 8; + lo |= this.view[offset+3]; + lo += this.view[offset ] << 24 >>> 0; + } + var value = new Long(lo, hi, false); + if (relative) this.offset += 8; + return value; + }; + + /** + * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!Long} + * @expose + */ + ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64; + + /** + * Writes a 64bit unsigned integer. + * @param {number|!Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeUint64 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + else if (!(value && value instanceof Long)) + throw TypeError("Illegal value: "+value+" (not an integer or Long)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + offset += 8; + var capacity7 = this.buffer.byteLength; + if (offset > capacity7) + this.resize((capacity7 *= 2) > offset ? capacity7 : offset); + offset -= 8; + var lo = value.low, + hi = value.high; + if (this.littleEndian) { + this.view[offset+3] = (lo >>> 24) & 0xFF; + this.view[offset+2] = (lo >>> 16) & 0xFF; + this.view[offset+1] = (lo >>> 8) & 0xFF; + this.view[offset ] = lo & 0xFF; + offset += 4; + this.view[offset+3] = (hi >>> 24) & 0xFF; + this.view[offset+2] = (hi >>> 16) & 0xFF; + this.view[offset+1] = (hi >>> 8) & 0xFF; + this.view[offset ] = hi & 0xFF; + } else { + this.view[offset ] = (hi >>> 24) & 0xFF; + this.view[offset+1] = (hi >>> 16) & 0xFF; + this.view[offset+2] = (hi >>> 8) & 0xFF; + this.view[offset+3] = hi & 0xFF; + offset += 4; + this.view[offset ] = (lo >>> 24) & 0xFF; + this.view[offset+1] = (lo >>> 16) & 0xFF; + this.view[offset+2] = (lo >>> 8) & 0xFF; + this.view[offset+3] = lo & 0xFF; + } + if (relative) this.offset += 8; + return this; + }; + + /** + * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}. + * @function + * @param {number|!Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64; + + /** + * Reads a 64bit unsigned integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!Long} + * @expose + */ + ByteBufferPrototype.readUint64 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 8 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); + } + var lo = 0, + hi = 0; + if (this.littleEndian) { + lo = this.view[offset+2] << 16; + lo |= this.view[offset+1] << 8; + lo |= this.view[offset ]; + lo += this.view[offset+3] << 24 >>> 0; + offset += 4; + hi = this.view[offset+2] << 16; + hi |= this.view[offset+1] << 8; + hi |= this.view[offset ]; + hi += this.view[offset+3] << 24 >>> 0; + } else { + hi = this.view[offset+1] << 16; + hi |= this.view[offset+2] << 8; + hi |= this.view[offset+3]; + hi += this.view[offset ] << 24 >>> 0; + offset += 4; + lo = this.view[offset+1] << 16; + lo |= this.view[offset+2] << 8; + lo |= this.view[offset+3]; + lo += this.view[offset ] << 24 >>> 0; + } + var value = new Long(lo, hi, true); + if (relative) this.offset += 8; + return value; + }; + + /** + * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}. + * @function + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!Long} + * @expose + */ + ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64; + + } // Long + + + // types/floats/float32 + + /* + ieee754 - https://github.com/feross/ieee754 + + The MIT License (MIT) + + Copyright (c) Feross Aboukhadijeh + + 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. + */ + + /** + * Reads an IEEE754 float from a byte array. + * @param {!Array} buffer + * @param {number} offset + * @param {boolean} isLE + * @param {number} mLen + * @param {number} nBytes + * @returns {number} + * @inner + */ + function ieee754_read(buffer, offset, isLE, mLen, nBytes) { + var e, m, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isLE ? (nBytes - 1) : 0, + d = isLE ? -1 : 1, + s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); + } + + /** + * Writes an IEEE754 float to a byte array. + * @param {!Array} buffer + * @param {number} value + * @param {number} offset + * @param {boolean} isLE + * @param {number} mLen + * @param {number} nBytes + * @inner + */ + function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isLE ? 0 : (nBytes - 1), + d = isLE ? 1 : -1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128; + } + + /** + * Writes a 32bit float. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeFloat32 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number') + throw TypeError("Illegal value: "+value+" (not a number)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 4; + var capacity8 = this.buffer.byteLength; + if (offset > capacity8) + this.resize((capacity8 *= 2) > offset ? capacity8 : offset); + offset -= 4; + ieee754_write(this.view, value, offset, this.littleEndian, 23, 4); + if (relative) this.offset += 4; + return this; + }; + + /** + * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32; + + /** + * Reads a 32bit float. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} + * @expose + */ + ByteBufferPrototype.readFloat32 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 4 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); + } + var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4); + if (relative) this.offset += 4; + return value; + }; + + /** + * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}. + * @function + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} + * @expose + */ + ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32; + + // types/floats/float64 + + /** + * Writes a 64bit float. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeFloat64 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number') + throw TypeError("Illegal value: "+value+" (not a number)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 8; + var capacity9 = this.buffer.byteLength; + if (offset > capacity9) + this.resize((capacity9 *= 2) > offset ? capacity9 : offset); + offset -= 8; + ieee754_write(this.view, value, offset, this.littleEndian, 52, 8); + if (relative) this.offset += 8; + return this; + }; + + /** + * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64; + + /** + * Reads a 64bit float. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {number} + * @expose + */ + ByteBufferPrototype.readFloat64 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 8 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); + } + var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8); + if (relative) this.offset += 8; + return value; + }; + + /** + * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}. + * @function + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {number} + * @expose + */ + ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64; + + + // types/varints/varint32 + + /** + * Maximum number of bytes required to store a 32bit base 128 variable-length integer. + * @type {number} + * @const + * @expose + */ + ByteBuffer.MAX_VARINT32_BYTES = 5; + + /** + * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer. + * @param {number} value Value to encode + * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES} + * @expose + */ + ByteBuffer.calculateVarint32 = function(value) { + // ref: src/google/protobuf/io/coded_stream.cc + value = value >>> 0; + if (value < 1 << 7 ) return 1; + else if (value < 1 << 14) return 2; + else if (value < 1 << 21) return 3; + else if (value < 1 << 28) return 4; + else return 5; + }; + + /** + * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding. + * @param {number} n Signed 32bit integer + * @returns {number} Unsigned zigzag encoded 32bit integer + * @expose + */ + ByteBuffer.zigZagEncode32 = function(n) { + return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h + }; + + /** + * Decodes a zigzag encoded signed 32bit integer. + * @param {number} n Unsigned zigzag encoded 32bit integer + * @returns {number} Signed 32bit integer + * @expose + */ + ByteBuffer.zigZagDecode32 = function(n) { + return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h + }; + + /** + * Writes a 32bit base 128 variable-length integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written + * @expose + */ + ByteBufferPrototype.writeVarint32 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var size = ByteBuffer.calculateVarint32(value), + b; + offset += size; + var capacity10 = this.buffer.byteLength; + if (offset > capacity10) + this.resize((capacity10 *= 2) > offset ? capacity10 : offset); + offset -= size; + value >>>= 0; + while (value >= 0x80) { + b = (value & 0x7f) | 0x80; + this.view[offset++] = b; + value >>>= 7; + } + this.view[offset++] = value; + if (relative) { + this.offset = offset; + return this; + } + return size; + }; + + /** + * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written + * @expose + */ + ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) { + return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset); + }; + + /** + * Reads a 32bit base 128 variable-length integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read + * and the actual number of bytes read. + * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available + * to fully decode the varint. + * @expose + */ + ByteBufferPrototype.readVarint32 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var c = 0, + value = 0 >>> 0, + b; + do { + if (!this.noAssert && offset > this.limit) { + var err = Error("Truncated"); + err['truncated'] = true; + throw err; + } + b = this.view[offset++]; + if (c < 5) + value |= (b & 0x7f) << (7*c); + ++c; + } while ((b & 0x80) !== 0); + value |= 0; + if (relative) { + this.offset = offset; + return value; + } + return { + "value": value, + "length": c + }; + }; + + /** + * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read + * and the actual number of bytes read. + * @throws {Error} If it's not a valid varint + * @expose + */ + ByteBufferPrototype.readVarint32ZigZag = function(offset) { + var val = this.readVarint32(offset); + if (typeof val === 'object') + val["value"] = ByteBuffer.zigZagDecode32(val["value"]); + else + val = ByteBuffer.zigZagDecode32(val); + return val; + }; + + // types/varints/varint64 + + if (Long) { + + /** + * Maximum number of bytes required to store a 64bit base 128 variable-length integer. + * @type {number} + * @const + * @expose + */ + ByteBuffer.MAX_VARINT64_BYTES = 10; + + /** + * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer. + * @param {number|!Long} value Value to encode + * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES} + * @expose + */ + ByteBuffer.calculateVarint64 = function(value) { + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + // ref: src/google/protobuf/io/coded_stream.cc + var part0 = value.toInt() >>> 0, + part1 = value.shiftRightUnsigned(28).toInt() >>> 0, + part2 = value.shiftRightUnsigned(56).toInt() >>> 0; + if (part2 == 0) { + if (part1 == 0) { + if (part0 < 1 << 14) + return part0 < 1 << 7 ? 1 : 2; + else + return part0 < 1 << 21 ? 3 : 4; + } else { + if (part1 < 1 << 14) + return part1 < 1 << 7 ? 5 : 6; + else + return part1 < 1 << 21 ? 7 : 8; + } + } else + return part2 < 1 << 7 ? 9 : 10; + }; + + /** + * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding. + * @param {number|!Long} value Signed long + * @returns {!Long} Unsigned zigzag encoded long + * @expose + */ + ByteBuffer.zigZagEncode64 = function(value) { + if (typeof value === 'number') + value = Long.fromNumber(value, false); + else if (typeof value === 'string') + value = Long.fromString(value, false); + else if (value.unsigned !== false) value = value.toSigned(); + // ref: src/google/protobuf/wire_format_lite.h + return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned(); + }; + + /** + * Decodes a zigzag encoded signed 64bit integer. + * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number + * @returns {!Long} Signed long + * @expose + */ + ByteBuffer.zigZagDecode64 = function(value) { + if (typeof value === 'number') + value = Long.fromNumber(value, false); + else if (typeof value === 'string') + value = Long.fromString(value, false); + else if (value.unsigned !== false) value = value.toSigned(); + // ref: src/google/protobuf/wire_format_lite.h + return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned(); + }; + + /** + * Writes a 64bit base 128 variable-length integer. + * @param {number|Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written. + * @expose + */ + ByteBufferPrototype.writeVarint64 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + else if (!(value && value instanceof Long)) + throw TypeError("Illegal value: "+value+" (not an integer or Long)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (typeof value === 'number') + value = Long.fromNumber(value, false); + else if (typeof value === 'string') + value = Long.fromString(value, false); + else if (value.unsigned !== false) value = value.toSigned(); + var size = ByteBuffer.calculateVarint64(value), + part0 = value.toInt() >>> 0, + part1 = value.shiftRightUnsigned(28).toInt() >>> 0, + part2 = value.shiftRightUnsigned(56).toInt() >>> 0; + offset += size; + var capacity11 = this.buffer.byteLength; + if (offset > capacity11) + this.resize((capacity11 *= 2) > offset ? capacity11 : offset); + offset -= size; + switch (size) { + case 10: this.view[offset+9] = (part2 >>> 7) & 0x01; + case 9 : this.view[offset+8] = size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F; + case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F; + case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F; + case 6 : this.view[offset+5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F; + case 5 : this.view[offset+4] = size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F; + case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F; + case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F; + case 2 : this.view[offset+1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F; + case 1 : this.view[offset ] = size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F; + } + if (relative) { + this.offset += size; + return this; + } else { + return size; + } + }; + + /** + * Writes a zig-zag encoded 64bit base 128 variable-length integer. + * @param {number|Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written. + * @expose + */ + ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) { + return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset); + }; + + /** + * Reads a 64bit base 128 variable-length integer. Requires Long.js. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and + * the actual number of bytes read. + * @throws {Error} If it's not a valid varint + * @expose + */ + ByteBufferPrototype.readVarint64 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + // ref: src/google/protobuf/io/coded_stream.cc + var start = offset, + part0 = 0, + part1 = 0, + part2 = 0, + b = 0; + b = this.view[offset++]; part0 = (b & 0x7F) ; if ( b & 0x80 ) { + b = this.view[offset++]; part0 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part1 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part1 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part2 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part2 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + throw Error("Buffer overrun"); }}}}}}}}}} + var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false); + if (relative) { + this.offset = offset; + return value; + } else { + return { + 'value': value, + 'length': offset-start + }; + } + }; + + /** + * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and + * the actual number of bytes read. + * @throws {Error} If it's not a valid varint + * @expose + */ + ByteBufferPrototype.readVarint64ZigZag = function(offset) { + var val = this.readVarint64(offset); + if (val && val['value'] instanceof Long) + val["value"] = ByteBuffer.zigZagDecode64(val["value"]); + else + val = ByteBuffer.zigZagDecode64(val); + return val; + }; + + } // Long + + + // types/strings/cstring + + /** + * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL + * characters itself. + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * contained in `str` + 1 if omitted. + * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written + * @expose + */ + ByteBufferPrototype.writeCString = function(str, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + var i, + k = str.length; + if (!this.noAssert) { + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + for (i=0; i>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + // UTF8 strings do not contain zero bytes in between except for the zero character, so: + k = utfx.calculateUTF16asUTF8(stringSource(str))[1]; + offset += k+1; + var capacity12 = this.buffer.byteLength; + if (offset > capacity12) + this.resize((capacity12 *= 2) > offset ? capacity12 : offset); + offset -= k+1; + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + this.view[offset++] = b; + }.bind(this)); + this.view[offset++] = 0; + if (relative) { + this.offset = offset; + return this; + } + return k; + }; + + /** + * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters + * itself. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + */ + ByteBufferPrototype.readCString = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var start = offset, + temp; + // UTF8 strings do not contain zero bytes in between except for the zero character itself, so: + var sd, b = -1; + utfx.decodeUTF8toUTF16(function() { + if (b === 0) return null; + if (offset >= this.limit) + throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit); + b = this.view[offset++]; + return b === 0 ? null : b; + }.bind(this), sd = stringDestination(), true); + if (relative) { + this.offset = offset; + return sd(); + } else { + return { + "string": sd(), + "length": offset - start + }; + } + }; + + // types/strings/istring + + /** + * Writes a length as uint32 prefixed UTF8 encoded string. + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written + * @expose + * @see ByteBuffer#writeVarint32 + */ + ByteBufferPrototype.writeIString = function(str, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var start = offset, + k; + k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1]; + offset += 4+k; + var capacity13 = this.buffer.byteLength; + if (offset > capacity13) + this.resize((capacity13 *= 2) > offset ? capacity13 : offset); + offset -= 4+k; + if (this.littleEndian) { + this.view[offset+3] = (k >>> 24) & 0xFF; + this.view[offset+2] = (k >>> 16) & 0xFF; + this.view[offset+1] = (k >>> 8) & 0xFF; + this.view[offset ] = k & 0xFF; + } else { + this.view[offset ] = (k >>> 24) & 0xFF; + this.view[offset+1] = (k >>> 16) & 0xFF; + this.view[offset+2] = (k >>> 8) & 0xFF; + this.view[offset+3] = k & 0xFF; + } + offset += 4; + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + this.view[offset++] = b; + }.bind(this)); + if (offset !== start + 4 + k) + throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k)); + if (relative) { + this.offset = offset; + return this; + } + return offset - start; + }; + + /** + * Reads a length as uint32 prefixed UTF8 encoded string. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + * @see ByteBuffer#readVarint32 + */ + ByteBufferPrototype.readIString = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 4 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); + } + var start = offset; + var len = this.readUint32(offset); + var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4); + offset += str['length']; + if (relative) { + this.offset = offset; + return str['string']; + } else { + return { + 'string': str['string'], + 'length': offset - start + }; + } + }; + + // types/strings/utf8string + + /** + * Metrics representing number of UTF8 characters. Evaluates to `c`. + * @type {string} + * @const + * @expose + */ + ByteBuffer.METRICS_CHARS = 'c'; + + /** + * Metrics representing number of bytes. Evaluates to `b`. + * @type {string} + * @const + * @expose + */ + ByteBuffer.METRICS_BYTES = 'b'; + + /** + * Writes an UTF8 encoded string. + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. + * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. + * @expose + */ + ByteBufferPrototype.writeUTF8String = function(str, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var k; + var start = offset; + k = utfx.calculateUTF16asUTF8(stringSource(str))[1]; + offset += k; + var capacity14 = this.buffer.byteLength; + if (offset > capacity14) + this.resize((capacity14 *= 2) > offset ? capacity14 : offset); + offset -= k; + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + this.view[offset++] = b; + }.bind(this)); + if (relative) { + this.offset = offset; + return this; + } + return offset - start; + }; + + /** + * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}. + * @function + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. + * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. + * @expose + */ + ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String; + + /** + * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's + * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF. + * @param {string} str String to calculate + * @returns {number} Number of UTF8 characters + * @expose + */ + ByteBuffer.calculateUTF8Chars = function(str) { + return utfx.calculateUTF16asUTF8(stringSource(str))[0]; + }; + + /** + * Calculates the number of UTF8 bytes of a string. + * @param {string} str String to calculate + * @returns {number} Number of UTF8 bytes + * @expose + */ + ByteBuffer.calculateUTF8Bytes = function(str) { + return utfx.calculateUTF16asUTF8(stringSource(str))[1]; + }; + + /** + * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}. + * @function + * @param {string} str String to calculate + * @returns {number} Number of UTF8 bytes + * @expose + */ + ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes; + + /** + * Reads an UTF8 encoded string. + * @param {number} length Number of characters or bytes to read. + * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to + * {@link ByteBuffer.METRICS_CHARS}. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + */ + ByteBufferPrototype.readUTF8String = function(length, metrics, offset) { + if (typeof metrics === 'number') { + offset = metrics; + metrics = undefined; + } + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS; + if (!this.noAssert) { + if (typeof length !== 'number' || length % 1 !== 0) + throw TypeError("Illegal length: "+length+" (not an integer)"); + length |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var i = 0, + start = offset, + sd; + if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser + sd = stringDestination(); + utfx.decodeUTF8(function() { + return i < length && offset < this.limit ? this.view[offset++] : null; + }.bind(this), function(cp) { + ++i; utfx.UTF8toUTF16(cp, sd); + }); + if (i !== length) + throw RangeError("Illegal range: Truncated data, "+i+" == "+length); + if (relative) { + this.offset = offset; + return sd(); + } else { + return { + "string": sd(), + "length": offset - start + }; + } + } else if (metrics === ByteBuffer.METRICS_BYTES) { + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + length > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength); + } + var k = offset + length; + utfx.decodeUTF8toUTF16(function() { + return offset < k ? this.view[offset++] : null; + }.bind(this), sd = stringDestination(), this.noAssert); + if (offset !== k) + throw RangeError("Illegal range: Truncated data, "+offset+" == "+k); + if (relative) { + this.offset = offset; + return sd(); + } else { + return { + 'string': sd(), + 'length': offset - start + }; + } + } else + throw TypeError("Unsupported metrics: "+metrics); + }; + + /** + * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}. + * @function + * @param {number} length Number of characters or bytes to read + * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to + * {@link ByteBuffer.METRICS_CHARS}. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + */ + ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String; + + // types/strings/vstring + + /** + * Writes a length as varint32 prefixed UTF8 encoded string. + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written + * @expose + * @see ByteBuffer#writeVarint32 + */ + ByteBufferPrototype.writeVString = function(str, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var start = offset, + k, l; + k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1]; + l = ByteBuffer.calculateVarint32(k); + offset += l+k; + var capacity15 = this.buffer.byteLength; + if (offset > capacity15) + this.resize((capacity15 *= 2) > offset ? capacity15 : offset); + offset -= l+k; + offset += this.writeVarint32(k, offset); + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + this.view[offset++] = b; + }.bind(this)); + if (offset !== start+k+l) + throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l)); + if (relative) { + this.offset = offset; + return this; + } + return offset - start; + }; + + /** + * Reads a length as varint32 prefixed UTF8 encoded string. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + * @see ByteBuffer#readVarint32 + */ + ByteBufferPrototype.readVString = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var start = offset; + var len = this.readVarint32(offset); + var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']); + offset += str['length']; + if (relative) { + this.offset = offset; + return str['string']; + } else { + return { + 'string': str['string'], + 'length': offset - start + }; + } + }; + + + /** + * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended + * data's length. + * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets + * will be modified according to the performed read operation. + * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") + * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer} this + * @expose + * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|` + * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|` + */ + ByteBufferPrototype.append = function(source, encoding, offset) { + if (typeof encoding === 'number' || typeof encoding !== 'string') { + offset = encoding; + encoding = undefined; + } + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (!(source instanceof ByteBuffer)) + source = ByteBuffer.wrap(source, encoding); + var length = source.limit - source.offset; + if (length <= 0) return this; // Nothing to append + offset += length; + var capacity16 = this.buffer.byteLength; + if (offset > capacity16) + this.resize((capacity16 *= 2) > offset ? capacity16 : offset); + offset -= length; + this.view.set(source.view.subarray(source.offset, source.limit), offset); + source.offset += length; + if (relative) this.offset += length; + return this; + }; + + /** + * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the + specified offset up to the length of this ByteBuffer's data. + * @param {!ByteBuffer} target Target ByteBuffer + * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {!ByteBuffer} this + * @expose + * @see ByteBuffer#append + */ + ByteBufferPrototype.appendTo = function(target, offset) { + target.append(this, offset); + return this; + }; + + /** + * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to + * disable them if your code already makes sure that everything is valid. + * @param {boolean} assert `true` to enable assertions, otherwise `false` + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.assert = function(assert) { + this.noAssert = !assert; + return this; + }; + + /** + * Gets the capacity of this ByteBuffer's backing buffer. + * @returns {number} Capacity of the backing buffer + * @expose + */ + ByteBufferPrototype.capacity = function() { + return this.buffer.byteLength; + }; + /** + * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the + * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.clear = function() { + this.offset = 0; + this.limit = this.buffer.byteLength; + this.markedOffset = -1; + return this; + }; + + /** + * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset}, + * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}. + * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false` + * @returns {!ByteBuffer} Cloned instance + * @expose + */ + ByteBufferPrototype.clone = function(copy) { + var bb = new ByteBuffer(0, this.littleEndian, this.noAssert); + if (copy) { + bb.buffer = new ArrayBuffer(this.buffer.byteLength); + bb.view = new Uint8Array(bb.buffer); + } else { + bb.buffer = this.buffer; + bb.view = this.view; + } + bb.offset = this.offset; + bb.markedOffset = this.markedOffset; + bb.limit = this.limit; + return bb; + }; + + /** + * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes + * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and + * adapt {@link ByteBuffer#markedOffset} to the same relative position if set. + * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset} + * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.compact = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + if (begin === 0 && end === this.buffer.byteLength) + return this; // Already compacted + var len = end - begin; + if (len === 0) { + this.buffer = EMPTY_BUFFER; + this.view = null; + if (this.markedOffset >= 0) this.markedOffset -= begin; + this.offset = 0; + this.limit = 0; + return this; + } + var buffer = new ArrayBuffer(len); + var view = new Uint8Array(buffer); + view.set(this.view.subarray(begin, end)); + this.buffer = buffer; + this.view = view; + if (this.markedOffset >= 0) this.markedOffset -= begin; + this.offset = 0; + this.limit = len; + return this; + }; + + /** + * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and + * {@link ByteBuffer#limit}. + * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}. + * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. + * @returns {!ByteBuffer} Copy + * @expose + */ + ByteBufferPrototype.copy = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + if (begin === end) + return new ByteBuffer(0, this.littleEndian, this.noAssert); + var capacity = end - begin, + bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert); + bb.offset = 0; + bb.limit = capacity; + if (bb.markedOffset >= 0) bb.markedOffset -= begin; + this.copyTo(bb, 0, begin, end); + return bb; + }; + + /** + * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and + * {@link ByteBuffer#limit}. + * @param {!ByteBuffer} target Target ByteBuffer + * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset} + * by the number of bytes copied if omitted. + * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the + * number of bytes copied if omitted. + * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit} + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) { + var relative, + targetRelative; + if (!this.noAssert) { + if (!ByteBuffer.isByteBuffer(target)) + throw TypeError("Illegal target: Not a ByteBuffer"); + } + targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0; + sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0; + sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0; + + if (targetOffset < 0 || targetOffset > target.buffer.byteLength) + throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength); + if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength) + throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength); + + var len = sourceLimit - sourceOffset; + if (len === 0) + return target; // Nothing to copy + + target.ensureCapacity(targetOffset + len); + + target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset); + + if (relative) this.offset += len; + if (targetRelative) target.offset += len; + + return this; + }; + + /** + * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the + * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity, + * the required capacity will be used instead. + * @param {number} capacity Required capacity + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.ensureCapacity = function(capacity) { + var current = this.buffer.byteLength; + if (current < capacity) + return this.resize((current *= 2) > capacity ? current : capacity); + return this; + }; + + /** + * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between + * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. + * @param {number|string} value Byte value to fill with. If given as a string, the first character is used. + * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. defaults to {@link ByteBuffer#offset}. + * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. + * @returns {!ByteBuffer} this + * @expose + * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes + */ + ByteBufferPrototype.fill = function(value, begin, end) { + var relative = typeof begin === 'undefined'; + if (relative) begin = this.offset; + if (typeof value === 'string' && value.length > 0) + value = value.charCodeAt(0); + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + if (begin >= end) + return this; // Nothing to fill + while (begin < end) this.view[begin++] = value; + if (relative) this.offset = begin; + return this; + }; + + /** + * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and + * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.flip = function() { + this.limit = this.offset; + this.offset = 0; + return this; + }; + /** + * Marks an offset on this ByteBuffer to be used later. + * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}. + * @returns {!ByteBuffer} this + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @see ByteBuffer#reset + * @expose + */ + ByteBufferPrototype.mark = function(offset) { + offset = typeof offset === 'undefined' ? this.offset : offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + this.markedOffset = offset; + return this; + }; + /** + * Sets the byte order. + * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.order = function(littleEndian) { + if (!this.noAssert) { + if (typeof littleEndian !== 'boolean') + throw TypeError("Illegal littleEndian: Not a boolean"); + } + this.littleEndian = !!littleEndian; + return this; + }; + + /** + * Switches (to) little endian byte order. + * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.LE = function(littleEndian) { + this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true; + return this; + }; + + /** + * Switches (to) big endian byte order. + * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.BE = function(bigEndian) { + this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false; + return this; + }; + /** + * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the + * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer + * will be resized and its contents moved accordingly. + * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be + * modified according to the performed read operation. + * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") + * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes + * prepended if omitted. + * @returns {!ByteBuffer} this + * @expose + * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|` + * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|` + */ + ByteBufferPrototype.prepend = function(source, encoding, offset) { + if (typeof encoding === 'number' || typeof encoding !== 'string') { + offset = encoding; + encoding = undefined; + } + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (!(source instanceof ByteBuffer)) + source = ByteBuffer.wrap(source, encoding); + var len = source.limit - source.offset; + if (len <= 0) return this; // Nothing to prepend + var diff = len - offset; + if (diff > 0) { // Not enough space before offset, so resize + move + var buffer = new ArrayBuffer(this.buffer.byteLength + diff); + var view = new Uint8Array(buffer); + view.set(this.view.subarray(offset, this.buffer.byteLength), len); + this.buffer = buffer; + this.view = view; + this.offset += diff; + if (this.markedOffset >= 0) this.markedOffset += diff; + this.limit += diff; + offset += diff; + } else { + var arrayView = new Uint8Array(this.buffer); + } + this.view.set(source.view.subarray(source.offset, source.limit), offset - len); + + source.offset = source.limit; + if (relative) + this.offset -= len; + return this; + }; + + /** + * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the + * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer + * will be resized and its contents moved accordingly. + * @param {!ByteBuffer} target Target ByteBuffer + * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes + * prepended if omitted. + * @returns {!ByteBuffer} this + * @expose + * @see ByteBuffer#prepend + */ + ByteBufferPrototype.prependTo = function(target, offset) { + target.prepend(this, offset); + return this; + }; + /** + * Prints debug information about this ByteBuffer's contents. + * @param {function(string)=} out Output function to call, defaults to console.log + * @expose + */ + ByteBufferPrototype.printDebug = function(out) { + if (typeof out !== 'function') out = console.log.bind(console); + out( + this.toString()+"\n"+ + "-------------------------------------------------------------------\n"+ + this.toDebug(/* columns */ true) + ); + }; + + /** + * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and + * {@link ByteBuffer#limit}, so this returns `limit - offset`. + * @returns {number} Remaining readable bytes. May be negative if `offset > limit`. + * @expose + */ + ByteBufferPrototype.remaining = function() { + return this.limit - this.offset; + }; + /** + * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark} + * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been + * marked, sets `offset = 0`. + * @returns {!ByteBuffer} this + * @see ByteBuffer#mark + * @expose + */ + ByteBufferPrototype.reset = function() { + if (this.markedOffset >= 0) { + this.offset = this.markedOffset; + this.markedOffset = -1; + } else { + this.offset = 0; + } + return this; + }; + /** + * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that + * large or larger. + * @param {number} capacity Capacity required + * @returns {!ByteBuffer} this + * @throws {TypeError} If `capacity` is not a number + * @throws {RangeError} If `capacity < 0` + * @expose + */ + ByteBufferPrototype.resize = function(capacity) { + if (!this.noAssert) { + if (typeof capacity !== 'number' || capacity % 1 !== 0) + throw TypeError("Illegal capacity: "+capacity+" (not an integer)"); + capacity |= 0; + if (capacity < 0) + throw RangeError("Illegal capacity: 0 <= "+capacity); + } + if (this.buffer.byteLength < capacity) { + var buffer = new ArrayBuffer(capacity); + var view = new Uint8Array(buffer); + view.set(this.view); + this.buffer = buffer; + this.view = view; + } + return this; + }; + /** + * Reverses this ByteBuffer's contents. + * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset} + * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.reverse = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + if (begin === end) + return this; // Nothing to reverse + Array.prototype.reverse.call(this.view.subarray(begin, end)); + return this; + }; + /** + * Skips the next `length` bytes. This will just advance + * @param {number} length Number of bytes to skip. May also be negative to move the offset back. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.skip = function(length) { + if (!this.noAssert) { + if (typeof length !== 'number' || length % 1 !== 0) + throw TypeError("Illegal length: "+length+" (not an integer)"); + length |= 0; + } + var offset = this.offset + length; + if (!this.noAssert) { + if (offset < 0 || offset > this.buffer.byteLength) + throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength); + } + this.offset = offset; + return this; + }; + + /** + * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`. + * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}. + * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. + * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer} + * @expose + */ + ByteBufferPrototype.slice = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + var bb = this.clone(); + bb.offset = begin; + bb.limit = end; + return bb; + }; + /** + * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between + * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. + * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if + * possible. Defaults to `false` + * @returns {!ArrayBuffer} Contents as an ArrayBuffer + * @expose + */ + ByteBufferPrototype.toBuffer = function(forceCopy) { + var offset = this.offset, + limit = this.limit; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: Not an integer"); + offset >>>= 0; + if (typeof limit !== 'number' || limit % 1 !== 0) + throw TypeError("Illegal limit: Not an integer"); + limit >>>= 0; + if (offset < 0 || offset > limit || limit > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength); + } + // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is + // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So: + if (!forceCopy && offset === 0 && limit === this.buffer.byteLength) + return this.buffer; + if (offset === limit) + return EMPTY_BUFFER; + var buffer = new ArrayBuffer(limit - offset); + new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0); + return buffer; + }; + + /** + * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between + * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}. + * @function + * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory. + * Defaults to `false` + * @returns {!ArrayBuffer} Contents as an ArrayBuffer + * @expose + */ + ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer; + + /** + * Converts the ByteBuffer's contents to a string. + * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows + * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with + * highlighted offsets. + * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset} + * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} + * @returns {string} String representation + * @throws {Error} If `encoding` is invalid + * @expose + */ + ByteBufferPrototype.toString = function(encoding, begin, end) { + if (typeof encoding === 'undefined') + return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")"; + if (typeof encoding === 'number') + encoding = "utf8", + begin = encoding, + end = begin; + switch (encoding) { + case "utf8": + return this.toUTF8(begin, end); + case "base64": + return this.toBase64(begin, end); + case "hex": + return this.toHex(begin, end); + case "binary": + return this.toBinary(begin, end); + case "debug": + return this.toDebug(); + case "columns": + return this.toColumns(); + default: + throw Error("Unsupported encoding: "+encoding); + } + }; + + // lxiv-embeddable + + /** + * lxiv-embeddable (c) 2014 Daniel Wirtz + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/lxiv for details + */ + var lxiv = function() { + "use strict"; + + /** + * lxiv namespace. + * @type {!Object.} + * @exports lxiv + */ + var lxiv = {}; + + /** + * Character codes for output. + * @type {!Array.} + * @inner + */ + var aout = [ + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 + ]; + + /** + * Character codes for input. + * @type {!Array.} + * @inner + */ + var ain = []; + for (var i=0, k=aout.length; i>2)&0x3f]); + t = (b&0x3)<<4; + if ((b = src()) !== null) { + t |= (b>>4)&0xf; + dst(aout[(t|((b>>4)&0xf))&0x3f]); + t = (b&0xf)<<2; + if ((b = src()) !== null) + dst(aout[(t|((b>>6)&0x3))&0x3f]), + dst(aout[b&0x3f]); + else + dst(aout[t&0x3f]), + dst(61); + } else + dst(aout[t&0x3f]), + dst(61), + dst(61); + } + }; + + /** + * Decodes base64 char codes to bytes. + * @param {!function():number|null} src Characters source as a function returning the next char code respectively + * `null` if there are no more characters left. + * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. + * @throws {Error} If a character code is invalid + */ + lxiv.decode = function(src, dst) { + var c, t1, t2; + function fail(c) { + throw Error("Illegal character code: "+c); + } + while ((c = src()) !== null) { + t1 = ain[c]; + if (typeof t1 === 'undefined') fail(c); + if ((c = src()) !== null) { + t2 = ain[c]; + if (typeof t2 === 'undefined') fail(c); + dst((t1<<2)>>>0|(t2&0x30)>>4); + if ((c = src()) !== null) { + t1 = ain[c]; + if (typeof t1 === 'undefined') + if (c === 61) break; else fail(c); + dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2); + if ((c = src()) !== null) { + t2 = ain[c]; + if (typeof t2 === 'undefined') + if (c === 61) break; else fail(c); + dst(((t1&0x3)<<6)>>>0|t2); + } + } + } + } + }; + + /** + * Tests if a string is valid base64. + * @param {string} str String to test + * @returns {boolean} `true` if valid, otherwise `false` + */ + lxiv.test = function(str) { + return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str); + }; + + return lxiv; + }(); + + // encodings/base64 + + /** + * Encodes this ByteBuffer's contents to a base64 encoded string. + * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}. + * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}. + * @returns {string} Base64 encoded string + * @throws {RangeError} If `begin` or `end` is out of bounds + * @expose + */ + ByteBufferPrototype.toBase64 = function(begin, end) { + if (typeof begin === 'undefined') + begin = this.offset; + if (typeof end === 'undefined') + end = this.limit; + begin = begin | 0; end = end | 0; + if (begin < 0 || end > this.capacity || begin > end) + throw RangeError("begin, end"); + var sd; lxiv.encode(function() { + return begin < end ? this.view[begin++] : null; + }.bind(this), sd = stringDestination()); + return sd(); + }; + + /** + * Decodes a base64 encoded string to a ByteBuffer. + * @param {string} str String to decode + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + */ + ByteBuffer.fromBase64 = function(str, littleEndian) { + if (typeof str !== 'string') + throw TypeError("str"); + var bb = new ByteBuffer(str.length/4*3, littleEndian), + i = 0; + lxiv.decode(stringSource(str), function(b) { + bb.view[i++] = b; + }); + bb.limit = i; + return bb; + }; + + /** + * Encodes a binary string to base64 like `window.btoa` does. + * @param {string} str Binary string + * @returns {string} Base64 encoded string + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa + * @expose + */ + ByteBuffer.btoa = function(str) { + return ByteBuffer.fromBinary(str).toBase64(); + }; + + /** + * Decodes a base64 encoded string to binary like `window.atob` does. + * @param {string} b64 Base64 encoded string + * @returns {string} Binary string + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob + * @expose + */ + ByteBuffer.atob = function(b64) { + return ByteBuffer.fromBase64(b64).toBinary(); + }; + + // encodings/binary + + /** + * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes. + * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}. + * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}. + * @returns {string} Binary encoded string + * @throws {RangeError} If `offset > limit` + * @expose + */ + ByteBufferPrototype.toBinary = function(begin, end) { + if (typeof begin === 'undefined') + begin = this.offset; + if (typeof end === 'undefined') + end = this.limit; + begin |= 0; end |= 0; + if (begin < 0 || end > this.capacity() || begin > end) + throw RangeError("begin, end"); + if (begin === end) + return ""; + var chars = [], + parts = []; + while (begin < end) { + chars.push(this.view[begin++]); + if (chars.length >= 1024) + parts.push(String.fromCharCode.apply(String, chars)), + chars = []; + } + return parts.join('') + String.fromCharCode.apply(String, chars); + }; + + /** + * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer. + * @param {string} str String to decode + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + */ + ByteBuffer.fromBinary = function(str, littleEndian) { + if (typeof str !== 'string') + throw TypeError("str"); + var i = 0, + k = str.length, + charCode, + bb = new ByteBuffer(k, littleEndian); + while (i 0xff) + throw RangeError("illegal char code: "+charCode); + bb.view[i++] = charCode; + } + bb.limit = k; + return bb; + }; + + // encodings/debug + + /** + * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are: + * * `<` : offset, + * * `'` : markedOffset, + * * `>` : limit, + * * `|` : offset and limit, + * * `[` : offset and markedOffset, + * * `]` : markedOffset and limit, + * * `!` : offset, markedOffset and limit + * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false` + * @returns {string|!Array.} Debug string or array of lines if `asArray = true` + * @expose + * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3` + * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4` + * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1` + * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1` + */ + ByteBufferPrototype.toDebug = function(columns) { + var i = -1, + k = this.buffer.byteLength, + b, + hex = "", + asc = "", + out = ""; + while (i 32 && b < 127 ? String.fromCharCode(b) : '.'; + } + ++i; + if (columns) { + if (i > 0 && i % 16 === 0 && i !== k) { + while (hex.length < 3*16+3) hex += " "; + out += hex+asc+"\n"; + hex = asc = ""; + } + } + if (i === this.offset && i === this.limit) + hex += i === this.markedOffset ? "!" : "|"; + else if (i === this.offset) + hex += i === this.markedOffset ? "[" : "<"; + else if (i === this.limit) + hex += i === this.markedOffset ? "]" : ">"; + else + hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : ""); + } + if (columns && hex !== " ") { + while (hex.length < 3*16+3) + hex += " "; + out += hex + asc + "\n"; + } + return columns ? out : hex; + }; + + /** + * Decodes a hex encoded string with marked offsets to a ByteBuffer. + * @param {string} str Debug string to decode (not be generated with `columns = true`) + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + * @see ByteBuffer#toDebug + */ + ByteBuffer.fromDebug = function(str, littleEndian, noAssert) { + var k = str.length, + bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert); + var i = 0, j = 0, ch, b, + rs = false, // Require symbol next + ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)? + fail = false; + while (i': + if (!noAssert) { + if (hl) { + fail = true; + break; + } + hl = true; + } + bb.limit = j; + rs = false; + break; + case "'": + if (!noAssert) { + if (hm) { + fail = true; + break; + } + hm = true; + } + bb.markedOffset = j; + rs = false; + break; + case ' ': + rs = false; + break; + default: + if (!noAssert) { + if (rs) { + fail = true; + break; + } + } + b = parseInt(ch+str.charAt(i++), 16); + if (!noAssert) { + if (isNaN(b) || b < 0 || b > 255) + throw TypeError("Illegal str: Not a debug encoded string"); + } + bb.view[j++] = b; + rs = true; + } + if (fail) + throw TypeError("Illegal str: Invalid symbol at "+i); + } + if (!noAssert) { + if (!ho || !hl) + throw TypeError("Illegal str: Missing offset or limit"); + if (j>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + var out = new Array(end - begin), + b; + while (begin < end) { + b = this.view[begin++]; + if (b < 0x10) + out.push("0", b.toString(16)); + else out.push(b.toString(16)); + } + return out.join(''); + }; + + /** + * Decodes a hex encoded string to a ByteBuffer. + * @param {string} str String to decode + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + */ + ByteBuffer.fromHex = function(str, littleEndian, noAssert) { + if (!noAssert) { + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + if (str.length % 2 !== 0) + throw TypeError("Illegal str: Length not a multiple of 2"); + } + var k = str.length, + bb = new ByteBuffer((k / 2) | 0, littleEndian), + b; + for (var i=0, j=0; i 255) + throw TypeError("Illegal str: Contains non-hex characters"); + bb.view[j++] = b; + } + bb.limit = j; + return bb; + }; + + // utfx-embeddable + + /** + * utfx-embeddable (c) 2014 Daniel Wirtz + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/utfx for details + */ + var utfx = function() { + "use strict"; + + /** + * utfx namespace. + * @inner + * @type {!Object.} + */ + var utfx = {}; + + /** + * Maximum valid code point. + * @type {number} + * @const + */ + utfx.MAX_CODEPOINT = 0x10FFFF; + + /** + * Encodes UTF8 code points to UTF8 bytes. + * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point + * respectively `null` if there are no more code points left or a single numeric code point. + * @param {!function(number)} dst Bytes destination as a function successively called with the next byte + */ + utfx.encodeUTF8 = function(src, dst) { + var cp = null; + if (typeof src === 'number') + cp = src, + src = function() { return null; }; + while (cp !== null || (cp = src()) !== null) { + if (cp < 0x80) + dst(cp&0x7F); + else if (cp < 0x800) + dst(((cp>>6)&0x1F)|0xC0), + dst((cp&0x3F)|0x80); + else if (cp < 0x10000) + dst(((cp>>12)&0x0F)|0xE0), + dst(((cp>>6)&0x3F)|0x80), + dst((cp&0x3F)|0x80); + else + dst(((cp>>18)&0x07)|0xF0), + dst(((cp>>12)&0x3F)|0x80), + dst(((cp>>6)&0x3F)|0x80), + dst((cp&0x3F)|0x80); + cp = null; + } + }; + + /** + * Decodes UTF8 bytes to UTF8 code points. + * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there + * are no more bytes left. + * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point. + * @throws {RangeError} If a starting byte is invalid in UTF8 + * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the + * remaining bytes. + */ + utfx.decodeUTF8 = function(src, dst) { + var a, b, c, d, fail = function(b) { + b = b.slice(0, b.indexOf(null)); + var err = Error(b.toString()); + err.name = "TruncatedError"; + err['bytes'] = b; + throw err; + }; + while ((a = src()) !== null) { + if ((a&0x80) === 0) + dst(a); + else if ((a&0xE0) === 0xC0) + ((b = src()) === null) && fail([a, b]), + dst(((a&0x1F)<<6) | (b&0x3F)); + else if ((a&0xF0) === 0xE0) + ((b=src()) === null || (c=src()) === null) && fail([a, b, c]), + dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F)); + else if ((a&0xF8) === 0xF0) + ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]), + dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F)); + else throw RangeError("Illegal starting byte: "+a); + } + }; + + /** + * Converts UTF16 characters to UTF8 code points. + * @param {!function():number|null} src Characters source as a function returning the next char code respectively + * `null` if there are no more characters left. + * @param {!function(number)} dst Code points destination as a function successively called with each converted code + * point. + */ + utfx.UTF16toUTF8 = function(src, dst) { + var c1, c2 = null; + while (true) { + if ((c1 = c2 !== null ? c2 : src()) === null) + break; + if (c1 >= 0xD800 && c1 <= 0xDFFF) { + if ((c2 = src()) !== null) { + if (c2 >= 0xDC00 && c2 <= 0xDFFF) { + dst((c1-0xD800)*0x400+c2-0xDC00+0x10000); + c2 = null; continue; + } + } + } + dst(c1); + } + if (c2 !== null) dst(c2); + }; + + /** + * Converts UTF8 code points to UTF16 characters. + * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point + * respectively `null` if there are no more code points left or a single numeric code point. + * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. + * @throws {RangeError} If a code point is out of range + */ + utfx.UTF8toUTF16 = function(src, dst) { + var cp = null; + if (typeof src === 'number') + cp = src, src = function() { return null; }; + while (cp !== null || (cp = src()) !== null) { + if (cp <= 0xFFFF) + dst(cp); + else + cp -= 0x10000, + dst((cp>>10)+0xD800), + dst((cp%0x400)+0xDC00); + cp = null; + } + }; + + /** + * Converts and encodes UTF16 characters to UTF8 bytes. + * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null` + * if there are no more characters left. + * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. + */ + utfx.encodeUTF16toUTF8 = function(src, dst) { + utfx.UTF16toUTF8(src, function(cp) { + utfx.encodeUTF8(cp, dst); + }); + }; + + /** + * Decodes and converts UTF8 bytes to UTF16 characters. + * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there + * are no more bytes left. + * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. + * @throws {RangeError} If a starting byte is invalid in UTF8 + * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes. + */ + utfx.decodeUTF8toUTF16 = function(src, dst) { + utfx.decodeUTF8(src, function(cp) { + utfx.UTF8toUTF16(cp, dst); + }); + }; + + /** + * Calculates the byte length of an UTF8 code point. + * @param {number} cp UTF8 code point + * @returns {number} Byte length + */ + utfx.calculateCodePoint = function(cp) { + return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; + }; + + /** + * Calculates the number of UTF8 bytes required to store UTF8 code points. + * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively + * `null` if there are no more code points left. + * @returns {number} The number of UTF8 bytes required + */ + utfx.calculateUTF8 = function(src) { + var cp, l=0; + while ((cp = src()) !== null) + l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; + return l; + }; + + /** + * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes. + * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively + * `null` if there are no more characters left. + * @returns {!Array.} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1. + */ + utfx.calculateUTF16asUTF8 = function(src) { + var n=0, l=0; + utfx.UTF16toUTF8(src, function(cp) { + ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; + }); + return [n,l]; + }; + + return utfx; + }(); + + // encodings/utf8 + + /** + * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded + * string. + * @returns {string} Hex encoded string + * @throws {RangeError} If `offset > limit` + * @expose + */ + ByteBufferPrototype.toUTF8 = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + var sd; try { + utfx.decodeUTF8toUTF16(function() { + return begin < end ? this.view[begin++] : null; + }.bind(this), sd = stringDestination()); + } catch (e) { + if (begin !== end) + throw RangeError("Illegal range: Truncated data, "+begin+" != "+end); + } + return sd(); + }; + + /** + * Decodes an UTF8 encoded string to a ByteBuffer. + * @param {string} str String to decode + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + */ + ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) { + if (!noAssert) + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert), + i = 0; + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + bb.view[i++] = b; + }); + bb.limit = i; + return bb; + }; + + return ByteBuffer; +}); + +},{"68":68}],39:[function(require,module,exports){ +var Buffer = require(93).Buffer +var Transform = require(103).Transform +var StringDecoder = require(36).StringDecoder +var inherits = require(65) + +function CipherBase (hashMode) { + Transform.call(this) + this.hashMode = typeof hashMode === 'string' + if (this.hashMode) { + this[hashMode] = this._finalOrDigest + } else { + this.final = this._finalOrDigest + } + if (this._final) { + this.__final = this._final + this._final = null + } + this._decoder = null + this._encoding = null +} +inherits(CipherBase, Transform) + +CipherBase.prototype.update = function (data, inputEnc, outputEnc) { + if (typeof data === 'string') { + data = Buffer.from(data, inputEnc) + } + + var outData = this._update(data) + if (this.hashMode) return this + + if (outputEnc) { + outData = this._toString(outData, outputEnc) + } + + return outData +} + +CipherBase.prototype.setAutoPadding = function () {} +CipherBase.prototype.getAuthTag = function () { + throw new Error('trying to get auth tag in unsupported state') +} + +CipherBase.prototype.setAuthTag = function () { + throw new Error('trying to set auth tag in unsupported state') +} + +CipherBase.prototype.setAAD = function () { + throw new Error('trying to set aad in unsupported state') +} + +CipherBase.prototype._transform = function (data, _, next) { + var err + try { + if (this.hashMode) { + this._update(data) + } else { + this.push(this._update(data)) + } + } catch (e) { + err = e + } finally { + next(err) + } +} +CipherBase.prototype._flush = function (done) { + var err + try { + this.push(this.__final()) + } catch (e) { + err = e + } + + done(err) +} +CipherBase.prototype._finalOrDigest = function (outputEnc) { + var outData = this.__final() || Buffer.alloc(0) + if (outputEnc) { + outData = this._toString(outData, outputEnc, true) + } + return outData +} + +CipherBase.prototype._toString = function (value, enc, fin) { + if (!this._decoder) { + this._decoder = new StringDecoder(enc) + this._encoding = enc + } + + if (this._encoding !== enc) throw new Error('can\'t switch encodings') + + var out = this._decoder.write(value) + if (fin) { + out += this._decoder.end() + } + + return out +} + +module.exports = CipherBase + +},{"103":103,"36":36,"65":65,"93":93}],40:[function(require,module,exports){ +(function (Buffer){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = Buffer.isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +}).call(this,{"isBuffer":require(66)}) + +},{"66":66}],41:[function(require,module,exports){ +'use strict' +var inherits = require(65) +var MD5 = require(69) +var RIPEMD160 = require(92) +var sha = require(96) +var Base = require(39) + +function Hash (hash) { + Base.call(this, 'digest') + + this._hash = hash +} + +inherits(Hash, Base) + +Hash.prototype._update = function (data) { + this._hash.update(data) +} + +Hash.prototype._final = function () { + return this._hash.digest() +} + +module.exports = function createHash (alg) { + alg = alg.toLowerCase() + if (alg === 'md5') return new MD5() + if (alg === 'rmd160' || alg === 'ripemd160') return new RIPEMD160() + + return new Hash(sha(alg)) +} + +},{"39":39,"65":65,"69":69,"92":92,"96":96}],42:[function(require,module,exports){ +var MD5 = require(69) + +module.exports = function (buffer) { + return new MD5().update(buffer).digest() +} + +},{"69":69}],43:[function(require,module,exports){ +'use strict' +var inherits = require(65) +var Legacy = require(44) +var Base = require(39) +var Buffer = require(93).Buffer +var md5 = require(42) +var RIPEMD160 = require(92) + +var sha = require(96) + +var ZEROS = Buffer.alloc(128) + +function Hmac (alg, key) { + Base.call(this, 'digest') + if (typeof key === 'string') { + key = Buffer.from(key) + } + + var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64 + + this._alg = alg + this._key = key + if (key.length > blocksize) { + var hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg) + key = hash.update(key).digest() + } else if (key.length < blocksize) { + key = Buffer.concat([key, ZEROS], blocksize) + } + + var ipad = this._ipad = Buffer.allocUnsafe(blocksize) + var opad = this._opad = Buffer.allocUnsafe(blocksize) + + for (var i = 0; i < blocksize; i++) { + ipad[i] = key[i] ^ 0x36 + opad[i] = key[i] ^ 0x5C + } + this._hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg) + this._hash.update(ipad) +} + +inherits(Hmac, Base) + +Hmac.prototype._update = function (data) { + this._hash.update(data) +} + +Hmac.prototype._final = function () { + var h = this._hash.digest() + var hash = this._alg === 'rmd160' ? new RIPEMD160() : sha(this._alg) + return hash.update(this._opad).update(h).digest() +} + +module.exports = function createHmac (alg, key) { + alg = alg.toLowerCase() + if (alg === 'rmd160' || alg === 'ripemd160') { + return new Hmac('rmd160', key) + } + if (alg === 'md5') { + return new Legacy(md5, key) + } + return new Hmac(alg, key) +} + +},{"39":39,"42":42,"44":44,"65":65,"92":92,"93":93,"96":96}],44:[function(require,module,exports){ +'use strict' +var inherits = require(65) +var Buffer = require(93).Buffer + +var Base = require(39) + +var ZEROS = Buffer.alloc(128) +var blocksize = 64 + +function Hmac (alg, key) { + Base.call(this, 'digest') + if (typeof key === 'string') { + key = Buffer.from(key) + } + + this._alg = alg + this._key = key + + if (key.length > blocksize) { + key = alg(key) + } else if (key.length < blocksize) { + key = Buffer.concat([key, ZEROS], blocksize) + } + + var ipad = this._ipad = Buffer.allocUnsafe(blocksize) + var opad = this._opad = Buffer.allocUnsafe(blocksize) + + for (var i = 0; i < blocksize; i++) { + ipad[i] = key[i] ^ 0x36 + opad[i] = key[i] ^ 0x5C + } + + this._hash = [ipad] +} + +inherits(Hmac, Base) + +Hmac.prototype._update = function (data) { + this._hash.push(data) +} + +Hmac.prototype._final = function () { + var h = this._alg(Buffer.concat(this._hash)) + return this._alg(Buffer.concat([this._opad, h])) +} +module.exports = Hmac + +},{"39":39,"65":65,"93":93}],45:[function(require,module,exports){ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require(47), require(48), require(52), require(50), require(46)); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var BlockCipher = C_lib.BlockCipher; + var C_algo = C.algo; + + // Lookup tables + var SBOX = []; + var INV_SBOX = []; + var SUB_MIX_0 = []; + var SUB_MIX_1 = []; + var SUB_MIX_2 = []; + var SUB_MIX_3 = []; + var INV_SUB_MIX_0 = []; + var INV_SUB_MIX_1 = []; + var INV_SUB_MIX_2 = []; + var INV_SUB_MIX_3 = []; + + // Compute lookup tables + (function () { + // Compute double table + var d = []; + for (var i = 0; i < 256; i++) { + if (i < 128) { + d[i] = i << 1; + } else { + d[i] = (i << 1) ^ 0x11b; + } + } + + // Walk GF(2^8) + var x = 0; + var xi = 0; + for (var i = 0; i < 256; i++) { + // Compute sbox + var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); + sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; + SBOX[x] = sx; + INV_SBOX[sx] = x; + + // Compute multiplication + var x2 = d[x]; + var x4 = d[x2]; + var x8 = d[x4]; + + // Compute sub bytes, mix columns tables + var t = (d[sx] * 0x101) ^ (sx * 0x1010100); + SUB_MIX_0[x] = (t << 24) | (t >>> 8); + SUB_MIX_1[x] = (t << 16) | (t >>> 16); + SUB_MIX_2[x] = (t << 8) | (t >>> 24); + SUB_MIX_3[x] = t; + + // Compute inv sub bytes, inv mix columns tables + var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); + INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8); + INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16); + INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24); + INV_SUB_MIX_3[sx] = t; + + // Compute next counter + if (!x) { + x = xi = 1; + } else { + x = x2 ^ d[d[d[x8 ^ x2]]]; + xi ^= d[d[xi]]; + } + } + }()); + + // Precomputed Rcon lookup + var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; + + /** + * AES block cipher algorithm. + */ + var AES = C_algo.AES = BlockCipher.extend({ + _doReset: function () { + // Skip reset of nRounds has been set before and key did not change + if (this._nRounds && this._keyPriorReset === this._key) { + return; + } + + // Shortcuts + var key = this._keyPriorReset = this._key; + var keyWords = key.words; + var keySize = key.sigBytes / 4; + + // Compute number of rounds + var nRounds = this._nRounds = keySize + 6; + + // Compute number of key schedule rows + var ksRows = (nRounds + 1) * 4; + + // Compute key schedule + var keySchedule = this._keySchedule = []; + for (var ksRow = 0; ksRow < ksRows; ksRow++) { + if (ksRow < keySize) { + keySchedule[ksRow] = keyWords[ksRow]; + } else { + var t = keySchedule[ksRow - 1]; + + if (!(ksRow % keySize)) { + // Rot word + t = (t << 8) | (t >>> 24); + + // Sub word + t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; + + // Mix Rcon + t ^= RCON[(ksRow / keySize) | 0] << 24; + } else if (keySize > 6 && ksRow % keySize == 4) { + // Sub word + t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; + } + + keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; + } + } + + // Compute inv key schedule + var invKeySchedule = this._invKeySchedule = []; + for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) { + var ksRow = ksRows - invKsRow; + + if (invKsRow % 4) { + var t = keySchedule[ksRow]; + } else { + var t = keySchedule[ksRow - 4]; + } + + if (invKsRow < 4 || ksRow <= 4) { + invKeySchedule[invKsRow] = t; + } else { + invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^ + INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]]; + } + } + }, + + encryptBlock: function (M, offset) { + this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); + }, + + decryptBlock: function (M, offset) { + // Swap 2nd and 4th rows + var t = M[offset + 1]; + M[offset + 1] = M[offset + 3]; + M[offset + 3] = t; + + this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); + + // Inv swap 2nd and 4th rows + var t = M[offset + 1]; + M[offset + 1] = M[offset + 3]; + M[offset + 3] = t; + }, + + _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { + // Shortcut + var nRounds = this._nRounds; + + // Get input, add round key + var s0 = M[offset] ^ keySchedule[0]; + var s1 = M[offset + 1] ^ keySchedule[1]; + var s2 = M[offset + 2] ^ keySchedule[2]; + var s3 = M[offset + 3] ^ keySchedule[3]; + + // Key schedule row counter + var ksRow = 4; + + // Rounds + for (var round = 1; round < nRounds; round++) { + // Shift rows, sub bytes, mix columns, add round key + var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++]; + var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++]; + var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++]; + var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++]; + + // Update state + s0 = t0; + s1 = t1; + s2 = t2; + s3 = t3; + } + + // Shift rows, sub bytes, add round key + var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; + var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; + var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; + var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; + + // Set output + M[offset] = t0; + M[offset + 1] = t1; + M[offset + 2] = t2; + M[offset + 3] = t3; + }, + + keySize: 256/32 + }); + + /** + * Shortcut functions to the cipher's object interface. + * + * @example + * + * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); + * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); + */ + C.AES = BlockCipher._createHelper(AES); + }()); + + + return CryptoJS.AES; + +})); +},{"46":46,"47":47,"48":48,"50":50,"52":52}],46:[function(require,module,exports){ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require(47), require(50)); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./evpkdf"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + /** + * Cipher core components. + */ + CryptoJS.lib.Cipher || (function (undefined) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var WordArray = C_lib.WordArray; + var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; + var C_enc = C.enc; + var Utf8 = C_enc.Utf8; + var Base64 = C_enc.Base64; + var C_algo = C.algo; + var EvpKDF = C_algo.EvpKDF; + + /** + * Abstract base cipher template. + * + * @property {number} keySize This cipher's key size. Default: 4 (128 bits) + * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) + * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. + * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. + */ + var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + * + * @property {WordArray} iv The IV to use for this operation. + */ + cfg: Base.extend(), + + /** + * Creates this cipher in encryption mode. + * + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {Cipher} A cipher instance. + * + * @static + * + * @example + * + * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); + */ + createEncryptor: function (key, cfg) { + return this.create(this._ENC_XFORM_MODE, key, cfg); + }, + + /** + * Creates this cipher in decryption mode. + * + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {Cipher} A cipher instance. + * + * @static + * + * @example + * + * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); + */ + createDecryptor: function (key, cfg) { + return this.create(this._DEC_XFORM_MODE, key, cfg); + }, + + /** + * Initializes a newly created cipher. + * + * @param {number} xformMode Either the encryption or decryption transormation mode constant. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @example + * + * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); + */ + init: function (xformMode, key, cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Store transform mode and key + this._xformMode = xformMode; + this._key = key; + + // Set initial values + this.reset(); + }, + + /** + * Resets this cipher to its initial state. + * + * @example + * + * cipher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-cipher logic + this._doReset(); + }, + + /** + * Adds data to be encrypted or decrypted. + * + * @param {WordArray|string} dataUpdate The data to encrypt or decrypt. + * + * @return {WordArray} The data after processing. + * + * @example + * + * var encrypted = cipher.process('data'); + * var encrypted = cipher.process(wordArray); + */ + process: function (dataUpdate) { + // Append + this._append(dataUpdate); + + // Process available blocks + return this._process(); + }, + + /** + * Finalizes the encryption or decryption process. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt. + * + * @return {WordArray} The data after final processing. + * + * @example + * + * var encrypted = cipher.finalize(); + * var encrypted = cipher.finalize('data'); + * var encrypted = cipher.finalize(wordArray); + */ + finalize: function (dataUpdate) { + // Final data update + if (dataUpdate) { + this._append(dataUpdate); + } + + // Perform concrete-cipher logic + var finalProcessedData = this._doFinalize(); + + return finalProcessedData; + }, + + keySize: 128/32, + + ivSize: 128/32, + + _ENC_XFORM_MODE: 1, + + _DEC_XFORM_MODE: 2, + + /** + * Creates shortcut functions to a cipher's object interface. + * + * @param {Cipher} cipher The cipher to create a helper for. + * + * @return {Object} An object with encrypt and decrypt shortcut functions. + * + * @static + * + * @example + * + * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); + */ + _createHelper: (function () { + function selectCipherStrategy(key) { + if (typeof key == 'string') { + return PasswordBasedCipher; + } else { + return SerializableCipher; + } + } + + return function (cipher) { + return { + encrypt: function (message, key, cfg) { + return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); + }, + + decrypt: function (ciphertext, key, cfg) { + return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); + } + }; + }; + }()) + }); + + /** + * Abstract base stream cipher template. + * + * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) + */ + var StreamCipher = C_lib.StreamCipher = Cipher.extend({ + _doFinalize: function () { + // Process partial blocks + var finalProcessedBlocks = this._process(!!'flush'); + + return finalProcessedBlocks; + }, + + blockSize: 1 + }); + + /** + * Mode namespace. + */ + var C_mode = C.mode = {}; + + /** + * Abstract base block cipher mode template. + */ + var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ + /** + * Creates this mode for encryption. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @static + * + * @example + * + * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); + */ + createEncryptor: function (cipher, iv) { + return this.Encryptor.create(cipher, iv); + }, + + /** + * Creates this mode for decryption. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @static + * + * @example + * + * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); + */ + createDecryptor: function (cipher, iv) { + return this.Decryptor.create(cipher, iv); + }, + + /** + * Initializes a newly created mode. + * + * @param {Cipher} cipher A block cipher instance. + * @param {Array} iv The IV words. + * + * @example + * + * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); + */ + init: function (cipher, iv) { + this._cipher = cipher; + this._iv = iv; + } + }); + + /** + * Cipher Block Chaining mode. + */ + var CBC = C_mode.CBC = (function () { + /** + * Abstract base CBC mode. + */ + var CBC = BlockCipherMode.extend(); + + /** + * CBC encryptor. + */ + CBC.Encryptor = CBC.extend({ + /** + * Processes the data block at offset. + * + * @param {Array} words The data words to operate on. + * @param {number} offset The offset where the block starts. + * + * @example + * + * mode.processBlock(data.words, offset); + */ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + // XOR and encrypt + xorBlock.call(this, words, offset, blockSize); + cipher.encryptBlock(words, offset); + + // Remember this block to use with next block + this._prevBlock = words.slice(offset, offset + blockSize); + } + }); + + /** + * CBC decryptor. + */ + CBC.Decryptor = CBC.extend({ + /** + * Processes the data block at offset. + * + * @param {Array} words The data words to operate on. + * @param {number} offset The offset where the block starts. + * + * @example + * + * mode.processBlock(data.words, offset); + */ + processBlock: function (words, offset) { + // Shortcuts + var cipher = this._cipher; + var blockSize = cipher.blockSize; + + // Remember this block to use with next block + var thisBlock = words.slice(offset, offset + blockSize); + + // Decrypt and XOR + cipher.decryptBlock(words, offset); + xorBlock.call(this, words, offset, blockSize); + + // This block becomes the previous block + this._prevBlock = thisBlock; + } + }); + + function xorBlock(words, offset, blockSize) { + // Shortcut + var iv = this._iv; + + // Choose mixing block + if (iv) { + var block = iv; + + // Remove IV for subsequent blocks + this._iv = undefined; + } else { + var block = this._prevBlock; + } + + // XOR blocks + for (var i = 0; i < blockSize; i++) { + words[offset + i] ^= block[i]; + } + } + + return CBC; + }()); + + /** + * Padding namespace. + */ + var C_pad = C.pad = {}; + + /** + * PKCS #5/7 padding strategy. + */ + var Pkcs7 = C_pad.Pkcs7 = { + /** + * Pads data using the algorithm defined in PKCS #5/7. + * + * @param {WordArray} data The data to pad. + * @param {number} blockSize The multiple that the data should be padded to. + * + * @static + * + * @example + * + * CryptoJS.pad.Pkcs7.pad(wordArray, 4); + */ + pad: function (data, blockSize) { + // Shortcut + var blockSizeBytes = blockSize * 4; + + // Count padding bytes + var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; + + // Create padding word + var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes; + + // Create padding + var paddingWords = []; + for (var i = 0; i < nPaddingBytes; i += 4) { + paddingWords.push(paddingWord); + } + var padding = WordArray.create(paddingWords, nPaddingBytes); + + // Add padding + data.concat(padding); + }, + + /** + * Unpads data that had been padded using the algorithm defined in PKCS #5/7. + * + * @param {WordArray} data The data to unpad. + * + * @static + * + * @example + * + * CryptoJS.pad.Pkcs7.unpad(wordArray); + */ + unpad: function (data) { + // Get number of padding bytes from last byte + var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; + + // Remove padding + data.sigBytes -= nPaddingBytes; + } + }; + + /** + * Abstract base block cipher template. + * + * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) + */ + var BlockCipher = C_lib.BlockCipher = Cipher.extend({ + /** + * Configuration options. + * + * @property {Mode} mode The block mode to use. Default: CBC + * @property {Padding} padding The padding strategy to use. Default: Pkcs7 + */ + cfg: Cipher.cfg.extend({ + mode: CBC, + padding: Pkcs7 + }), + + reset: function () { + // Reset cipher + Cipher.reset.call(this); + + // Shortcuts + var cfg = this.cfg; + var iv = cfg.iv; + var mode = cfg.mode; + + // Reset block mode + if (this._xformMode == this._ENC_XFORM_MODE) { + var modeCreator = mode.createEncryptor; + } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { + var modeCreator = mode.createDecryptor; + // Keep at least one block in the buffer for unpadding + this._minBufferSize = 1; + } + + if (this._mode && this._mode.__creator == modeCreator) { + this._mode.init(this, iv && iv.words); + } else { + this._mode = modeCreator.call(mode, this, iv && iv.words); + this._mode.__creator = modeCreator; + } + }, + + _doProcessBlock: function (words, offset) { + this._mode.processBlock(words, offset); + }, + + _doFinalize: function () { + // Shortcut + var padding = this.cfg.padding; + + // Finalize + if (this._xformMode == this._ENC_XFORM_MODE) { + // Pad data + padding.pad(this._data, this.blockSize); + + // Process final blocks + var finalProcessedBlocks = this._process(!!'flush'); + } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { + // Process final blocks + var finalProcessedBlocks = this._process(!!'flush'); + + // Unpad data + padding.unpad(finalProcessedBlocks); + } + + return finalProcessedBlocks; + }, + + blockSize: 128/32 + }); + + /** + * A collection of cipher parameters. + * + * @property {WordArray} ciphertext The raw ciphertext. + * @property {WordArray} key The key to this ciphertext. + * @property {WordArray} iv The IV used in the ciphering operation. + * @property {WordArray} salt The salt used with a key derivation function. + * @property {Cipher} algorithm The cipher algorithm. + * @property {Mode} mode The block mode used in the ciphering operation. + * @property {Padding} padding The padding scheme used in the ciphering operation. + * @property {number} blockSize The block size of the cipher. + * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. + */ + var CipherParams = C_lib.CipherParams = Base.extend({ + /** + * Initializes a newly created cipher params object. + * + * @param {Object} cipherParams An object with any of the possible cipher parameters. + * + * @example + * + * var cipherParams = CryptoJS.lib.CipherParams.create({ + * ciphertext: ciphertextWordArray, + * key: keyWordArray, + * iv: ivWordArray, + * salt: saltWordArray, + * algorithm: CryptoJS.algo.AES, + * mode: CryptoJS.mode.CBC, + * padding: CryptoJS.pad.PKCS7, + * blockSize: 4, + * formatter: CryptoJS.format.OpenSSL + * }); + */ + init: function (cipherParams) { + this.mixIn(cipherParams); + }, + + /** + * Converts this cipher params object to a string. + * + * @param {Format} formatter (Optional) The formatting strategy to use. + * + * @return {string} The stringified cipher params. + * + * @throws Error If neither the formatter nor the default formatter is set. + * + * @example + * + * var string = cipherParams + ''; + * var string = cipherParams.toString(); + * var string = cipherParams.toString(CryptoJS.format.OpenSSL); + */ + toString: function (formatter) { + return (formatter || this.formatter).stringify(this); + } + }); + + /** + * Format namespace. + */ + var C_format = C.format = {}; + + /** + * OpenSSL formatting strategy. + */ + var OpenSSLFormatter = C_format.OpenSSL = { + /** + * Converts a cipher params object to an OpenSSL-compatible string. + * + * @param {CipherParams} cipherParams The cipher params object. + * + * @return {string} The OpenSSL-compatible string. + * + * @static + * + * @example + * + * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); + */ + stringify: function (cipherParams) { + // Shortcuts + var ciphertext = cipherParams.ciphertext; + var salt = cipherParams.salt; + + // Format + if (salt) { + var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); + } else { + var wordArray = ciphertext; + } + + return wordArray.toString(Base64); + }, + + /** + * Converts an OpenSSL-compatible string to a cipher params object. + * + * @param {string} openSSLStr The OpenSSL-compatible string. + * + * @return {CipherParams} The cipher params object. + * + * @static + * + * @example + * + * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); + */ + parse: function (openSSLStr) { + // Parse base64 + var ciphertext = Base64.parse(openSSLStr); + + // Shortcut + var ciphertextWords = ciphertext.words; + + // Test for salt + if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { + // Extract salt + var salt = WordArray.create(ciphertextWords.slice(2, 4)); + + // Remove salt from ciphertext + ciphertextWords.splice(0, 4); + ciphertext.sigBytes -= 16; + } + + return CipherParams.create({ ciphertext: ciphertext, salt: salt }); + } + }; + + /** + * A cipher wrapper that returns ciphertext as a serializable cipher params object. + */ + var SerializableCipher = C_lib.SerializableCipher = Base.extend({ + /** + * Configuration options. + * + * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL + */ + cfg: Base.extend({ + format: OpenSSLFormatter + }), + + /** + * Encrypts a message. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {WordArray|string} message The message to encrypt. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {CipherParams} A cipher params object. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); + * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + */ + encrypt: function (cipher, message, key, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Encrypt + var encryptor = cipher.createEncryptor(key, cfg); + var ciphertext = encryptor.finalize(message); + + // Shortcut + var cipherCfg = encryptor.cfg; + + // Create and return serializable cipher params + return CipherParams.create({ + ciphertext: ciphertext, + key: key, + iv: cipherCfg.iv, + algorithm: cipher, + mode: cipherCfg.mode, + padding: cipherCfg.padding, + blockSize: cipher.blockSize, + formatter: cfg.format + }); + }, + + /** + * Decrypts serialized ciphertext. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {CipherParams|string} ciphertext The ciphertext to decrypt. + * @param {WordArray} key The key. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {WordArray} The plaintext. + * + * @static + * + * @example + * + * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); + */ + decrypt: function (cipher, ciphertext, key, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Convert string to CipherParams + ciphertext = this._parse(ciphertext, cfg.format); + + // Decrypt + var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); + + return plaintext; + }, + + /** + * Converts serialized ciphertext to CipherParams, + * else assumed CipherParams already and returns ciphertext unchanged. + * + * @param {CipherParams|string} ciphertext The ciphertext. + * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext. + * + * @return {CipherParams} The unserialized ciphertext. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); + */ + _parse: function (ciphertext, format) { + if (typeof ciphertext == 'string') { + return format.parse(ciphertext, this); + } else { + return ciphertext; + } + } + }); + + /** + * Key derivation function namespace. + */ + var C_kdf = C.kdf = {}; + + /** + * OpenSSL key derivation function. + */ + var OpenSSLKdf = C_kdf.OpenSSL = { + /** + * Derives a key and IV from a password. + * + * @param {string} password The password to derive from. + * @param {number} keySize The size in words of the key to generate. + * @param {number} ivSize The size in words of the IV to generate. + * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. + * + * @return {CipherParams} A cipher params object with the key, IV, and salt. + * + * @static + * + * @example + * + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); + * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); + */ + execute: function (password, keySize, ivSize, salt) { + // Generate random salt + if (!salt) { + salt = WordArray.random(64/8); + } + + // Derive key and IV + var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); + + // Separate key and IV + var iv = WordArray.create(key.words.slice(keySize), ivSize * 4); + key.sigBytes = keySize * 4; + + // Return params + return CipherParams.create({ key: key, iv: iv, salt: salt }); + } + }; + + /** + * A serializable cipher wrapper that derives the key from a password, + * and returns ciphertext as a serializable cipher params object. + */ + var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ + /** + * Configuration options. + * + * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL + */ + cfg: SerializableCipher.cfg.extend({ + kdf: OpenSSLKdf + }), + + /** + * Encrypts a message using a password. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {WordArray|string} message The message to encrypt. + * @param {string} password The password. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {CipherParams} A cipher params object. + * + * @static + * + * @example + * + * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); + * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); + */ + encrypt: function (cipher, message, password, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Derive key and other params + var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize); + + // Add IV to config + cfg.iv = derivedParams.iv; + + // Encrypt + var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); + + // Mix in derived params + ciphertext.mixIn(derivedParams); + + return ciphertext; + }, + + /** + * Decrypts serialized ciphertext using a password. + * + * @param {Cipher} cipher The cipher algorithm to use. + * @param {CipherParams|string} ciphertext The ciphertext to decrypt. + * @param {string} password The password. + * @param {Object} cfg (Optional) The configuration options to use for this operation. + * + * @return {WordArray} The plaintext. + * + * @static + * + * @example + * + * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); + * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); + */ + decrypt: function (cipher, ciphertext, password, cfg) { + // Apply config defaults + cfg = this.cfg.extend(cfg); + + // Convert string to CipherParams + ciphertext = this._parse(ciphertext, cfg.format); + + // Derive key and other params + var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt); + + // Add IV to config + cfg.iv = derivedParams.iv; + + // Decrypt + var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); + + return plaintext; + } + }); + }()); + + +})); +},{"47":47,"50":50}],47:[function(require,module,exports){ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(); + } + else if (typeof define === "function" && define.amd) { + // AMD + define([], factory); + } + else { + // Global (browser) + root.CryptoJS = factory(); + } +}(this, function () { + + /** + * CryptoJS core components. + */ + var CryptoJS = CryptoJS || (function (Math, undefined) { + /* + * Local polyfil of Object.create + */ + var create = Object.create || (function () { + function F() {}; + + return function (obj) { + var subtype; + + F.prototype = obj; + + subtype = new F(); + + F.prototype = null; + + return subtype; + }; + }()) + + /** + * CryptoJS namespace. + */ + var C = {}; + + /** + * Library namespace. + */ + var C_lib = C.lib = {}; + + /** + * Base object for prototypal inheritance. + */ + var Base = C_lib.Base = (function () { + + + return { + /** + * Creates a new object that inherits from this object. + * + * @param {Object} overrides Properties to copy into the new object. + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * field: 'value', + * + * method: function () { + * } + * }); + */ + extend: function (overrides) { + // Spawn + var subtype = create(this); + + // Augment + if (overrides) { + subtype.mixIn(overrides); + } + + // Create default initializer + if (!subtype.hasOwnProperty('init') || this.init === subtype.init) { + subtype.init = function () { + subtype.$super.init.apply(this, arguments); + }; + } + + // Initializer's prototype is the subtype object + subtype.init.prototype = subtype; + + // Reference supertype + subtype.$super = this; + + return subtype; + }, + + /** + * Extends this object and runs the init method. + * Arguments to create() will be passed to init(). + * + * @return {Object} The new object. + * + * @static + * + * @example + * + * var instance = MyType.create(); + */ + create: function () { + var instance = this.extend(); + instance.init.apply(instance, arguments); + + return instance; + }, + + /** + * Initializes a newly created object. + * Override this method to add some logic when your objects are created. + * + * @example + * + * var MyType = CryptoJS.lib.Base.extend({ + * init: function () { + * // ... + * } + * }); + */ + init: function () { + }, + + /** + * Copies properties into this object. + * + * @param {Object} properties The properties to mix in. + * + * @example + * + * MyType.mixIn({ + * field: 'value' + * }); + */ + mixIn: function (properties) { + for (var propertyName in properties) { + if (properties.hasOwnProperty(propertyName)) { + this[propertyName] = properties[propertyName]; + } + } + + // IE won't copy toString using the loop above + if (properties.hasOwnProperty('toString')) { + this.toString = properties.toString; + } + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = instance.clone(); + */ + clone: function () { + return this.init.prototype.extend(this); + } + }; + }()); + + /** + * An array of 32-bit words. + * + * @property {Array} words The array of 32-bit words. + * @property {number} sigBytes The number of significant bytes in this word array. + */ + var WordArray = C_lib.WordArray = Base.extend({ + /** + * Initializes a newly created word array. + * + * @param {Array} words (Optional) An array of 32-bit words. + * @param {number} sigBytes (Optional) The number of significant bytes in the words. + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.create(); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); + * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); + */ + init: function (words, sigBytes) { + words = this.words = words || []; + + if (sigBytes != undefined) { + this.sigBytes = sigBytes; + } else { + this.sigBytes = words.length * 4; + } + }, + + /** + * Converts this word array to a string. + * + * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex + * + * @return {string} The stringified word array. + * + * @example + * + * var string = wordArray + ''; + * var string = wordArray.toString(); + * var string = wordArray.toString(CryptoJS.enc.Utf8); + */ + toString: function (encoder) { + return (encoder || Hex).stringify(this); + }, + + /** + * Concatenates a word array to this word array. + * + * @param {WordArray} wordArray The word array to append. + * + * @return {WordArray} This word array. + * + * @example + * + * wordArray1.concat(wordArray2); + */ + concat: function (wordArray) { + // Shortcuts + var thisWords = this.words; + var thatWords = wordArray.words; + var thisSigBytes = this.sigBytes; + var thatSigBytes = wordArray.sigBytes; + + // Clamp excess bits + this.clamp(); + + // Concat + if (thisSigBytes % 4) { + // Copy one byte at a time + for (var i = 0; i < thatSigBytes; i++) { + var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); + } + } else { + // Copy one word at a time + for (var i = 0; i < thatSigBytes; i += 4) { + thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; + } + } + this.sigBytes += thatSigBytes; + + // Chainable + return this; + }, + + /** + * Removes insignificant bits. + * + * @example + * + * wordArray.clamp(); + */ + clamp: function () { + // Shortcuts + var words = this.words; + var sigBytes = this.sigBytes; + + // Clamp + words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); + words.length = Math.ceil(sigBytes / 4); + }, + + /** + * Creates a copy of this word array. + * + * @return {WordArray} The clone. + * + * @example + * + * var clone = wordArray.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone.words = this.words.slice(0); + + return clone; + }, + + /** + * Creates a word array filled with random bytes. + * + * @param {number} nBytes The number of random bytes to generate. + * + * @return {WordArray} The random word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.lib.WordArray.random(16); + */ + random: function (nBytes) { + var words = []; + + var r = (function (m_w) { + var m_w = m_w; + var m_z = 0x3ade68b1; + var mask = 0xffffffff; + + return function () { + m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask; + m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask; + var result = ((m_z << 0x10) + m_w) & mask; + result /= 0x100000000; + result += 0.5; + return result * (Math.random() > .5 ? 1 : -1); + } + }); + + for (var i = 0, rcache; i < nBytes; i += 4) { + var _r = r((rcache || Math.random()) * 0x100000000); + + rcache = _r() * 0x3ade67b7; + words.push((_r() * 0x100000000) | 0); + } + + return new WordArray.init(words, nBytes); + } + }); + + /** + * Encoder namespace. + */ + var C_enc = C.enc = {}; + + /** + * Hex encoding strategy. + */ + var Hex = C_enc.Hex = { + /** + * Converts a word array to a hex string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The hex string. + * + * @static + * + * @example + * + * var hexString = CryptoJS.enc.Hex.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var hexChars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + hexChars.push((bite >>> 4).toString(16)); + hexChars.push((bite & 0x0f).toString(16)); + } + + return hexChars.join(''); + }, + + /** + * Converts a hex string to a word array. + * + * @param {string} hexStr The hex string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Hex.parse(hexString); + */ + parse: function (hexStr) { + // Shortcut + var hexStrLength = hexStr.length; + + // Convert + var words = []; + for (var i = 0; i < hexStrLength; i += 2) { + words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); + } + + return new WordArray.init(words, hexStrLength / 2); + } + }; + + /** + * Latin1 encoding strategy. + */ + var Latin1 = C_enc.Latin1 = { + /** + * Converts a word array to a Latin1 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Latin1 string. + * + * @static + * + * @example + * + * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + + // Convert + var latin1Chars = []; + for (var i = 0; i < sigBytes; i++) { + var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + latin1Chars.push(String.fromCharCode(bite)); + } + + return latin1Chars.join(''); + }, + + /** + * Converts a Latin1 string to a word array. + * + * @param {string} latin1Str The Latin1 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); + */ + parse: function (latin1Str) { + // Shortcut + var latin1StrLength = latin1Str.length; + + // Convert + var words = []; + for (var i = 0; i < latin1StrLength; i++) { + words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); + } + + return new WordArray.init(words, latin1StrLength); + } + }; + + /** + * UTF-8 encoding strategy. + */ + var Utf8 = C_enc.Utf8 = { + /** + * Converts a word array to a UTF-8 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The UTF-8 string. + * + * @static + * + * @example + * + * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); + */ + stringify: function (wordArray) { + try { + return decodeURIComponent(escape(Latin1.stringify(wordArray))); + } catch (e) { + throw new Error('Malformed UTF-8 data'); + } + }, + + /** + * Converts a UTF-8 string to a word array. + * + * @param {string} utf8Str The UTF-8 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); + */ + parse: function (utf8Str) { + return Latin1.parse(unescape(encodeURIComponent(utf8Str))); + } + }; + + /** + * Abstract buffered block algorithm template. + * + * The property blockSize must be implemented in a concrete subtype. + * + * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 + */ + var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ + /** + * Resets this block algorithm's data buffer to its initial state. + * + * @example + * + * bufferedBlockAlgorithm.reset(); + */ + reset: function () { + // Initial values + this._data = new WordArray.init(); + this._nDataBytes = 0; + }, + + /** + * Adds new data to this block algorithm's buffer. + * + * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. + * + * @example + * + * bufferedBlockAlgorithm._append('data'); + * bufferedBlockAlgorithm._append(wordArray); + */ + _append: function (data) { + // Convert string to WordArray, else assume WordArray already + if (typeof data == 'string') { + data = Utf8.parse(data); + } + + // Append + this._data.concat(data); + this._nDataBytes += data.sigBytes; + }, + + /** + * Processes available data blocks. + * + * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. + * + * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. + * + * @return {WordArray} The processed data. + * + * @example + * + * var processedData = bufferedBlockAlgorithm._process(); + * var processedData = bufferedBlockAlgorithm._process(!!'flush'); + */ + _process: function (doFlush) { + // Shortcuts + var data = this._data; + var dataWords = data.words; + var dataSigBytes = data.sigBytes; + var blockSize = this.blockSize; + var blockSizeBytes = blockSize * 4; + + // Count blocks ready + var nBlocksReady = dataSigBytes / blockSizeBytes; + if (doFlush) { + // Round up to include partial blocks + nBlocksReady = Math.ceil(nBlocksReady); + } else { + // Round down to include only full blocks, + // less the number of blocks that must remain in the buffer + nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); + } + + // Count words ready + var nWordsReady = nBlocksReady * blockSize; + + // Count bytes ready + var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); + + // Process blocks + if (nWordsReady) { + for (var offset = 0; offset < nWordsReady; offset += blockSize) { + // Perform concrete-algorithm logic + this._doProcessBlock(dataWords, offset); + } + + // Remove processed words + var processedWords = dataWords.splice(0, nWordsReady); + data.sigBytes -= nBytesReady; + } + + // Return processed words + return new WordArray.init(processedWords, nBytesReady); + }, + + /** + * Creates a copy of this object. + * + * @return {Object} The clone. + * + * @example + * + * var clone = bufferedBlockAlgorithm.clone(); + */ + clone: function () { + var clone = Base.clone.call(this); + clone._data = this._data.clone(); + + return clone; + }, + + _minBufferSize: 0 + }); + + /** + * Abstract hasher template. + * + * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) + */ + var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ + /** + * Configuration options. + */ + cfg: Base.extend(), + + /** + * Initializes a newly created hasher. + * + * @param {Object} cfg (Optional) The configuration options to use for this hash computation. + * + * @example + * + * var hasher = CryptoJS.algo.SHA256.create(); + */ + init: function (cfg) { + // Apply config defaults + this.cfg = this.cfg.extend(cfg); + + // Set initial values + this.reset(); + }, + + /** + * Resets this hasher to its initial state. + * + * @example + * + * hasher.reset(); + */ + reset: function () { + // Reset data buffer + BufferedBlockAlgorithm.reset.call(this); + + // Perform concrete-hasher logic + this._doReset(); + }, + + /** + * Updates this hasher with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {Hasher} This hasher. + * + * @example + * + * hasher.update('message'); + * hasher.update(wordArray); + */ + update: function (messageUpdate) { + // Append + this._append(messageUpdate); + + // Update the hash + this._process(); + + // Chainable + return this; + }, + + /** + * Finalizes the hash computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The hash. + * + * @example + * + * var hash = hasher.finalize(); + * var hash = hasher.finalize('message'); + * var hash = hasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Final message update + if (messageUpdate) { + this._append(messageUpdate); + } + + // Perform concrete-hasher logic + var hash = this._doFinalize(); + + return hash; + }, + + blockSize: 512/32, + + /** + * Creates a shortcut function to a hasher's object interface. + * + * @param {Hasher} hasher The hasher to create a helper for. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); + */ + _createHelper: function (hasher) { + return function (message, cfg) { + return new hasher.init(cfg).finalize(message); + }; + }, + + /** + * Creates a shortcut function to the HMAC's object interface. + * + * @param {Hasher} hasher The hasher to use in this HMAC helper. + * + * @return {Function} The shortcut function. + * + * @static + * + * @example + * + * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); + */ + _createHmacHelper: function (hasher) { + return function (message, key) { + return new C_algo.HMAC.init(hasher, key).finalize(message); + }; + } + }); + + /** + * Algorithm namespace. + */ + var C_algo = C.algo = {}; + + return C; + }(Math)); + + + return CryptoJS; + +})); +},{}],48:[function(require,module,exports){ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require(47)); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var C_enc = C.enc; + + /** + * Base64 encoding strategy. + */ + var Base64 = C_enc.Base64 = { + /** + * Converts a word array to a Base64 string. + * + * @param {WordArray} wordArray The word array. + * + * @return {string} The Base64 string. + * + * @static + * + * @example + * + * var base64String = CryptoJS.enc.Base64.stringify(wordArray); + */ + stringify: function (wordArray) { + // Shortcuts + var words = wordArray.words; + var sigBytes = wordArray.sigBytes; + var map = this._map; + + // Clamp excess bits + wordArray.clamp(); + + // Convert + var base64Chars = []; + for (var i = 0; i < sigBytes; i += 3) { + var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; + var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; + + var triplet = (byte1 << 16) | (byte2 << 8) | byte3; + + for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { + base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); + } + } + + // Add padding + var paddingChar = map.charAt(64); + if (paddingChar) { + while (base64Chars.length % 4) { + base64Chars.push(paddingChar); + } + } + + return base64Chars.join(''); + }, + + /** + * Converts a Base64 string to a word array. + * + * @param {string} base64Str The Base64 string. + * + * @return {WordArray} The word array. + * + * @static + * + * @example + * + * var wordArray = CryptoJS.enc.Base64.parse(base64String); + */ + parse: function (base64Str) { + // Shortcuts + var base64StrLength = base64Str.length; + var map = this._map; + var reverseMap = this._reverseMap; + + if (!reverseMap) { + reverseMap = this._reverseMap = []; + for (var j = 0; j < map.length; j++) { + reverseMap[map.charCodeAt(j)] = j; + } + } + + // Ignore padding + var paddingChar = map.charAt(64); + if (paddingChar) { + var paddingIndex = base64Str.indexOf(paddingChar); + if (paddingIndex !== -1) { + base64StrLength = paddingIndex; + } + } + + // Convert + return parseLoop(base64Str, base64StrLength, reverseMap); + + }, + + _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' + }; + + function parseLoop(base64Str, base64StrLength, reverseMap) { + var words = []; + var nBytes = 0; + for (var i = 0; i < base64StrLength; i++) { + if (i % 4) { + var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); + var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); + words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); + nBytes++; + } + } + return WordArray.create(words, nBytes); + } + }()); + + + return CryptoJS.enc.Base64; + +})); +},{"47":47}],49:[function(require,module,exports){ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require(47)); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + return CryptoJS.enc.Hex; + +})); +},{"47":47}],50:[function(require,module,exports){ +;(function (root, factory, undef) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require(47), require(53), require(51)); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core", "./sha1", "./hmac"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var WordArray = C_lib.WordArray; + var C_algo = C.algo; + var MD5 = C_algo.MD5; + + /** + * This key derivation function is meant to conform with EVP_BytesToKey. + * www.openssl.org/docs/crypto/EVP_BytesToKey.html + */ + var EvpKDF = C_algo.EvpKDF = Base.extend({ + /** + * Configuration options. + * + * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) + * @property {Hasher} hasher The hash algorithm to use. Default: MD5 + * @property {number} iterations The number of iterations to perform. Default: 1 + */ + cfg: Base.extend({ + keySize: 128/32, + hasher: MD5, + iterations: 1 + }), + + /** + * Initializes a newly created key derivation function. + * + * @param {Object} cfg (Optional) The configuration options to use for the derivation. + * + * @example + * + * var kdf = CryptoJS.algo.EvpKDF.create(); + * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 }); + * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 }); + */ + init: function (cfg) { + this.cfg = this.cfg.extend(cfg); + }, + + /** + * Derives a key from a password. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * + * @return {WordArray} The derived key. + * + * @example + * + * var key = kdf.compute(password, salt); + */ + compute: function (password, salt) { + // Shortcut + var cfg = this.cfg; + + // Init hasher + var hasher = cfg.hasher.create(); + + // Initial values + var derivedKey = WordArray.create(); + + // Shortcuts + var derivedKeyWords = derivedKey.words; + var keySize = cfg.keySize; + var iterations = cfg.iterations; + + // Generate key + while (derivedKeyWords.length < keySize) { + if (block) { + hasher.update(block); + } + var block = hasher.update(password).finalize(salt); + hasher.reset(); + + // Iterations + for (var i = 1; i < iterations; i++) { + block = hasher.finalize(block); + hasher.reset(); + } + + derivedKey.concat(block); + } + derivedKey.sigBytes = keySize * 4; + + return derivedKey; + } + }); + + /** + * Derives a key from a password. + * + * @param {WordArray|string} password The password. + * @param {WordArray|string} salt A salt. + * @param {Object} cfg (Optional) The configuration options to use for this computation. + * + * @return {WordArray} The derived key. + * + * @static + * + * @example + * + * var key = CryptoJS.EvpKDF(password, salt); + * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 }); + * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 }); + */ + C.EvpKDF = function (password, salt, cfg) { + return EvpKDF.create(cfg).compute(password, salt); + }; + }()); + + + return CryptoJS.EvpKDF; + +})); +},{"47":47,"51":51,"53":53}],51:[function(require,module,exports){ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require(47)); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var Base = C_lib.Base; + var C_enc = C.enc; + var Utf8 = C_enc.Utf8; + var C_algo = C.algo; + + /** + * HMAC algorithm. + */ + var HMAC = C_algo.HMAC = Base.extend({ + /** + * Initializes a newly created HMAC. + * + * @param {Hasher} hasher The hash algorithm to use. + * @param {WordArray|string} key The secret key. + * + * @example + * + * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); + */ + init: function (hasher, key) { + // Init hasher + hasher = this._hasher = new hasher.init(); + + // Convert string to WordArray, else assume WordArray already + if (typeof key == 'string') { + key = Utf8.parse(key); + } + + // Shortcuts + var hasherBlockSize = hasher.blockSize; + var hasherBlockSizeBytes = hasherBlockSize * 4; + + // Allow arbitrary length keys + if (key.sigBytes > hasherBlockSizeBytes) { + key = hasher.finalize(key); + } + + // Clamp excess bits + key.clamp(); + + // Clone key for inner and outer pads + var oKey = this._oKey = key.clone(); + var iKey = this._iKey = key.clone(); + + // Shortcuts + var oKeyWords = oKey.words; + var iKeyWords = iKey.words; + + // XOR keys with pad constants + for (var i = 0; i < hasherBlockSize; i++) { + oKeyWords[i] ^= 0x5c5c5c5c; + iKeyWords[i] ^= 0x36363636; + } + oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; + + // Set initial values + this.reset(); + }, + + /** + * Resets this HMAC to its initial state. + * + * @example + * + * hmacHasher.reset(); + */ + reset: function () { + // Shortcut + var hasher = this._hasher; + + // Reset + hasher.reset(); + hasher.update(this._iKey); + }, + + /** + * Updates this HMAC with a message. + * + * @param {WordArray|string} messageUpdate The message to append. + * + * @return {HMAC} This HMAC instance. + * + * @example + * + * hmacHasher.update('message'); + * hmacHasher.update(wordArray); + */ + update: function (messageUpdate) { + this._hasher.update(messageUpdate); + + // Chainable + return this; + }, + + /** + * Finalizes the HMAC computation. + * Note that the finalize operation is effectively a destructive, read-once operation. + * + * @param {WordArray|string} messageUpdate (Optional) A final message update. + * + * @return {WordArray} The HMAC. + * + * @example + * + * var hmac = hmacHasher.finalize(); + * var hmac = hmacHasher.finalize('message'); + * var hmac = hmacHasher.finalize(wordArray); + */ + finalize: function (messageUpdate) { + // Shortcut + var hasher = this._hasher; + + // Compute HMAC + var innerHash = hasher.finalize(messageUpdate); + hasher.reset(); + var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); + + return hmac; + } + }); + }()); + + +})); +},{"47":47}],52:[function(require,module,exports){ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require(47)); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function (Math) { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Constants table + var T = []; + + // Compute constants + (function () { + for (var i = 0; i < 64; i++) { + T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; + } + }()); + + /** + * MD5 hash algorithm. + */ + var MD5 = C_algo.MD5 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0x67452301, 0xefcdab89, + 0x98badcfe, 0x10325476 + ]); + }, + + _doProcessBlock: function (M, offset) { + // Swap endian + for (var i = 0; i < 16; i++) { + // Shortcuts + var offset_i = offset + i; + var M_offset_i = M[offset_i]; + + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ); + } + + // Shortcuts + var H = this._hash.words; + + var M_offset_0 = M[offset + 0]; + var M_offset_1 = M[offset + 1]; + var M_offset_2 = M[offset + 2]; + var M_offset_3 = M[offset + 3]; + var M_offset_4 = M[offset + 4]; + var M_offset_5 = M[offset + 5]; + var M_offset_6 = M[offset + 6]; + var M_offset_7 = M[offset + 7]; + var M_offset_8 = M[offset + 8]; + var M_offset_9 = M[offset + 9]; + var M_offset_10 = M[offset + 10]; + var M_offset_11 = M[offset + 11]; + var M_offset_12 = M[offset + 12]; + var M_offset_13 = M[offset + 13]; + var M_offset_14 = M[offset + 14]; + var M_offset_15 = M[offset + 15]; + + // Working varialbes + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + + // Computation + a = FF(a, b, c, d, M_offset_0, 7, T[0]); + d = FF(d, a, b, c, M_offset_1, 12, T[1]); + c = FF(c, d, a, b, M_offset_2, 17, T[2]); + b = FF(b, c, d, a, M_offset_3, 22, T[3]); + a = FF(a, b, c, d, M_offset_4, 7, T[4]); + d = FF(d, a, b, c, M_offset_5, 12, T[5]); + c = FF(c, d, a, b, M_offset_6, 17, T[6]); + b = FF(b, c, d, a, M_offset_7, 22, T[7]); + a = FF(a, b, c, d, M_offset_8, 7, T[8]); + d = FF(d, a, b, c, M_offset_9, 12, T[9]); + c = FF(c, d, a, b, M_offset_10, 17, T[10]); + b = FF(b, c, d, a, M_offset_11, 22, T[11]); + a = FF(a, b, c, d, M_offset_12, 7, T[12]); + d = FF(d, a, b, c, M_offset_13, 12, T[13]); + c = FF(c, d, a, b, M_offset_14, 17, T[14]); + b = FF(b, c, d, a, M_offset_15, 22, T[15]); + + a = GG(a, b, c, d, M_offset_1, 5, T[16]); + d = GG(d, a, b, c, M_offset_6, 9, T[17]); + c = GG(c, d, a, b, M_offset_11, 14, T[18]); + b = GG(b, c, d, a, M_offset_0, 20, T[19]); + a = GG(a, b, c, d, M_offset_5, 5, T[20]); + d = GG(d, a, b, c, M_offset_10, 9, T[21]); + c = GG(c, d, a, b, M_offset_15, 14, T[22]); + b = GG(b, c, d, a, M_offset_4, 20, T[23]); + a = GG(a, b, c, d, M_offset_9, 5, T[24]); + d = GG(d, a, b, c, M_offset_14, 9, T[25]); + c = GG(c, d, a, b, M_offset_3, 14, T[26]); + b = GG(b, c, d, a, M_offset_8, 20, T[27]); + a = GG(a, b, c, d, M_offset_13, 5, T[28]); + d = GG(d, a, b, c, M_offset_2, 9, T[29]); + c = GG(c, d, a, b, M_offset_7, 14, T[30]); + b = GG(b, c, d, a, M_offset_12, 20, T[31]); + + a = HH(a, b, c, d, M_offset_5, 4, T[32]); + d = HH(d, a, b, c, M_offset_8, 11, T[33]); + c = HH(c, d, a, b, M_offset_11, 16, T[34]); + b = HH(b, c, d, a, M_offset_14, 23, T[35]); + a = HH(a, b, c, d, M_offset_1, 4, T[36]); + d = HH(d, a, b, c, M_offset_4, 11, T[37]); + c = HH(c, d, a, b, M_offset_7, 16, T[38]); + b = HH(b, c, d, a, M_offset_10, 23, T[39]); + a = HH(a, b, c, d, M_offset_13, 4, T[40]); + d = HH(d, a, b, c, M_offset_0, 11, T[41]); + c = HH(c, d, a, b, M_offset_3, 16, T[42]); + b = HH(b, c, d, a, M_offset_6, 23, T[43]); + a = HH(a, b, c, d, M_offset_9, 4, T[44]); + d = HH(d, a, b, c, M_offset_12, 11, T[45]); + c = HH(c, d, a, b, M_offset_15, 16, T[46]); + b = HH(b, c, d, a, M_offset_2, 23, T[47]); + + a = II(a, b, c, d, M_offset_0, 6, T[48]); + d = II(d, a, b, c, M_offset_7, 10, T[49]); + c = II(c, d, a, b, M_offset_14, 15, T[50]); + b = II(b, c, d, a, M_offset_5, 21, T[51]); + a = II(a, b, c, d, M_offset_12, 6, T[52]); + d = II(d, a, b, c, M_offset_3, 10, T[53]); + c = II(c, d, a, b, M_offset_10, 15, T[54]); + b = II(b, c, d, a, M_offset_1, 21, T[55]); + a = II(a, b, c, d, M_offset_8, 6, T[56]); + d = II(d, a, b, c, M_offset_15, 10, T[57]); + c = II(c, d, a, b, M_offset_6, 15, T[58]); + b = II(b, c, d, a, M_offset_13, 21, T[59]); + a = II(a, b, c, d, M_offset_4, 6, T[60]); + d = II(d, a, b, c, M_offset_11, 10, T[61]); + c = II(c, d, a, b, M_offset_2, 15, T[62]); + b = II(b, c, d, a, M_offset_9, 21, T[63]); + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + + var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); + var nBitsTotalL = nBitsTotal; + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ( + (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | + (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00) + ); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | + (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00) + ); + + data.sigBytes = (dataWords.length + 1) * 4; + + // Hash final blocks + this._process(); + + // Shortcuts + var hash = this._hash; + var H = hash.words; + + // Swap endian + for (var i = 0; i < 4; i++) { + // Shortcut + var H_i = H[i]; + + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); + } + + // Return final computed hash + return hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + function FF(a, b, c, d, x, s, t) { + var n = a + ((b & c) | (~b & d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function GG(a, b, c, d, x, s, t) { + var n = a + ((b & d) | (c & ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function HH(a, b, c, d, x, s, t) { + var n = a + (b ^ c ^ d) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + function II(a, b, c, d, x, s, t) { + var n = a + (c ^ (b | ~d)) + x + t; + return ((n << s) | (n >>> (32 - s))) + b; + } + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.MD5('message'); + * var hash = CryptoJS.MD5(wordArray); + */ + C.MD5 = Hasher._createHelper(MD5); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacMD5(message, key); + */ + C.HmacMD5 = Hasher._createHmacHelper(MD5); + }(Math)); + + + return CryptoJS.MD5; + +})); +},{"47":47}],53:[function(require,module,exports){ +;(function (root, factory) { + if (typeof exports === "object") { + // CommonJS + module.exports = exports = factory(require(47)); + } + else if (typeof define === "function" && define.amd) { + // AMD + define(["./core"], factory); + } + else { + // Global (browser) + factory(root.CryptoJS); + } +}(this, function (CryptoJS) { + + (function () { + // Shortcuts + var C = CryptoJS; + var C_lib = C.lib; + var WordArray = C_lib.WordArray; + var Hasher = C_lib.Hasher; + var C_algo = C.algo; + + // Reusable object + var W = []; + + /** + * SHA-1 hash algorithm. + */ + var SHA1 = C_algo.SHA1 = Hasher.extend({ + _doReset: function () { + this._hash = new WordArray.init([ + 0x67452301, 0xefcdab89, + 0x98badcfe, 0x10325476, + 0xc3d2e1f0 + ]); + }, + + _doProcessBlock: function (M, offset) { + // Shortcut + var H = this._hash.words; + + // Working variables + var a = H[0]; + var b = H[1]; + var c = H[2]; + var d = H[3]; + var e = H[4]; + + // Computation + for (var i = 0; i < 80; i++) { + if (i < 16) { + W[i] = M[offset + i] | 0; + } else { + var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; + W[i] = (n << 1) | (n >>> 31); + } + + var t = ((a << 5) | (a >>> 27)) + e + W[i]; + if (i < 20) { + t += ((b & c) | (~b & d)) + 0x5a827999; + } else if (i < 40) { + t += (b ^ c ^ d) + 0x6ed9eba1; + } else if (i < 60) { + t += ((b & c) | (b & d) | (c & d)) - 0x70e44324; + } else /* if (i < 80) */ { + t += (b ^ c ^ d) - 0x359d3e2a; + } + + e = d; + d = c; + c = (b << 30) | (b >>> 2); + b = a; + a = t; + } + + // Intermediate hash value + H[0] = (H[0] + a) | 0; + H[1] = (H[1] + b) | 0; + H[2] = (H[2] + c) | 0; + H[3] = (H[3] + d) | 0; + H[4] = (H[4] + e) | 0; + }, + + _doFinalize: function () { + // Shortcuts + var data = this._data; + var dataWords = data.words; + + var nBitsTotal = this._nDataBytes * 8; + var nBitsLeft = data.sigBytes * 8; + + // Add padding + dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); + dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; + data.sigBytes = dataWords.length * 4; + + // Hash final blocks + this._process(); + + // Return final computed hash + return this._hash; + }, + + clone: function () { + var clone = Hasher.clone.call(this); + clone._hash = this._hash.clone(); + + return clone; + } + }); + + /** + * Shortcut function to the hasher's object interface. + * + * @param {WordArray|string} message The message to hash. + * + * @return {WordArray} The hash. + * + * @static + * + * @example + * + * var hash = CryptoJS.SHA1('message'); + * var hash = CryptoJS.SHA1(wordArray); + */ + C.SHA1 = Hasher._createHelper(SHA1); + + /** + * Shortcut function to the HMAC's object interface. + * + * @param {WordArray|string} message The message to hash. + * @param {WordArray|string} key The secret key. + * + * @return {WordArray} The HMAC. + * + * @static + * + * @example + * + * var hmac = CryptoJS.HmacSHA1(message, key); + */ + C.HmacSHA1 = Hasher._createHmacHelper(SHA1); + }()); + + + return CryptoJS.SHA1; + +})); +},{"47":47}],54:[function(require,module,exports){ +var pSlice = Array.prototype.slice; +var objectKeys = require(56); +var isArguments = require(55); + +var deepEqual = module.exports = function (actual, expected, opts) { + if (!opts) opts = {}; + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') { + return opts.strict ? actual === expected : actual == expected; + + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected, opts); + } +} + +function isUndefinedOrNull(value) { + return value === null || value === undefined; +} + +function isBuffer (x) { + if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false; + if (typeof x.copy !== 'function' || typeof x.slice !== 'function') { + return false; + } + if (x.length > 0 && typeof x[0] !== 'number') return false; + return true; +} + +function objEquiv(a, b, opts) { + var i, key; + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return deepEqual(a, b, opts); + } + if (isBuffer(a)) { + if (!isBuffer(b)) { + return false; + } + if (a.length !== b.length) return false; + for (i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false; + } + return true; + } + try { + var ka = objectKeys(a), + kb = objectKeys(b); + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!deepEqual(a[key], b[key], opts)) return false; + } + return typeof a === typeof b; +} + +},{"55":55,"56":56}],55:[function(require,module,exports){ +var supportsArgumentsClass = (function(){ + return Object.prototype.toString.call(arguments) +})() == '[object Arguments]'; + +exports = module.exports = supportsArgumentsClass ? supported : unsupported; + +exports.supported = supported; +function supported(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +}; + +exports.unsupported = unsupported; +function unsupported(object){ + return object && + typeof object == 'object' && + typeof object.length == 'number' && + Object.prototype.hasOwnProperty.call(object, 'callee') && + !Object.prototype.propertyIsEnumerable.call(object, 'callee') || + false; +}; + +},{}],56:[function(require,module,exports){ +exports = module.exports = typeof Object.keys === 'function' + ? Object.keys : shim; + +exports.shim = shim; +function shim (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +} + +},{}],57:[function(require,module,exports){ +var assert = require(27) +var BigInteger = require(32) + +var Point = require(61) + +function Curve (p, a, b, Gx, Gy, n, h) { + this.p = p + this.a = a + this.b = b + this.G = Point.fromAffine(this, Gx, Gy) + this.n = n + this.h = h + + this.infinity = new Point(this, null, null, BigInteger.ZERO) + + // result caching + this.pOverFour = p.add(BigInteger.ONE).shiftRight(2) + + // determine size of p in bytes + this.pLength = Math.floor((this.p.bitLength() + 7) / 8) +} + +Curve.prototype.pointFromX = function (isOdd, x) { + var alpha = x.pow(3).add(this.a.multiply(x)).add(this.b).mod(this.p) + var beta = alpha.modPow(this.pOverFour, this.p) // XXX: not compatible with all curves + + var y = beta + if (beta.isEven() ^ !isOdd) { + y = this.p.subtract(y) // -y % p + } + + return Point.fromAffine(this, x, y) +} + +Curve.prototype.isInfinity = function (Q) { + if (Q === this.infinity) return true + + return Q.z.signum() === 0 && Q.y.signum() !== 0 +} + +Curve.prototype.isOnCurve = function (Q) { + if (this.isInfinity(Q)) return true + + var x = Q.affineX + var y = Q.affineY + var a = this.a + var b = this.b + var p = this.p + + // Check that xQ and yQ are integers in the interval [0, p - 1] + if (x.signum() < 0 || x.compareTo(p) >= 0) return false + if (y.signum() < 0 || y.compareTo(p) >= 0) return false + + // and check that y^2 = x^3 + ax + b (mod p) + var lhs = y.square().mod(p) + var rhs = x.pow(3).add(a.multiply(x)).add(b).mod(p) + return lhs.equals(rhs) +} + +/** + * Validate an elliptic curve point. + * + * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive + */ +Curve.prototype.validate = function (Q) { + // Check Q != O + assert(!this.isInfinity(Q), 'Point is at infinity') + assert(this.isOnCurve(Q), 'Point is not on the curve') + + // Check nQ = O (where Q is a scalar multiple of G) + var nQ = Q.multiply(this.n) + assert(this.isInfinity(nQ), 'Point is not a scalar multiple of G') + + return true +} + +module.exports = Curve + +},{"27":27,"32":32,"61":61}],58:[function(require,module,exports){ +module.exports={ + "secp128r1": { + "p": "fffffffdffffffffffffffffffffffff", + "a": "fffffffdfffffffffffffffffffffffc", + "b": "e87579c11079f43dd824993c2cee5ed3", + "n": "fffffffe0000000075a30d1b9038a115", + "h": "01", + "Gx": "161ff7528b899b2d0c28607ca52c5b86", + "Gy": "cf5ac8395bafeb13c02da292dded7a83" + }, + "secp160k1": { + "p": "fffffffffffffffffffffffffffffffeffffac73", + "a": "00", + "b": "07", + "n": "0100000000000000000001b8fa16dfab9aca16b6b3", + "h": "01", + "Gx": "3b4c382ce37aa192a4019e763036f4f5dd4d7ebb", + "Gy": "938cf935318fdced6bc28286531733c3f03c4fee" + }, + "secp160r1": { + "p": "ffffffffffffffffffffffffffffffff7fffffff", + "a": "ffffffffffffffffffffffffffffffff7ffffffc", + "b": "1c97befc54bd7a8b65acf89f81d4d4adc565fa45", + "n": "0100000000000000000001f4c8f927aed3ca752257", + "h": "01", + "Gx": "4a96b5688ef573284664698968c38bb913cbfc82", + "Gy": "23a628553168947d59dcc912042351377ac5fb32" + }, + "secp192k1": { + "p": "fffffffffffffffffffffffffffffffffffffffeffffee37", + "a": "00", + "b": "03", + "n": "fffffffffffffffffffffffe26f2fc170f69466a74defd8d", + "h": "01", + "Gx": "db4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d", + "Gy": "9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d" + }, + "secp192r1": { + "p": "fffffffffffffffffffffffffffffffeffffffffffffffff", + "a": "fffffffffffffffffffffffffffffffefffffffffffffffc", + "b": "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", + "n": "ffffffffffffffffffffffff99def836146bc9b1b4d22831", + "h": "01", + "Gx": "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", + "Gy": "07192b95ffc8da78631011ed6b24cdd573f977a11e794811" + }, + "secp256k1": { + "p": "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "a": "00", + "b": "07", + "n": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "h": "01", + "Gx": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + "Gy": "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + }, + "secp256r1": { + "p": "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "a": "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", + "b": "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", + "n": "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + "h": "01", + "Gx": "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", + "Gy": "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + } +} + +},{}],59:[function(require,module,exports){ +var Point = require(61) +var Curve = require(57) + +var getCurveByName = require(60) + +module.exports = { + Curve: Curve, + Point: Point, + getCurveByName: getCurveByName +} + +},{"57":57,"60":60,"61":61}],60:[function(require,module,exports){ +var BigInteger = require(32) + +var curves = require(58) +var Curve = require(57) + +function getCurveByName (name) { + var curve = curves[name] + if (!curve) return null + + var p = new BigInteger(curve.p, 16) + var a = new BigInteger(curve.a, 16) + var b = new BigInteger(curve.b, 16) + var n = new BigInteger(curve.n, 16) + var h = new BigInteger(curve.h, 16) + var Gx = new BigInteger(curve.Gx, 16) + var Gy = new BigInteger(curve.Gy, 16) + + return new Curve(p, a, b, Gx, Gy, n, h) +} + +module.exports = getCurveByName + +},{"32":32,"57":57,"58":58}],61:[function(require,module,exports){ +var assert = require(27) +var Buffer = require(93).Buffer +var BigInteger = require(32) + +var THREE = BigInteger.valueOf(3) + +function Point (curve, x, y, z) { + assert.notStrictEqual(z, undefined, 'Missing Z coordinate') + + this.curve = curve + this.x = x + this.y = y + this.z = z + this._zInv = null + + this.compressed = true +} + +Object.defineProperty(Point.prototype, 'zInv', { + get: function () { + if (this._zInv === null) { + this._zInv = this.z.modInverse(this.curve.p) + } + + return this._zInv + } +}) + +Object.defineProperty(Point.prototype, 'affineX', { + get: function () { + return this.x.multiply(this.zInv).mod(this.curve.p) + } +}) + +Object.defineProperty(Point.prototype, 'affineY', { + get: function () { + return this.y.multiply(this.zInv).mod(this.curve.p) + } +}) + +Point.fromAffine = function (curve, x, y) { + return new Point(curve, x, y, BigInteger.ONE) +} + +Point.prototype.equals = function (other) { + if (other === this) return true + if (this.curve.isInfinity(this)) return this.curve.isInfinity(other) + if (this.curve.isInfinity(other)) return this.curve.isInfinity(this) + + // u = Y2 * Z1 - Y1 * Z2 + var u = other.y.multiply(this.z).subtract(this.y.multiply(other.z)).mod(this.curve.p) + + if (u.signum() !== 0) return false + + // v = X2 * Z1 - X1 * Z2 + var v = other.x.multiply(this.z).subtract(this.x.multiply(other.z)).mod(this.curve.p) + + return v.signum() === 0 +} + +Point.prototype.negate = function () { + var y = this.curve.p.subtract(this.y) + + return new Point(this.curve, this.x, y, this.z) +} + +Point.prototype.add = function (b) { + if (this.curve.isInfinity(this)) return b + if (this.curve.isInfinity(b)) return this + + var x1 = this.x + var y1 = this.y + var x2 = b.x + var y2 = b.y + + // u = Y2 * Z1 - Y1 * Z2 + var u = y2.multiply(this.z).subtract(y1.multiply(b.z)).mod(this.curve.p) + // v = X2 * Z1 - X1 * Z2 + var v = x2.multiply(this.z).subtract(x1.multiply(b.z)).mod(this.curve.p) + + if (v.signum() === 0) { + if (u.signum() === 0) { + return this.twice() // this == b, so double + } + + return this.curve.infinity // this = -b, so infinity + } + + var v2 = v.square() + var v3 = v2.multiply(v) + var x1v2 = x1.multiply(v2) + var zu2 = u.square().multiply(this.z) + + // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) + var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.p) + // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 + var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.p) + // z3 = v^3 * z1 * z2 + var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.p) + + return new Point(this.curve, x3, y3, z3) +} + +Point.prototype.twice = function () { + if (this.curve.isInfinity(this)) return this + if (this.y.signum() === 0) return this.curve.infinity + + var x1 = this.x + var y1 = this.y + + var y1z1 = y1.multiply(this.z).mod(this.curve.p) + var y1sqz1 = y1z1.multiply(y1).mod(this.curve.p) + var a = this.curve.a + + // w = 3 * x1^2 + a * z1^2 + var w = x1.square().multiply(THREE) + + if (a.signum() !== 0) { + w = w.add(this.z.square().multiply(a)) + } + + w = w.mod(this.curve.p) + // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) + var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.p) + // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 + var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.pow(3)).mod(this.curve.p) + // z3 = 8 * (y1 * z1)^3 + var z3 = y1z1.pow(3).shiftLeft(3).mod(this.curve.p) + + return new Point(this.curve, x3, y3, z3) +} + +// Simple NAF (Non-Adjacent Form) multiplication algorithm +// TODO: modularize the multiplication algorithm +Point.prototype.multiply = function (k) { + if (this.curve.isInfinity(this)) return this + if (k.signum() === 0) return this.curve.infinity + + var e = k + var h = e.multiply(THREE) + + var neg = this.negate() + var R = this + + for (var i = h.bitLength() - 2; i > 0; --i) { + var hBit = h.testBit(i) + var eBit = e.testBit(i) + + R = R.twice() + + if (hBit !== eBit) { + R = R.add(hBit ? this : neg) + } + } + + return R +} + +// Compute this*j + x*k (simultaneous multiplication) +Point.prototype.multiplyTwo = function (j, x, k) { + var i = Math.max(j.bitLength(), k.bitLength()) - 1 + var R = this.curve.infinity + var both = this.add(x) + + while (i >= 0) { + var jBit = j.testBit(i) + var kBit = k.testBit(i) + + R = R.twice() + + if (jBit) { + if (kBit) { + R = R.add(both) + } else { + R = R.add(this) + } + } else if (kBit) { + R = R.add(x) + } + --i + } + + return R +} + +Point.prototype.getEncoded = function (compressed) { + if (compressed == null) compressed = this.compressed + if (this.curve.isInfinity(this)) return Buffer.alloc(1, 0) // Infinity point encoded is simply '00' + + var x = this.affineX + var y = this.affineY + var byteLength = this.curve.pLength + var buffer + + // 0x02/0x03 | X + if (compressed) { + buffer = Buffer.allocUnsafe(1 + byteLength) + buffer.writeUInt8(y.isEven() ? 0x02 : 0x03, 0) + + // 0x04 | X | Y + } else { + buffer = Buffer.allocUnsafe(1 + byteLength + byteLength) + buffer.writeUInt8(0x04, 0) + + y.toBuffer(byteLength).copy(buffer, 1 + byteLength) + } + + x.toBuffer(byteLength).copy(buffer, 1) + + return buffer +} + +Point.decodeFrom = function (curve, buffer) { + var type = buffer.readUInt8(0) + var compressed = (type !== 4) + + var byteLength = Math.floor((curve.p.bitLength() + 7) / 8) + var x = BigInteger.fromBuffer(buffer.slice(1, 1 + byteLength)) + + var Q + if (compressed) { + assert.equal(buffer.length, byteLength + 1, 'Invalid sequence length') + assert(type === 0x02 || type === 0x03, 'Invalid sequence tag') + + var isOdd = (type === 0x03) + Q = curve.pointFromX(isOdd, x) + } else { + assert.equal(buffer.length, 1 + byteLength + byteLength, 'Invalid sequence length') + + var y = BigInteger.fromBuffer(buffer.slice(1 + byteLength)) + Q = Point.fromAffine(curve, x, y) + } + + Q.compressed = compressed + return Q +} + +Point.prototype.toString = function () { + if (this.curve.isInfinity(this)) return '(INFINITY)' + + return '(' + this.affineX.toString() + ',' + this.affineY.toString() + ')' +} + +module.exports = Point + +},{"27":27,"32":32,"93":93}],62:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + // At least give some kind of context to the user + var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); + err.context = er; + throw err; + } + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; +}; + +EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],63:[function(require,module,exports){ +'use strict' +var Buffer = require(93).Buffer +var Transform = require(103).Transform +var inherits = require(65) + +function throwIfNotStringOrBuffer (val, prefix) { + if (!Buffer.isBuffer(val) && typeof val !== 'string') { + throw new TypeError(prefix + ' must be a string or a buffer') + } +} + +function HashBase (blockSize) { + Transform.call(this) + + this._block = Buffer.allocUnsafe(blockSize) + this._blockSize = blockSize + this._blockOffset = 0 + this._length = [0, 0, 0, 0] + + this._finalized = false +} + +inherits(HashBase, Transform) + +HashBase.prototype._transform = function (chunk, encoding, callback) { + var error = null + try { + this.update(chunk, encoding) + } catch (err) { + error = err + } + + callback(error) +} + +HashBase.prototype._flush = function (callback) { + var error = null + try { + this.push(this.digest()) + } catch (err) { + error = err + } + + callback(error) +} + +HashBase.prototype.update = function (data, encoding) { + throwIfNotStringOrBuffer(data, 'Data') + if (this._finalized) throw new Error('Digest already called') + if (!Buffer.isBuffer(data)) data = Buffer.from(data, encoding) + + // consume data + var block = this._block + var offset = 0 + while (this._blockOffset + data.length - offset >= this._blockSize) { + for (var i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++] + this._update() + this._blockOffset = 0 + } + while (offset < data.length) block[this._blockOffset++] = data[offset++] + + // update length + for (var j = 0, carry = data.length * 8; carry > 0; ++j) { + this._length[j] += carry + carry = (this._length[j] / 0x0100000000) | 0 + if (carry > 0) this._length[j] -= 0x0100000000 * carry + } + + return this +} + +HashBase.prototype._update = function () { + throw new Error('_update is not implemented') +} + +HashBase.prototype.digest = function (encoding) { + if (this._finalized) throw new Error('Digest already called') + this._finalized = true + + var digest = this._digest() + if (encoding !== undefined) digest = digest.toString(encoding) + + // reset state + this._block.fill(0) + this._blockOffset = 0 + for (var i = 0; i < 4; ++i) this._length[i] = 0 + + return digest +} + +HashBase.prototype._digest = function () { + throw new Error('_digest is not implemented') +} + +module.exports = HashBase + +},{"103":103,"65":65,"93":93}],64:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = (nBytes * 8) - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} + +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = (nBytes * 8) - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = ((value * c) - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 +} + +},{}],65:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +},{}],66:[function(require,module,exports){ +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +// The _isBuffer check is for Safari 5-7 support, because it's missing +// Object.prototype.constructor. Remove this eventually +module.exports = function (obj) { + return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) +} + +function isBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} + +// For Node v0.10 support. Remove this eventually. +function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) +} + +},{}],67:[function(require,module,exports){ +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + +},{}],68:[function(require,module,exports){ +/* + Copyright 2013 Daniel Wirtz + Copyright 2009 The Closure Library Authors. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS-IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +/** + * @license long.js (c) 2013 Daniel Wirtz + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/long.js for details + */ +(function(global, factory) { + + /* AMD */ if (typeof define === 'function' && define["amd"]) + define([], factory); + /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"]) + module["exports"] = factory(); + /* Global */ else + (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory(); + +})(this, function() { + "use strict"; + + /** + * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers. + * See the from* functions below for more convenient ways of constructing Longs. + * @exports Long + * @class A Long class for representing a 64 bit two's-complement integer value. + * @param {number} low The low (signed) 32 bits of the long + * @param {number} high The high (signed) 32 bits of the long + * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed + * @constructor + */ + function Long(low, high, unsigned) { + + /** + * The low 32 bits as a signed value. + * @type {number} + */ + this.low = low | 0; + + /** + * The high 32 bits as a signed value. + * @type {number} + */ + this.high = high | 0; + + /** + * Whether unsigned or not. + * @type {boolean} + */ + this.unsigned = !!unsigned; + } + + // The internal representation of a long is the two given signed, 32-bit values. + // We use 32-bit pieces because these are the size of integers on which + // Javascript performs bit-operations. For operations like addition and + // multiplication, we split each number into 16 bit pieces, which can easily be + // multiplied within Javascript's floating-point representation without overflow + // or change in sign. + // + // In the algorithms below, we frequently reduce the negative case to the + // positive case by negating the input(s) and then post-processing the result. + // Note that we must ALWAYS check specially whether those values are MIN_VALUE + // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as + // a positive number, it overflows back into a negative). Not handling this + // case would often result in infinite recursion. + // + // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from* + // methods on which they depend. + + /** + * An indicator used to reliably determine if an object is a Long or not. + * @type {boolean} + * @const + * @private + */ + Long.prototype.__isLong__; + + Object.defineProperty(Long.prototype, "__isLong__", { + value: true, + enumerable: false, + configurable: false + }); + + /** + * @function + * @param {*} obj Object + * @returns {boolean} + * @inner + */ + function isLong(obj) { + return (obj && obj["__isLong__"]) === true; + } + + /** + * Tests if the specified object is a Long. + * @function + * @param {*} obj Object + * @returns {boolean} + */ + Long.isLong = isLong; + + /** + * A cache of the Long representations of small integer values. + * @type {!Object} + * @inner + */ + var INT_CACHE = {}; + + /** + * A cache of the Long representations of small unsigned integer values. + * @type {!Object} + * @inner + */ + var UINT_CACHE = {}; + + /** + * @param {number} value + * @param {boolean=} unsigned + * @returns {!Long} + * @inner + */ + function fromInt(value, unsigned) { + var obj, cachedObj, cache; + if (unsigned) { + value >>>= 0; + if (cache = (0 <= value && value < 256)) { + cachedObj = UINT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true); + if (cache) + UINT_CACHE[value] = obj; + return obj; + } else { + value |= 0; + if (cache = (-128 <= value && value < 128)) { + cachedObj = INT_CACHE[value]; + if (cachedObj) + return cachedObj; + } + obj = fromBits(value, value < 0 ? -1 : 0, false); + if (cache) + INT_CACHE[value] = obj; + return obj; + } + } + + /** + * Returns a Long representing the given 32 bit integer value. + * @function + * @param {number} value The 32 bit integer in question + * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed + * @returns {!Long} The corresponding Long value + */ + Long.fromInt = fromInt; + + /** + * @param {number} value + * @param {boolean=} unsigned + * @returns {!Long} + * @inner + */ + function fromNumber(value, unsigned) { + if (isNaN(value) || !isFinite(value)) + return unsigned ? UZERO : ZERO; + if (unsigned) { + if (value < 0) + return UZERO; + if (value >= TWO_PWR_64_DBL) + return MAX_UNSIGNED_VALUE; + } else { + if (value <= -TWO_PWR_63_DBL) + return MIN_VALUE; + if (value + 1 >= TWO_PWR_63_DBL) + return MAX_VALUE; + } + if (value < 0) + return fromNumber(-value, unsigned).neg(); + return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned); + } + + /** + * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. + * @function + * @param {number} value The number in question + * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed + * @returns {!Long} The corresponding Long value + */ + Long.fromNumber = fromNumber; + + /** + * @param {number} lowBits + * @param {number} highBits + * @param {boolean=} unsigned + * @returns {!Long} + * @inner + */ + function fromBits(lowBits, highBits, unsigned) { + return new Long(lowBits, highBits, unsigned); + } + + /** + * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is + * assumed to use 32 bits. + * @function + * @param {number} lowBits The low 32 bits + * @param {number} highBits The high 32 bits + * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed + * @returns {!Long} The corresponding Long value + */ + Long.fromBits = fromBits; + + /** + * @function + * @param {number} base + * @param {number} exponent + * @returns {number} + * @inner + */ + var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4) + + /** + * @param {string} str + * @param {(boolean|number)=} unsigned + * @param {number=} radix + * @returns {!Long} + * @inner + */ + function fromString(str, unsigned, radix) { + if (str.length === 0) + throw Error('empty string'); + if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") + return ZERO; + if (typeof unsigned === 'number') { + // For goog.math.long compatibility + radix = unsigned, + unsigned = false; + } else { + unsigned = !! unsigned; + } + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw RangeError('radix'); + + var p; + if ((p = str.indexOf('-')) > 0) + throw Error('interior hyphen'); + else if (p === 0) { + return fromString(str.substring(1), unsigned, radix).neg(); + } + + // Do several (8) digits each time through the loop, so as to + // minimize the calls to the very expensive emulated div. + var radixToPower = fromNumber(pow_dbl(radix, 8)); + + var result = ZERO; + for (var i = 0; i < str.length; i += 8) { + var size = Math.min(8, str.length - i), + value = parseInt(str.substring(i, i + size), radix); + if (size < 8) { + var power = fromNumber(pow_dbl(radix, size)); + result = result.mul(power).add(fromNumber(value)); + } else { + result = result.mul(radixToPower); + result = result.add(fromNumber(value)); + } + } + result.unsigned = unsigned; + return result; + } + + /** + * Returns a Long representation of the given string, written using the specified radix. + * @function + * @param {string} str The textual representation of the Long + * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed + * @param {number=} radix The radix in which the text is written (2-36), defaults to 10 + * @returns {!Long} The corresponding Long value + */ + Long.fromString = fromString; + + /** + * @function + * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val + * @returns {!Long} + * @inner + */ + function fromValue(val) { + if (val /* is compatible */ instanceof Long) + return val; + if (typeof val === 'number') + return fromNumber(val); + if (typeof val === 'string') + return fromString(val); + // Throws for non-objects, converts non-instanceof Long: + return fromBits(val.low, val.high, val.unsigned); + } + + /** + * Converts the specified value to a Long. + * @function + * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value + * @returns {!Long} + */ + Long.fromValue = fromValue; + + // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be + // no runtime penalty for these. + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_16_DBL = 1 << 16; + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_24_DBL = 1 << 24; + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; + + /** + * @type {number} + * @const + * @inner + */ + var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; + + /** + * @type {!Long} + * @const + * @inner + */ + var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL); + + /** + * @type {!Long} + * @inner + */ + var ZERO = fromInt(0); + + /** + * Signed zero. + * @type {!Long} + */ + Long.ZERO = ZERO; + + /** + * @type {!Long} + * @inner + */ + var UZERO = fromInt(0, true); + + /** + * Unsigned zero. + * @type {!Long} + */ + Long.UZERO = UZERO; + + /** + * @type {!Long} + * @inner + */ + var ONE = fromInt(1); + + /** + * Signed one. + * @type {!Long} + */ + Long.ONE = ONE; + + /** + * @type {!Long} + * @inner + */ + var UONE = fromInt(1, true); + + /** + * Unsigned one. + * @type {!Long} + */ + Long.UONE = UONE; + + /** + * @type {!Long} + * @inner + */ + var NEG_ONE = fromInt(-1); + + /** + * Signed negative one. + * @type {!Long} + */ + Long.NEG_ONE = NEG_ONE; + + /** + * @type {!Long} + * @inner + */ + var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false); + + /** + * Maximum signed value. + * @type {!Long} + */ + Long.MAX_VALUE = MAX_VALUE; + + /** + * @type {!Long} + * @inner + */ + var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true); + + /** + * Maximum unsigned value. + * @type {!Long} + */ + Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE; + + /** + * @type {!Long} + * @inner + */ + var MIN_VALUE = fromBits(0, 0x80000000|0, false); + + /** + * Minimum signed value. + * @type {!Long} + */ + Long.MIN_VALUE = MIN_VALUE; + + /** + * @alias Long.prototype + * @inner + */ + var LongPrototype = Long.prototype; + + /** + * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer. + * @returns {number} + */ + LongPrototype.toInt = function toInt() { + return this.unsigned ? this.low >>> 0 : this.low; + }; + + /** + * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa). + * @returns {number} + */ + LongPrototype.toNumber = function toNumber() { + if (this.unsigned) + return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0); + return this.high * TWO_PWR_32_DBL + (this.low >>> 0); + }; + + /** + * Converts the Long to a string written in the specified radix. + * @param {number=} radix Radix (2-36), defaults to 10 + * @returns {string} + * @override + * @throws {RangeError} If `radix` is out of range + */ + LongPrototype.toString = function toString(radix) { + radix = radix || 10; + if (radix < 2 || 36 < radix) + throw RangeError('radix'); + if (this.isZero()) + return '0'; + if (this.isNegative()) { // Unsigned Longs are never negative + if (this.eq(MIN_VALUE)) { + // We need to change the Long value before it can be negated, so we remove + // the bottom-most digit in this base and then recurse to do the rest. + var radixLong = fromNumber(radix), + div = this.div(radixLong), + rem1 = div.mul(radixLong).sub(this); + return div.toString(radix) + rem1.toInt().toString(radix); + } else + return '-' + this.neg().toString(radix); + } + + // Do several (6) digits each time through the loop, so as to + // minimize the calls to the very expensive emulated div. + var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned), + rem = this; + var result = ''; + while (true) { + var remDiv = rem.div(radixToPower), + intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0, + digits = intval.toString(radix); + rem = remDiv; + if (rem.isZero()) + return digits + result; + else { + while (digits.length < 6) + digits = '0' + digits; + result = '' + digits + result; + } + } + }; + + /** + * Gets the high 32 bits as a signed integer. + * @returns {number} Signed high bits + */ + LongPrototype.getHighBits = function getHighBits() { + return this.high; + }; + + /** + * Gets the high 32 bits as an unsigned integer. + * @returns {number} Unsigned high bits + */ + LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() { + return this.high >>> 0; + }; + + /** + * Gets the low 32 bits as a signed integer. + * @returns {number} Signed low bits + */ + LongPrototype.getLowBits = function getLowBits() { + return this.low; + }; + + /** + * Gets the low 32 bits as an unsigned integer. + * @returns {number} Unsigned low bits + */ + LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() { + return this.low >>> 0; + }; + + /** + * Gets the number of bits needed to represent the absolute value of this Long. + * @returns {number} + */ + LongPrototype.getNumBitsAbs = function getNumBitsAbs() { + if (this.isNegative()) // Unsigned Longs are never negative + return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs(); + var val = this.high != 0 ? this.high : this.low; + for (var bit = 31; bit > 0; bit--) + if ((val & (1 << bit)) != 0) + break; + return this.high != 0 ? bit + 33 : bit + 1; + }; + + /** + * Tests if this Long's value equals zero. + * @returns {boolean} + */ + LongPrototype.isZero = function isZero() { + return this.high === 0 && this.low === 0; + }; + + /** + * Tests if this Long's value is negative. + * @returns {boolean} + */ + LongPrototype.isNegative = function isNegative() { + return !this.unsigned && this.high < 0; + }; + + /** + * Tests if this Long's value is positive. + * @returns {boolean} + */ + LongPrototype.isPositive = function isPositive() { + return this.unsigned || this.high >= 0; + }; + + /** + * Tests if this Long's value is odd. + * @returns {boolean} + */ + LongPrototype.isOdd = function isOdd() { + return (this.low & 1) === 1; + }; + + /** + * Tests if this Long's value is even. + * @returns {boolean} + */ + LongPrototype.isEven = function isEven() { + return (this.low & 1) === 0; + }; + + /** + * Tests if this Long's value equals the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.equals = function equals(other) { + if (!isLong(other)) + other = fromValue(other); + if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1) + return false; + return this.high === other.high && this.low === other.low; + }; + + /** + * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.eq = LongPrototype.equals; + + /** + * Tests if this Long's value differs from the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.notEquals = function notEquals(other) { + return !this.eq(/* validates */ other); + }; + + /** + * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.neq = LongPrototype.notEquals; + + /** + * Tests if this Long's value is less than the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.lessThan = function lessThan(other) { + return this.comp(/* validates */ other) < 0; + }; + + /** + * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.lt = LongPrototype.lessThan; + + /** + * Tests if this Long's value is less than or equal the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) { + return this.comp(/* validates */ other) <= 0; + }; + + /** + * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.lte = LongPrototype.lessThanOrEqual; + + /** + * Tests if this Long's value is greater than the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.greaterThan = function greaterThan(other) { + return this.comp(/* validates */ other) > 0; + }; + + /** + * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.gt = LongPrototype.greaterThan; + + /** + * Tests if this Long's value is greater than or equal the specified's. + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) { + return this.comp(/* validates */ other) >= 0; + }; + + /** + * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}. + * @function + * @param {!Long|number|string} other Other value + * @returns {boolean} + */ + LongPrototype.gte = LongPrototype.greaterThanOrEqual; + + /** + * Compares this Long's value with the specified's. + * @param {!Long|number|string} other Other value + * @returns {number} 0 if they are the same, 1 if the this is greater and -1 + * if the given one is greater + */ + LongPrototype.compare = function compare(other) { + if (!isLong(other)) + other = fromValue(other); + if (this.eq(other)) + return 0; + var thisNeg = this.isNegative(), + otherNeg = other.isNegative(); + if (thisNeg && !otherNeg) + return -1; + if (!thisNeg && otherNeg) + return 1; + // At this point the sign bits are the same + if (!this.unsigned) + return this.sub(other).isNegative() ? -1 : 1; + // Both are positive if at least one is unsigned + return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1; + }; + + /** + * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}. + * @function + * @param {!Long|number|string} other Other value + * @returns {number} 0 if they are the same, 1 if the this is greater and -1 + * if the given one is greater + */ + LongPrototype.comp = LongPrototype.compare; + + /** + * Negates this Long's value. + * @returns {!Long} Negated Long + */ + LongPrototype.negate = function negate() { + if (!this.unsigned && this.eq(MIN_VALUE)) + return MIN_VALUE; + return this.not().add(ONE); + }; + + /** + * Negates this Long's value. This is an alias of {@link Long#negate}. + * @function + * @returns {!Long} Negated Long + */ + LongPrototype.neg = LongPrototype.negate; + + /** + * Returns the sum of this and the specified Long. + * @param {!Long|number|string} addend Addend + * @returns {!Long} Sum + */ + LongPrototype.add = function add(addend) { + if (!isLong(addend)) + addend = fromValue(addend); + + // Divide each number into 4 chunks of 16 bits, and then sum the chunks. + + var a48 = this.high >>> 16; + var a32 = this.high & 0xFFFF; + var a16 = this.low >>> 16; + var a00 = this.low & 0xFFFF; + + var b48 = addend.high >>> 16; + var b32 = addend.high & 0xFFFF; + var b16 = addend.low >>> 16; + var b00 = addend.low & 0xFFFF; + + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 + b00; + c16 += c00 >>> 16; + c00 &= 0xFFFF; + c16 += a16 + b16; + c32 += c16 >>> 16; + c16 &= 0xFFFF; + c32 += a32 + b32; + c48 += c32 >>> 16; + c32 &= 0xFFFF; + c48 += a48 + b48; + c48 &= 0xFFFF; + return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned); + }; + + /** + * Returns the difference of this and the specified Long. + * @param {!Long|number|string} subtrahend Subtrahend + * @returns {!Long} Difference + */ + LongPrototype.subtract = function subtract(subtrahend) { + if (!isLong(subtrahend)) + subtrahend = fromValue(subtrahend); + return this.add(subtrahend.neg()); + }; + + /** + * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}. + * @function + * @param {!Long|number|string} subtrahend Subtrahend + * @returns {!Long} Difference + */ + LongPrototype.sub = LongPrototype.subtract; + + /** + * Returns the product of this and the specified Long. + * @param {!Long|number|string} multiplier Multiplier + * @returns {!Long} Product + */ + LongPrototype.multiply = function multiply(multiplier) { + if (this.isZero()) + return ZERO; + if (!isLong(multiplier)) + multiplier = fromValue(multiplier); + if (multiplier.isZero()) + return ZERO; + if (this.eq(MIN_VALUE)) + return multiplier.isOdd() ? MIN_VALUE : ZERO; + if (multiplier.eq(MIN_VALUE)) + return this.isOdd() ? MIN_VALUE : ZERO; + + if (this.isNegative()) { + if (multiplier.isNegative()) + return this.neg().mul(multiplier.neg()); + else + return this.neg().mul(multiplier).neg(); + } else if (multiplier.isNegative()) + return this.mul(multiplier.neg()).neg(); + + // If both longs are small, use float multiplication + if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24)) + return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned); + + // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products. + // We can skip products that would overflow. + + var a48 = this.high >>> 16; + var a32 = this.high & 0xFFFF; + var a16 = this.low >>> 16; + var a00 = this.low & 0xFFFF; + + var b48 = multiplier.high >>> 16; + var b32 = multiplier.high & 0xFFFF; + var b16 = multiplier.low >>> 16; + var b00 = multiplier.low & 0xFFFF; + + var c48 = 0, c32 = 0, c16 = 0, c00 = 0; + c00 += a00 * b00; + c16 += c00 >>> 16; + c00 &= 0xFFFF; + c16 += a16 * b00; + c32 += c16 >>> 16; + c16 &= 0xFFFF; + c16 += a00 * b16; + c32 += c16 >>> 16; + c16 &= 0xFFFF; + c32 += a32 * b00; + c48 += c32 >>> 16; + c32 &= 0xFFFF; + c32 += a16 * b16; + c48 += c32 >>> 16; + c32 &= 0xFFFF; + c32 += a00 * b32; + c48 += c32 >>> 16; + c32 &= 0xFFFF; + c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; + c48 &= 0xFFFF; + return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned); + }; + + /** + * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}. + * @function + * @param {!Long|number|string} multiplier Multiplier + * @returns {!Long} Product + */ + LongPrototype.mul = LongPrototype.multiply; + + /** + * Returns this Long divided by the specified. The result is signed if this Long is signed or + * unsigned if this Long is unsigned. + * @param {!Long|number|string} divisor Divisor + * @returns {!Long} Quotient + */ + LongPrototype.divide = function divide(divisor) { + if (!isLong(divisor)) + divisor = fromValue(divisor); + if (divisor.isZero()) + throw Error('division by zero'); + if (this.isZero()) + return this.unsigned ? UZERO : ZERO; + var approx, rem, res; + if (!this.unsigned) { + // This section is only relevant for signed longs and is derived from the + // closure library as a whole. + if (this.eq(MIN_VALUE)) { + if (divisor.eq(ONE) || divisor.eq(NEG_ONE)) + return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE + else if (divisor.eq(MIN_VALUE)) + return ONE; + else { + // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. + var halfThis = this.shr(1); + approx = halfThis.div(divisor).shl(1); + if (approx.eq(ZERO)) { + return divisor.isNegative() ? ONE : NEG_ONE; + } else { + rem = this.sub(divisor.mul(approx)); + res = approx.add(rem.div(divisor)); + return res; + } + } + } else if (divisor.eq(MIN_VALUE)) + return this.unsigned ? UZERO : ZERO; + if (this.isNegative()) { + if (divisor.isNegative()) + return this.neg().div(divisor.neg()); + return this.neg().div(divisor).neg(); + } else if (divisor.isNegative()) + return this.div(divisor.neg()).neg(); + res = ZERO; + } else { + // The algorithm below has not been made for unsigned longs. It's therefore + // required to take special care of the MSB prior to running it. + if (!divisor.unsigned) + divisor = divisor.toUnsigned(); + if (divisor.gt(this)) + return UZERO; + if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true + return UONE; + res = UZERO; + } + + // Repeat the following until the remainder is less than other: find a + // floating-point that approximates remainder / other *from below*, add this + // into the result, and subtract it from the remainder. It is critical that + // the approximate value is less than or equal to the real value so that the + // remainder never becomes negative. + rem = this; + while (rem.gte(divisor)) { + // Approximate the result of division. This may be a little greater or + // smaller than the actual value. + approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber())); + + // We will tweak the approximate result by changing it in the 48-th digit or + // the smallest non-fractional digit, whichever is larger. + var log2 = Math.ceil(Math.log(approx) / Math.LN2), + delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48), + + // Decrease the approximation until it is smaller than the remainder. Note + // that if it is too large, the product overflows and is negative. + approxRes = fromNumber(approx), + approxRem = approxRes.mul(divisor); + while (approxRem.isNegative() || approxRem.gt(rem)) { + approx -= delta; + approxRes = fromNumber(approx, this.unsigned); + approxRem = approxRes.mul(divisor); + } + + // We know the answer can't be zero... and actually, zero would cause + // infinite recursion since we would make no progress. + if (approxRes.isZero()) + approxRes = ONE; + + res = res.add(approxRes); + rem = rem.sub(approxRem); + } + return res; + }; + + /** + * Returns this Long divided by the specified. This is an alias of {@link Long#divide}. + * @function + * @param {!Long|number|string} divisor Divisor + * @returns {!Long} Quotient + */ + LongPrototype.div = LongPrototype.divide; + + /** + * Returns this Long modulo the specified. + * @param {!Long|number|string} divisor Divisor + * @returns {!Long} Remainder + */ + LongPrototype.modulo = function modulo(divisor) { + if (!isLong(divisor)) + divisor = fromValue(divisor); + return this.sub(this.div(divisor).mul(divisor)); + }; + + /** + * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}. + * @function + * @param {!Long|number|string} divisor Divisor + * @returns {!Long} Remainder + */ + LongPrototype.mod = LongPrototype.modulo; + + /** + * Returns the bitwise NOT of this Long. + * @returns {!Long} + */ + LongPrototype.not = function not() { + return fromBits(~this.low, ~this.high, this.unsigned); + }; + + /** + * Returns the bitwise AND of this Long and the specified. + * @param {!Long|number|string} other Other Long + * @returns {!Long} + */ + LongPrototype.and = function and(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low & other.low, this.high & other.high, this.unsigned); + }; + + /** + * Returns the bitwise OR of this Long and the specified. + * @param {!Long|number|string} other Other Long + * @returns {!Long} + */ + LongPrototype.or = function or(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low | other.low, this.high | other.high, this.unsigned); + }; + + /** + * Returns the bitwise XOR of this Long and the given one. + * @param {!Long|number|string} other Other Long + * @returns {!Long} + */ + LongPrototype.xor = function xor(other) { + if (!isLong(other)) + other = fromValue(other); + return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned); + }; + + /** + * Returns this Long with bits shifted to the left by the given amount. + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shiftLeft = function shiftLeft(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned); + else + return fromBits(0, this.low << (numBits - 32), this.unsigned); + }; + + /** + * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}. + * @function + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shl = LongPrototype.shiftLeft; + + /** + * Returns this Long with bits arithmetically shifted to the right by the given amount. + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shiftRight = function shiftRight(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + if ((numBits &= 63) === 0) + return this; + else if (numBits < 32) + return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned); + else + return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned); + }; + + /** + * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}. + * @function + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shr = LongPrototype.shiftRight; + + /** + * Returns this Long with bits logically shifted to the right by the given amount. + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) { + if (isLong(numBits)) + numBits = numBits.toInt(); + numBits &= 63; + if (numBits === 0) + return this; + else { + var high = this.high; + if (numBits < 32) { + var low = this.low; + return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned); + } else if (numBits === 32) + return fromBits(high, 0, this.unsigned); + else + return fromBits(high >>> (numBits - 32), 0, this.unsigned); + } + }; + + /** + * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}. + * @function + * @param {number|!Long} numBits Number of bits + * @returns {!Long} Shifted Long + */ + LongPrototype.shru = LongPrototype.shiftRightUnsigned; + + /** + * Converts this Long to signed. + * @returns {!Long} Signed long + */ + LongPrototype.toSigned = function toSigned() { + if (!this.unsigned) + return this; + return fromBits(this.low, this.high, false); + }; + + /** + * Converts this Long to unsigned. + * @returns {!Long} Unsigned long + */ + LongPrototype.toUnsigned = function toUnsigned() { + if (this.unsigned) + return this; + return fromBits(this.low, this.high, true); + }; + + /** + * Converts this Long to its byte representation. + * @param {boolean=} le Whether little or big endian, defaults to big endian + * @returns {!Array.} Byte representation + */ + LongPrototype.toBytes = function(le) { + return le ? this.toBytesLE() : this.toBytesBE(); + } + + /** + * Converts this Long to its little endian byte representation. + * @returns {!Array.} Little endian byte representation + */ + LongPrototype.toBytesLE = function() { + var hi = this.high, + lo = this.low; + return [ + lo & 0xff, + (lo >>> 8) & 0xff, + (lo >>> 16) & 0xff, + (lo >>> 24) & 0xff, + hi & 0xff, + (hi >>> 8) & 0xff, + (hi >>> 16) & 0xff, + (hi >>> 24) & 0xff + ]; + } + + /** + * Converts this Long to its big endian byte representation. + * @returns {!Array.} Big endian byte representation + */ + LongPrototype.toBytesBE = function() { + var hi = this.high, + lo = this.low; + return [ + (hi >>> 24) & 0xff, + (hi >>> 16) & 0xff, + (hi >>> 8) & 0xff, + hi & 0xff, + (lo >>> 24) & 0xff, + (lo >>> 16) & 0xff, + (lo >>> 8) & 0xff, + lo & 0xff + ]; + } + + return Long; +}); + +},{}],69:[function(require,module,exports){ +(function (Buffer){ +'use strict' +var inherits = require(65) +var HashBase = require(63) + +var ARRAY16 = new Array(16) + +function MD5 () { + HashBase.call(this, 64) + + // state + this._a = 0x67452301 + this._b = 0xefcdab89 + this._c = 0x98badcfe + this._d = 0x10325476 +} + +inherits(MD5, HashBase) + +MD5.prototype._update = function () { + var M = ARRAY16 + for (var i = 0; i < 16; ++i) M[i] = this._block.readInt32LE(i * 4) + + var a = this._a + var b = this._b + var c = this._c + var d = this._d + + a = fnF(a, b, c, d, M[0], 0xd76aa478, 7) + d = fnF(d, a, b, c, M[1], 0xe8c7b756, 12) + c = fnF(c, d, a, b, M[2], 0x242070db, 17) + b = fnF(b, c, d, a, M[3], 0xc1bdceee, 22) + a = fnF(a, b, c, d, M[4], 0xf57c0faf, 7) + d = fnF(d, a, b, c, M[5], 0x4787c62a, 12) + c = fnF(c, d, a, b, M[6], 0xa8304613, 17) + b = fnF(b, c, d, a, M[7], 0xfd469501, 22) + a = fnF(a, b, c, d, M[8], 0x698098d8, 7) + d = fnF(d, a, b, c, M[9], 0x8b44f7af, 12) + c = fnF(c, d, a, b, M[10], 0xffff5bb1, 17) + b = fnF(b, c, d, a, M[11], 0x895cd7be, 22) + a = fnF(a, b, c, d, M[12], 0x6b901122, 7) + d = fnF(d, a, b, c, M[13], 0xfd987193, 12) + c = fnF(c, d, a, b, M[14], 0xa679438e, 17) + b = fnF(b, c, d, a, M[15], 0x49b40821, 22) + + a = fnG(a, b, c, d, M[1], 0xf61e2562, 5) + d = fnG(d, a, b, c, M[6], 0xc040b340, 9) + c = fnG(c, d, a, b, M[11], 0x265e5a51, 14) + b = fnG(b, c, d, a, M[0], 0xe9b6c7aa, 20) + a = fnG(a, b, c, d, M[5], 0xd62f105d, 5) + d = fnG(d, a, b, c, M[10], 0x02441453, 9) + c = fnG(c, d, a, b, M[15], 0xd8a1e681, 14) + b = fnG(b, c, d, a, M[4], 0xe7d3fbc8, 20) + a = fnG(a, b, c, d, M[9], 0x21e1cde6, 5) + d = fnG(d, a, b, c, M[14], 0xc33707d6, 9) + c = fnG(c, d, a, b, M[3], 0xf4d50d87, 14) + b = fnG(b, c, d, a, M[8], 0x455a14ed, 20) + a = fnG(a, b, c, d, M[13], 0xa9e3e905, 5) + d = fnG(d, a, b, c, M[2], 0xfcefa3f8, 9) + c = fnG(c, d, a, b, M[7], 0x676f02d9, 14) + b = fnG(b, c, d, a, M[12], 0x8d2a4c8a, 20) + + a = fnH(a, b, c, d, M[5], 0xfffa3942, 4) + d = fnH(d, a, b, c, M[8], 0x8771f681, 11) + c = fnH(c, d, a, b, M[11], 0x6d9d6122, 16) + b = fnH(b, c, d, a, M[14], 0xfde5380c, 23) + a = fnH(a, b, c, d, M[1], 0xa4beea44, 4) + d = fnH(d, a, b, c, M[4], 0x4bdecfa9, 11) + c = fnH(c, d, a, b, M[7], 0xf6bb4b60, 16) + b = fnH(b, c, d, a, M[10], 0xbebfbc70, 23) + a = fnH(a, b, c, d, M[13], 0x289b7ec6, 4) + d = fnH(d, a, b, c, M[0], 0xeaa127fa, 11) + c = fnH(c, d, a, b, M[3], 0xd4ef3085, 16) + b = fnH(b, c, d, a, M[6], 0x04881d05, 23) + a = fnH(a, b, c, d, M[9], 0xd9d4d039, 4) + d = fnH(d, a, b, c, M[12], 0xe6db99e5, 11) + c = fnH(c, d, a, b, M[15], 0x1fa27cf8, 16) + b = fnH(b, c, d, a, M[2], 0xc4ac5665, 23) + + a = fnI(a, b, c, d, M[0], 0xf4292244, 6) + d = fnI(d, a, b, c, M[7], 0x432aff97, 10) + c = fnI(c, d, a, b, M[14], 0xab9423a7, 15) + b = fnI(b, c, d, a, M[5], 0xfc93a039, 21) + a = fnI(a, b, c, d, M[12], 0x655b59c3, 6) + d = fnI(d, a, b, c, M[3], 0x8f0ccc92, 10) + c = fnI(c, d, a, b, M[10], 0xffeff47d, 15) + b = fnI(b, c, d, a, M[1], 0x85845dd1, 21) + a = fnI(a, b, c, d, M[8], 0x6fa87e4f, 6) + d = fnI(d, a, b, c, M[15], 0xfe2ce6e0, 10) + c = fnI(c, d, a, b, M[6], 0xa3014314, 15) + b = fnI(b, c, d, a, M[13], 0x4e0811a1, 21) + a = fnI(a, b, c, d, M[4], 0xf7537e82, 6) + d = fnI(d, a, b, c, M[11], 0xbd3af235, 10) + c = fnI(c, d, a, b, M[2], 0x2ad7d2bb, 15) + b = fnI(b, c, d, a, M[9], 0xeb86d391, 21) + + this._a = (this._a + a) | 0 + this._b = (this._b + b) | 0 + this._c = (this._c + c) | 0 + this._d = (this._d + d) | 0 +} + +MD5.prototype._digest = function () { + // create padding and handle blocks + this._block[this._blockOffset++] = 0x80 + if (this._blockOffset > 56) { + this._block.fill(0, this._blockOffset, 64) + this._update() + this._blockOffset = 0 + } + + this._block.fill(0, this._blockOffset, 56) + this._block.writeUInt32LE(this._length[0], 56) + this._block.writeUInt32LE(this._length[1], 60) + this._update() + + // produce result + var buffer = new Buffer(16) + buffer.writeInt32LE(this._a, 0) + buffer.writeInt32LE(this._b, 4) + buffer.writeInt32LE(this._c, 8) + buffer.writeInt32LE(this._d, 12) + return buffer +} + +function rotl (x, n) { + return (x << n) | (x >>> (32 - n)) +} + +function fnF (a, b, c, d, m, k, s) { + return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + b) | 0 +} + +function fnG (a, b, c, d, m, k, s) { + return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + b) | 0 +} + +function fnH (a, b, c, d, m, k, s) { + return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + b) | 0 +} + +function fnI (a, b, c, d, m, k, s) { + return (rotl((a + ((c ^ (b | (~d)))) + m + k) | 0, s) + b) | 0 +} + +module.exports = MD5 + +}).call(this,require(35).Buffer) + +},{"35":35,"63":63,"65":65}],70:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; +exports.Manager = exports.ChainConfig = exports.Apis = undefined; + +var _ApiInstances = require(71); + +var _ApiInstances2 = _interopRequireDefault(_ApiInstances); + +var _ConnectionManager = require(74); + +var _ConnectionManager2 = _interopRequireDefault(_ConnectionManager); + +var _ChainConfig = require(72); + +var _ChainConfig2 = _interopRequireDefault(_ChainConfig); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.Apis = _ApiInstances2.default; +exports.ChainConfig = _ChainConfig2.default; +exports.Manager = _ConnectionManager2.default; +},{"71":71,"72":72,"74":74}],71:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _ChainWebSocket = require(73); + +var _ChainWebSocket2 = _interopRequireDefault(_ChainWebSocket); + +var _GrapheneApi = require(75); + +var _GrapheneApi2 = _interopRequireDefault(_GrapheneApi); + +var _ChainConfig = require(72); + +var _ChainConfig2 = _interopRequireDefault(_ChainConfig); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var inst = void 0; + +var ApisInstance = function () { + function ApisInstance() { + _classCallCheck(this, ApisInstance); + } + + /** @arg {string} connection .. */ + ApisInstance.prototype.connect = function connect(cs, connectTimeout) { + var _this = this; + + var rpc_user = ''; + var rpc_password = ''; + + if (typeof window !== 'undefined' && window.location && window.location.protocol === 'https:' && cs.indexOf('wss://') < 0) { + throw new Error('Secure domains require wss connection'); + } + + this.ws_rpc = new _ChainWebSocket2.default(cs, this.statusCb, connectTimeout); + + this.init_promise = this.ws_rpc.login(rpc_user, rpc_password).then(function () { + console.log('Connected to API node:', cs); + _this._db = new _GrapheneApi2.default(_this.ws_rpc, 'database'); + _this._net = new _GrapheneApi2.default(_this.ws_rpc, 'network_broadcast'); + _this._hist = new _GrapheneApi2.default(_this.ws_rpc, 'history'); + _this._crypto = new _GrapheneApi2.default(_this.ws_rpc, 'crypto'); + _this._bookie = new _GrapheneApi2.default(_this.ws_rpc, 'bookie'); + var db_promise = _this._db.init().then(function () { + return _this._db.exec('get_chain_id', []).then(function (_chain_id) { + _this.chain_id = _chain_id; + return _ChainConfig2.default.setChainId(_chain_id); + }); + }); + + _this.ws_rpc.on_reconnect = function () { + _this.ws_rpc.login('', '').then(function () { + _this._db.init().then(function () { + if (_this.statusCb) { + _this.statusCb(_ChainWebSocket2.default.status.RECONNECTED); + } + }); + _this._net.init(); + _this._hist.init(); + _this._crypto.init(); + _this._bookie.init(); + }); + }; + + return Promise.all([db_promise, _this._net.init(), _this._hist.init(), + // Temporary squash crypto API error until the API is upgraded everywhere + _this._crypto.init().catch(function (e) { + return console.error('ApiInstance\tCrypto API Error', e); + }), _this._bookie.init()]); + }); + }; + + ApisInstance.prototype.close = function close() { + if (this.ws_rpc) { + this.ws_rpc.close(); + } + + this.ws_rpc = null; + }; + + ApisInstance.prototype.db_api = function db_api() { + return this._db; + }; + + ApisInstance.prototype.network_api = function network_api() { + return this._net; + }; + + ApisInstance.prototype.history_api = function history_api() { + return this._hist; + }; + + ApisInstance.prototype.crypto_api = function crypto_api() { + return this._crypto; + }; + + ApisInstance.prototype.bookie_api = function bookie_api() { + return this._bookie; + }; + + ApisInstance.prototype.setRpcConnectionStatusCallback = function setRpcConnectionStatusCallback(callback) { + this.statusCb = callback; + }; + + return ApisInstance; +}(); + +/** + Configure: configure as follows `Apis.instance("ws://localhost:8090").init_promise`. This + returns a promise, once resolved the connection is ready. + + Import: import { Apis } from "@graphene/chain" + + Short-hand: Apis.db("method", "parm1", 2, 3, ...). Returns a promise with results. + + Additional usage: Apis.instance().db_api().exec("method", ["method", "parm1", 2, 3, ...]). + Returns a promise with results. +*/ + +exports.default = { + setRpcConnectionStatusCallback: function setRpcConnectionStatusCallback(callback) { + this.statusCb = callback; + + if (inst) { + inst.setRpcConnectionStatusCallback(callback); + } + }, + + /** + @arg {string} cs is only provided in the first call + @return {Apis} singleton .. Check Apis.instance().init_promise to + know when the connection is established + */ + reset: function reset() { + var cs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'ws://localhost:8090'; + var connect = arguments[1]; + var connectTimeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4000; + + if (inst) { + inst.close(); + inst = null; + } + + inst = new ApisInstance(); + inst.setRpcConnectionStatusCallback(this.statusCb); + + if (inst && connect) { + inst.connect(cs, connectTimeout); + } + + return inst; + }, + instance: function instance() { + var cs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'ws://localhost:8090'; + var connect = arguments[1]; + var connectTimeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4000; + + if (!inst) { + inst = new ApisInstance(); + inst.setRpcConnectionStatusCallback(this.statusCb); + } + + if (inst && connect) { + inst.connect(cs, connectTimeout); + } + + return inst; + }, + chainId: function chainId() { + return this.instance().chain_id; + }, + close: function close() { + if (inst) { + inst.close(); + inst = null; + } + } + // db: (method, ...args) => Apis.instance().db_api().exec(method, toStrings(args)), + // network: (method, ...args) => Apis.instance().network_api().exec(method, toStrings(args)), + // history: (method, ...args) => Apis.instance().history_api().exec(method, toStrings(args)), + // crypto: (method, ...args) => Apis.instance().crypto_api().exec(method, toStrings(args)) + +}; +},{"72":72,"73":73,"75":75}],72:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var defaults = { + core_asset: 'PPY', + address_prefix: 'PPY', + expire_in_secs: 15, + expire_in_secs_proposal: 24 * 60 * 60, + review_in_secs_committee: 24 * 60 * 60 +}; + +var networks = { + networks: { + Peerplays: { + core_asset: 'PPY', + address_prefix: 'PPY', + chain_id: '6b6b5f0ce7a36d323768e534f3edb41c6d6332a541a95725b98e28d140850134' + }, + PeerplaysTestnet: { + core_asset: 'PPYTEST', + address_prefix: 'PPYTEST', + chain_id: 'be6b79295e728406cbb7494bcb626e62ad278fa4018699cf8f75739f4c1a81fd' + } + } +}; + +var ChainConfig = function () { + function ChainConfig() { + _classCallCheck(this, ChainConfig); + + this.reset(); + } + + ChainConfig.prototype.reset = function reset() { + Object.assign(this, defaults); + }; + + ChainConfig.prototype.setChainId = function setChainId(chainID) { + var ref = Object.keys(networks); + + for (var i = 0, len = ref.length; i < len; i++) { + var network_name = ref[i]; + var network = networks[network_name]; + + if (network.chain_id === chainID) { + this.network_name = network_name; + + if (network.address_prefix) { + this.address_prefix = network.address_prefix; + } + + return { + network_name: network_name, + network: network + }; + } + } + + if (!this.network_name) { + console.log('Unknown chain id (this may be a testnet)', chainID); + } + }; + + ChainConfig.prototype.setPrefix = function setPrefix() { + var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'PPY'; + + this.address_prefix = prefix; + }; + + return ChainConfig; +}(); + +exports.default = new ChainConfig(); +},{}],73:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var SOCKET_DEBUG = false; +var WebSocketClient = null; + +if (typeof WebSocket !== 'undefined') { + WebSocketClient = WebSocket; +} else { + WebSocketClient = require(34); // eslint-disable-line global-require +} + +var SUBSCRIBE_OPERATIONS = ['set_subscribe_callback', 'subscribe_to_market', 'broadcast_transaction_with_callback', 'set_pending_transaction_callback']; + +var UNSUBSCRIBE_OPERATIONS = ['unsubscribe_from_market', 'unsubscribe_from_accounts']; + +var HEALTH_CHECK_INTERVAL = 10000; + +var ChainWebSocket = function () { + /** + *Creates an instance of ChainWebSocket. + * @param {string} serverAddress The address of the websocket to connect to. + * @param {function} statusCb Called when status events occur. + * @param {number} [connectTimeout=10000] The time for a connection attempt to complete. + * @memberof ChainWebSocket + */ + function ChainWebSocket(serverAddress, statusCb) { + var connectTimeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 10000; + + _classCallCheck(this, ChainWebSocket); + + this.statusCb = statusCb; + this.serverAddress = serverAddress; + this.timeoutInterval = connectTimeout; + + // The currenct connection state of the websocket. + this.connected = false; + this.reconnectTimeout = null; + + // Callback to execute when the websocket is reconnected. + this.on_reconnect = null; + + // An incrementing ID for each request so that we can pair it with the + // response from the websocket. + this.cbId = 0; + + // Objects to store key/value pairs for callbacks, subscription callbacks + // and unsubscribe callbacks. + this.cbs = {}; + this.subs = {}; + this.unsub = {}; + + // Current connection promises' rejection + this.currentResolve = null; + this.currentReject = null; + + // Health check for the connection to the BlockChain. + this.healthCheck = null; + + // Copy the constants to this instance. + this.status = ChainWebSocket.status; + + // Bind the functions to the instance. + this.onConnectionOpen = this.onConnectionOpen.bind(this); + this.onConnectionClose = this.onConnectionClose.bind(this); + this.onConnectionTerminate = this.onConnectionTerminate.bind(this); + this.onConnectionError = this.onConnectionError.bind(this); + this.onConnectionTimeout = this.onConnectionTimeout.bind(this); + this.createConnection = this.createConnection.bind(this); + this.createConnectionPromise = this.createConnectionPromise.bind(this); + this.listener = this.listener.bind(this); + + // Create the initial connection the blockchain. + this.createConnection(); + } + + /** + * Create the connection to the Blockchain. + * + * @returns + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.createConnection = function createConnection() { + this.debug('!!! ChainWebSocket create connection'); + + // Clear any possible reconnect timers. + this.reconnectTimeout = null; + + // Create the promise for this connection + if (!this.connect_promise) { + this.connect_promise = new Promise(this.createConnectionPromise); + } + + // Attempt to create the websocket + try { + this.ws = new WebSocketClient(this.serverAddress); + } catch (error) { + // Set a timeout to try and reconnect here. + return this.resetConnection(); + } + + this.addEventListeners(); + + // Handle timeouts to the websocket's initial connection. + this.connectionTimeout = setTimeout(this.onConnectionTimeout, this.timeoutInterval); + }; + + /** + * Reset the connection to the BlockChain. + * + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.resetConnection = function resetConnection() { + // Close the Websocket if its still 'half-open' + this.close(); + + // Make sure we only ever have one timeout running to reconnect. + if (!this.reconnectTimeout) { + this.debug('!!! ChainWebSocket reset connection', this.timeoutInterval); + this.reconnectTimeout = setTimeout(this.createConnection, this.timeoutInterval); + } + + // Reject the current promise if there is one. + if (this.currentReject) { + this.currentReject(new Error('Connection attempt failed: ' + this.serverAddress)); + } + }; + + /** + * Add event listeners to the WebSocket. + * + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.addEventListeners = function addEventListeners() { + this.debug('!!! ChainWebSocket add event listeners'); + this.ws.addEventListener('open', this.onConnectionOpen); + this.ws.addEventListener('close', this.onConnectionClose); + this.ws.addEventListener('error', this.onConnectionError); + this.ws.addEventListener('message', this.listener); + }; + + /** + * Remove the event listers from the WebSocket. Its important to remove the event listerers + * for garbaage collection. Because we are creating a new WebSocket on each connection attempt + * any listeners that are still attached could prevent the old sockets from + * being garbage collected. + * + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.removeEventListeners = function removeEventListeners() { + this.debug('!!! ChainWebSocket remove event listeners'); + this.ws.removeEventListener('open', this.onConnectionOpen); + this.ws.removeEventListener('close', this.onConnectionClose); + this.ws.removeEventListener('error', this.onConnectionError); + this.ws.removeEventListener('message', this.listener); + }; + + /** + * A function that is passed to a new promise that stores the resolve and reject callbacks + * in the state. + * + * @param {function} resolve A callback to be executed when the promise is resolved. + * @param {function} reject A callback to be executed when the promise is rejected. + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.createConnectionPromise = function createConnectionPromise(resolve, reject) { + this.debug('!!! ChainWebSocket createPromise'); + this.currentResolve = resolve; + this.currentReject = reject; + }; + + /** + * Called when a new Websocket connection is opened. + * + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.onConnectionOpen = function onConnectionOpen() { + this.debug('!!! ChainWebSocket Connected '); + + this.connected = true; + + clearTimeout(this.connectionTimeout); + this.connectionTimeout = null; + + // This will trigger the login process as well as some additional setup in ApiInstances + if (this.on_reconnect) { + this.on_reconnect(); + } + + if (this.currentResolve) { + this.currentResolve(); + } + + if (this.statusCb) { + this.statusCb(ChainWebSocket.status.OPEN); + } + }; + + /** + * called when the connection attempt times out. + * + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.onConnectionTimeout = function onConnectionTimeout() { + this.debug('!!! ChainWebSocket timeout'); + this.onConnectionClose(new Error('Connection timed out.')); + }; + + /** + * Called when the Websocket is not responding to the health checks. + * + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.onConnectionTerminate = function onConnectionTerminate() { + this.debug('!!! ChainWebSocket terminate'); + this.onConnectionClose(new Error('Connection was terminated.')); + }; + + /** + * Called when the connection to the Blockchain is closed. + * + * @param {*} error + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.onConnectionClose = function onConnectionClose(error) { + this.debug('!!! ChainWebSocket Close ', error); + + this.resetConnection(); + + if (this.statusCb) { + this.statusCb(ChainWebSocket.status.CLOSED); + } + }; + + /** + * Called when the Websocket encounters an error. + * + * @param {*} error + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.onConnectionError = function onConnectionError(error) { + this.debug('!!! ChainWebSocket On Connection Error ', error); + + this.resetConnection(); + + if (this.statusCb) { + this.statusCb(ChainWebSocket.status.ERROR); + } + }; + + /** + * Entry point to make RPC calls on the BlockChain. + * + * @param {array} params An array of params to be passed to the rpc call. [method, ...params] + * @returns A new promise for this specific call. + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.call = function call(params) { + var _this = this; + + if (!this.connected) { + this.debug('!!! ChainWebSocket Call not connected. '); + return Promise.reject(new Error('Disconnected from the BlockChain.')); + } + + this.debug('!!! ChainWebSocket Call connected. ', params); + + var request = { + method: params[1], + params: params, + id: this.cbId + 1 + }; + + this.cbId = request.id; + + if (SUBSCRIBE_OPERATIONS.includes(request.method)) { + // Store callback in subs map + this.subs[request.id] = { + callback: request.params[2][0] + }; + + // Replace callback with the callback id + request.params[2][0] = request.id; + } + + if (UNSUBSCRIBE_OPERATIONS.includes(request.method)) { + if (typeof request.params[2][0] !== 'function') { + throw new Error('First parameter of unsub must be the original callback'); + } + + var unSubCb = request.params[2].splice(0, 1)[0]; + + // Find the corresponding subscription + for (var id in this.subs) { + // eslint-disable-line + if (this.subs[id].callback === unSubCb) { + this.unsub[request.id] = id; + break; + } + } + } + + if (!this.healthCheck) { + this.healthCheck = setTimeout(this.onConnectionTerminate.bind(this), HEALTH_CHECK_INTERVAL); + } + + return new Promise(function (resolve, reject) { + _this.cbs[request.id] = { + time: new Date(), + resolve: resolve, + reject: reject + }; + + // Set all requests to be 'call' methods. + request.method = 'call'; + + try { + _this.ws.send(JSON.stringify(request)); + } catch (error) { + _this.debug('Caught a nasty error : ', error); + } + }); + }; + + /** + * Called when messages are received on the Websocket. + * + * @param {*} response The message received. + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.listener = function listener(response) { + var responseJSON = null; + + try { + responseJSON = JSON.parse(response.data); + } catch (error) { + responseJSON.error = 'Error parsing response: ' + error.stack; + this.debug('Error parsing response: ', response); + } + + // Clear the health check timeout, we've just received a healthy response from the server. + if (this.healthCheck) { + clearTimeout(this.healthCheck); + this.healthCheck = null; + } + + var sub = false; + var callback = null; + + if (responseJSON.method === 'notice') { + sub = true; + responseJSON.id = responseJSON.params[0]; + } + + if (!sub) { + callback = this.cbs[responseJSON.id]; + } else { + callback = this.subs[responseJSON.id].callback; + } + + if (callback && !sub) { + if (responseJSON.error) { + this.debug('----> responseJSON : ', responseJSON); + callback.reject(responseJSON.error); + } else { + callback.resolve(responseJSON.result); + } + + delete this.cbs[responseJSON.id]; + + if (this.unsub[responseJSON.id]) { + delete this.subs[this.unsub[responseJSON.id]]; + delete this.unsub[responseJSON.id]; + } + } else if (callback && sub) { + callback(responseJSON.params[1]); + } else { + this.debug('Warning: unknown websocket responseJSON: ', responseJSON); + } + }; + + /** + * Login to the Blockchain. + * + * @param {string} user Username + * @param {string} password Password + * @returns A promise that is fulfilled after login. + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.login = function login(user, password) { + var _this2 = this; + + this.debug('!!! ChainWebSocket login.', user, password); + return this.connect_promise.then(function () { + return _this2.call([1, 'login', [user, password]]); + }); + }; + + /** + * Close the connection to the Blockchain. + * + * @memberof ChainWebSocket + */ + + + ChainWebSocket.prototype.close = function close() { + if (this.ws) { + this.removeEventListeners(); + + // Try and fire close on the connection. + this.ws.close(); + + // Clear our references so that it can be garbage collected. + this.ws = null; + } + + // Clear our timeouts for connection timeout and health check. + clearTimeout(this.connectionTimeout); + this.connectionTimeout = null; + + clearTimeout(this.healthCheck); + this.healthCheck = null; + + clearTimeout(this.reconnectTimeout); + this.reconnectTimeout = null; + + // Toggle the connected flag. + this.connected = false; + }; + + ChainWebSocket.prototype.debug = function debug() { + if (SOCKET_DEBUG) { + for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) { + params[_key] = arguments[_key]; + } + + console.log.apply(null, params); + } + }; + + return ChainWebSocket; +}(); + +// Constants for STATE + + +ChainWebSocket.status = { + RECONNECTED: 'reconnected', + OPEN: 'open', + CLOSED: 'closed', + ERROR: 'error' +}; + +exports.default = ChainWebSocket; +},{"34":34}],74:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; + +var _ApiInstances = require(71); + +var _ApiInstances2 = _interopRequireDefault(_ApiInstances); + +var _ChainWebSocket = require(73); + +var _ChainWebSocket2 = _interopRequireDefault(_ChainWebSocket); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Manager = function () { + function Manager(_ref) { + var url = _ref.url, + urls = _ref.urls; + + _classCallCheck(this, Manager); + + this.url = url; + this.urls = urls.filter(function (a) { + return a !== url; + }); + } + + Manager.prototype.logFailure = function logFailure(url) { + console.error('Unable to connect to', url + ', skipping to next full node API server'); + }; + + Manager.prototype.connect = function connect() { + var _connect = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + + var url = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.url; + + return new Promise(function (resolve, reject) { + _ApiInstances2.default.instance(url, _connect).init_promise.then(resolve).catch(function (error) { + _ApiInstances2.default.instance().close(); + reject(error); + }); + }); + }; + + Manager.prototype.connectWithFallback = function connectWithFallback() { + var connect = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + var url = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.url; + var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + + var _this = this; + + var resolve = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + var reject = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; + + if (reject && index > this.urls.length - 1) { + return reject(new Error('Tried ' + (index + 1) + ' connections, none of which worked: ' + JSON.stringify(this.urls.concat(this.url)))); + } + + var fallback = function fallback(resolve, reject) { + _this.logFailure(url); + return _this.connectWithFallback(connect, _this.urls[index], index + 1, resolve, reject); + }; + + if (resolve && reject) { + return this.connect(connect, url).then(resolve).catch(function () { + fallback(resolve, reject); + }); + } + + return new Promise(function (resolve, reject) { + _this.connect(connect).then(resolve).catch(function () { + fallback(resolve, reject); + }); + }); + }; + + Manager.prototype.checkConnections = function checkConnections() { + var rpc_user = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; + var rpc_password = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + var _this2 = this; + + var resolve = arguments[2]; + var reject = arguments[3]; + + var connectionStartTimes = {}; + + var checkFunction = function checkFunction(resolve, reject) { + var fullList = _this2.urls.concat(_this2.url); + var connectionPromises = []; + + fullList.forEach(function (url) { + var conn = new _ChainWebSocket2.default(url, function () {}); + connectionStartTimes[url] = new Date().getTime(); + connectionPromises.push(function () { + return conn.login(rpc_user, rpc_password).then(function () { + var _ref2; + + conn.close(); + return _ref2 = {}, _ref2[url] = new Date().getTime() - connectionStartTimes[url], _ref2; + }).catch(function () { + if (url === _this2.url) { + _this2.url = _this2.urls[0]; + } else { + _this2.urls = _this2.urls.filter(function (a) { + return a !== url; + }); + } + + conn.close(); + return null; + }); + }); + }); + + Promise.all(connectionPromises.map(function (a) { + return a(); + })).then(function (res) { + resolve(res.filter(function (a) { + return !!a; + }).reduce(function (f, a) { + var key = Object.keys(a)[0]; + f[key] = a[key]; + return f; + }, {})); + }).catch(function () { + return _this2.checkConnections(rpc_user, rpc_password, resolve, reject); + }); + }; + + if (resolve && reject) { + checkFunction(resolve, reject); + } else { + return new Promise(checkFunction); + } + }; + + return Manager; +}(); + +exports.default = Manager; +},{"71":71,"73":73}],75:[function(require,module,exports){ +'use strict'; + +exports.__esModule = true; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var GrapheneApi = function () { + function GrapheneApi(ws_rpc, api_name) { + _classCallCheck(this, GrapheneApi); + + this.ws_rpc = ws_rpc; + this.api_name = api_name; + } + + GrapheneApi.prototype.init = function init() { + var _this = this; + + return this.ws_rpc.call([1, this.api_name, []]).then(function (response) { + _this.api_id = response; + return _this; + }); + }; + + GrapheneApi.prototype.exec = function exec(method, params) { + return this.ws_rpc.call([this.api_id, method, params]).catch(function (error) { + console.log('!!! GrapheneApi error: ', method, params, error, JSON.stringify(error)); + throw error; + }); + }; + + return GrapheneApi; +}(); + +exports.default = GrapheneApi; +},{}],76:[function(require,module,exports){ +(function (process){ +'use strict'; + +if (!process.version || + process.version.indexOf('v0.') === 0 || + process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { + module.exports = { nextTick: nextTick }; +} else { + module.exports = process +} + +function nextTick(fn, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); + }); + } +} + + +}).call(this,require(77)) + +},{"77":77}],77:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],78:[function(require,module,exports){ +module.exports = require(79); + +},{"79":79}],79:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +'use strict'; + +/**/ + +var pna = require(76); +/**/ + +/**/ +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; +}; +/**/ + +module.exports = Duplex; + +/**/ +var util = require(40); +util.inherits = require(87); +/**/ + +var Readable = require(81); +var Writable = require(83); + +util.inherits(Duplex, Readable); + +{ + // avoid scope creep, the keys array can then be collected + var keys = objectKeys(Writable.prototype); + for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; + } +} + +function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) this.readable = false; + + if (options && options.writable === false) this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; + + this.once('end', onend); +} + +Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function () { + return this._writableState.highWaterMark; + } +}); + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) return; + + // no more data can be written. + // But allow more writes to happen in this tick. + pna.nextTick(onEndNT, this); +} + +function onEndNT(self) { + self.end(); +} + +Object.defineProperty(Duplex.prototype, 'destroyed', { + get: function () { + if (this._readableState === undefined || this._writableState === undefined) { + return false; + } + return this._readableState.destroyed && this._writableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (this._readableState === undefined || this._writableState === undefined) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + this._writableState.destroyed = value; + } +}); + +Duplex.prototype._destroy = function (err, cb) { + this.push(null); + this.end(); + + pna.nextTick(cb, err); +}; +},{"40":40,"76":76,"81":81,"83":83,"87":87}],80:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +'use strict'; + +module.exports = PassThrough; + +var Transform = require(82); + +/**/ +var util = require(40); +util.inherits = require(87); +/**/ + +util.inherits(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) return new PassThrough(options); + + Transform.call(this, options); +} + +PassThrough.prototype._transform = function (chunk, encoding, cb) { + cb(null, chunk); +}; +},{"40":40,"82":82,"87":87}],81:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +'use strict'; + +/**/ + +var pna = require(76); +/**/ + +module.exports = Readable; + +/**/ +var isArray = require(67); +/**/ + +/**/ +var Duplex; +/**/ + +Readable.ReadableState = ReadableState; + +/**/ +var EE = require(62).EventEmitter; + +var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +/**/ +var Stream = require(86); +/**/ + +/**/ + +var Buffer = require(93).Buffer; +var OurUint8Array = global.Uint8Array || function () {}; +function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); +} +function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; +} + +/**/ + +/**/ +var util = require(40); +util.inherits = require(87); +/**/ + +/**/ +var debugUtil = require(34); +var debug = void 0; +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + +var BufferList = require(84); +var destroyImpl = require(85); +var StringDecoder; + +util.inherits(Readable, Stream); + +var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; + +function prependListener(emitter, event, fn) { + // Sadly this is not cacheable as some libraries bundle their own + // event emitter implementation with them. + if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); + + // This is a hack to make sure that our error handler is attached before any + // userland ones. NEVER DO THIS. This is here only because this code needs + // to continue to work with older versions of Node.js that do not include + // the prependListener() method. The goal is to eventually remove this hack. + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; +} + +function ReadableState(options, stream) { + Duplex = Duplex || require(79); + + options = options || {}; + + // Duplex streams are both readable and writable, but share + // the same options object. + // However, some cases require setting options to different + // values for the readable and the writable sides of the duplex stream. + // These options can be provided separately as readableXXX and writableXXX. + var isDuplex = stream instanceof Duplex; + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var readableHwm = options.readableHighWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + + if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm; + + // cast to ints. + this.highWaterMark = Math.floor(this.highWaterMark); + + // A linked list is used to store data chunks instead of an array because the + // linked list can remove elements from the beginning faster than + // array.shift() + this.buffer = new BufferList(); + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the event 'readable'/'data' is emitted + // immediately, or on a later tick. We set this to true at first, because + // any actions that shouldn't happen until "later" should generally also + // not happen before the first read call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = false; + + // has it been destroyed + this.destroyed = false; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) StringDecoder = require(104).StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + Duplex = Duplex || require(79); + + if (!(this instanceof Readable)) return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + if (options) { + if (typeof options.read === 'function') this._read = options.read; + + if (typeof options.destroy === 'function') this._destroy = options.destroy; + } + + Stream.call(this); +} + +Object.defineProperty(Readable.prototype, 'destroyed', { + get: function () { + if (this._readableState === undefined) { + return false; + } + return this._readableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._readableState) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._readableState.destroyed = value; + } +}); + +Readable.prototype.destroy = destroyImpl.destroy; +Readable.prototype._undestroy = destroyImpl.undestroy; +Readable.prototype._destroy = function (err, cb) { + this.push(null); + cb(err); +}; + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function (chunk, encoding) { + var state = this._readableState; + var skipChunkCheck; + + if (!state.objectMode) { + if (typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = Buffer.from(chunk, encoding); + encoding = ''; + } + skipChunkCheck = true; + } + } else { + skipChunkCheck = true; + } + + return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function (chunk) { + return readableAddChunk(this, chunk, null, true, false); +}; + +function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { + var state = stream._readableState; + if (chunk === null) { + state.reading = false; + onEofChunk(stream, state); + } else { + var er; + if (!skipChunkCheck) er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { + chunk = _uint8ArrayToBuffer(chunk); + } + + if (addToFront) { + if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true); + } else if (state.ended) { + stream.emit('error', new Error('stream.push() after EOF')); + } else { + state.reading = false; + if (state.decoder && !encoding) { + chunk = state.decoder.write(chunk); + if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); + } else { + addChunk(stream, state, chunk, false); + } + } + } else if (!addToFront) { + state.reading = false; + } + } + + return needMoreData(state); +} + +function addChunk(stream, state, chunk, addToFront) { + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); + + if (state.needReadable) emitReadable(stream); + } + maybeReadMore(stream, state); +} + +function chunkInvalid(state, chunk) { + var er; + if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); +} + +Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; +}; + +// backwards compatibility. +Readable.prototype.setEncoding = function (enc) { + if (!StringDecoder) StringDecoder = require(104).StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 8MB +var MAX_HWM = 0x800000; +function computeNewHighWaterMark(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 to prevent increasing hwm excessively in + // tiny amounts + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + return n; +} + +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function howMuchToRead(n, state) { + if (n <= 0 || state.length === 0 && state.ended) return 0; + if (state.objectMode) return 1; + if (n !== n) { + // Only flow one buffer at a time + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; + } + // If we're asking for more than the current hwm, then raise the hwm. + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); + if (n <= state.length) return n; + // Don't have enough + if (!state.ended) { + state.needReadable = true; + return 0; + } + return state.length; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function (n) { + debug('read', n); + n = parseInt(n, 10); + var state = this._readableState; + var nOrig = n; + + if (n !== 0) state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } else if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (!state.reading) n = howMuchToRead(nOrig, state); + } + + var ret; + if (n > 0) ret = fromList(n, state);else ret = null; + + if (ret === null) { + state.needReadable = true; + n = 0; + } else { + state.length -= n; + } + + if (state.length === 0) { + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (!state.ended) state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended) endReadable(this); + } + + if (ret !== null) this.emit('data', ret); + + return ret; +}; + +function onEofChunk(stream, state) { + if (state.ended) return; + if (state.decoder) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + pna.nextTick(maybeReadMore_, stream, state); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break;else len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function (n) { + this.emit('error', new Error('_read() is not implemented')); +}; + +Readable.prototype.pipe = function (dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; + + var endFn = doEnd ? onend : unpipe; + if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable, unpipeInfo) { + debug('onunpipe'); + if (readable === src) { + if (unpipeInfo && unpipeInfo.hasUnpiped === false) { + unpipeInfo.hasUnpiped = true; + cleanup(); + } + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + var cleanedUp = false; + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', unpipe); + src.removeListener('data', ondata); + + cleanedUp = true; + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); + } + + // If the user pushes more data while we're writing to dest then we'll end up + // in ondata again. However, we only want to increase awaitDrain once because + // dest will only emit one 'drain' event for the multiple writes. + // => Introduce a guard on increasing awaitDrain. + var increasedAwaitDrain = false; + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + increasedAwaitDrain = false; + var ret = dest.write(chunk); + if (false === ret && !increasedAwaitDrain) { + // If the user unpiped during `dest.write()`, it is possible + // to get stuck in a permanently paused state if that write + // also returned false. + // => Check whether `dest` is still a piping destination. + if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { + debug('false write response, pause', src._readableState.awaitDrain); + src._readableState.awaitDrain++; + increasedAwaitDrain = true; + } + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); + } + + // Make sure our error handler is attached before userland ones. + prependListener(dest, 'error', onerror); + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function () { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) state.awaitDrain--; + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + +Readable.prototype.unpipe = function (dest) { + var state = this._readableState; + var unpipeInfo = { hasUnpiped: false }; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) return this; + + if (!dest) dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this, unpipeInfo); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) { + dests[i].emit('unpipe', this, unpipeInfo); + }return this; + } + + // try to find the right one. + var index = indexOf(state.pipes, dest); + if (index === -1) return this; + + state.pipes.splice(index, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + + dest.emit('unpipe', this, unpipeInfo); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function (ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + if (ev === 'data') { + // Start flowing on next tick if stream isn't explicitly paused + if (this._readableState.flowing !== false) this.resume(); + } else if (ev === 'readable') { + var state = this._readableState; + if (!state.endEmitted && !state.readableListening) { + state.readableListening = state.needReadable = true; + state.emittedReadable = false; + if (!state.reading) { + pna.nextTick(nReadingNextTick, this); + } else if (state.length) { + emitReadable(this); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); +} + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function () { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + pna.nextTick(resume_, stream, state); + } +} + +function resume_(stream, state) { + if (!state.reading) { + debug('resume read 0'); + stream.read(0); + } + + state.resumeScheduled = false; + state.awaitDrain = 0; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); +} + +Readable.prototype.pause = function () { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + while (state.flowing && stream.read() !== null) {} +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function (stream) { + var _this = this; + + var state = this._readableState; + var paused = false; + + stream.on('end', function () { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) _this.push(chunk); + } + + _this.push(null); + }); + + stream.on('data', function (chunk) { + debug('wrapped data'); + if (state.decoder) chunk = state.decoder.write(chunk); + + // don't skip over falsy values in objectMode + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; + + var ret = _this.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (this[i] === undefined && typeof stream[i] === 'function') { + this[i] = function (method) { + return function () { + return stream[method].apply(stream, arguments); + }; + }(i); + } + } + + // proxy certain important events. + for (var n = 0; n < kProxyEvents.length; n++) { + stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); + } + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + this._read = function (n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return this; +}; + +Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function () { + return this._readableState.highWaterMark; + } +}); + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromList(n, state) { + // nothing buffered + if (state.length === 0) return null; + + var ret; + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { + // read it all, truncate the list + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); + state.buffer.clear(); + } else { + // read part of list + ret = fromListPartial(n, state.buffer, state.decoder); + } + + return ret; +} + +// Extracts only enough buffered data to satisfy the amount requested. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromListPartial(n, list, hasStrings) { + var ret; + if (n < list.head.data.length) { + // slice is the same for buffers and strings + ret = list.head.data.slice(0, n); + list.head.data = list.head.data.slice(n); + } else if (n === list.head.data.length) { + // first chunk is a perfect match + ret = list.shift(); + } else { + // result spans more than one buffer + ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); + } + return ret; +} + +// Copies a specified amount of characters from the list of buffered data +// chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBufferString(n, list) { + var p = list.head; + var c = 1; + var ret = p.data; + n -= ret.length; + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = str.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +// Copies a specified amount of bytes from the list of buffered data chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBuffer(n, list) { + var ret = Buffer.allocUnsafe(n); + var p = list.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = buf.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + pna.nextTick(endReadableNT, state, stream); + } +} + +function endReadableNT(state, stream) { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } +} + +function indexOf(xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} +}).call(this,require(77),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"104":104,"34":34,"40":40,"62":62,"67":67,"76":76,"77":77,"79":79,"84":84,"85":85,"86":86,"87":87,"93":93}],82:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +'use strict'; + +module.exports = Transform; + +var Duplex = require(79); + +/**/ +var util = require(40); +util.inherits = require(87); +/**/ + +util.inherits(Transform, Duplex); + +function afterTransform(er, data) { + var ts = this._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) { + return this.emit('error', new Error('write callback called multiple times')); + } + + ts.writechunk = null; + ts.writecb = null; + + if (data != null) // single equals check for both `null` and `undefined` + this.push(data); + + cb(er); + + var rs = this._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + this._read(rs.highWaterMark); + } +} + +function Transform(options) { + if (!(this instanceof Transform)) return new Transform(options); + + Duplex.call(this, options); + + this._transformState = { + afterTransform: afterTransform.bind(this), + needTransform: false, + transforming: false, + writecb: null, + writechunk: null, + writeencoding: null + }; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + if (options) { + if (typeof options.transform === 'function') this._transform = options.transform; + + if (typeof options.flush === 'function') this._flush = options.flush; + } + + // When the writable side finishes, then flush out anything remaining. + this.on('prefinish', prefinish); +} + +function prefinish() { + var _this = this; + + if (typeof this._flush === 'function') { + this._flush(function (er, data) { + done(_this, er, data); + }); + } else { + done(this, null, null); + } +} + +Transform.prototype.push = function (chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function (chunk, encoding, cb) { + throw new Error('_transform() is not implemented'); +}; + +Transform.prototype._write = function (chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function (n) { + var ts = this._transformState; + + if (ts.writechunk !== null && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + +Transform.prototype._destroy = function (err, cb) { + var _this2 = this; + + Duplex.prototype._destroy.call(this, err, function (err2) { + cb(err2); + _this2.emit('close'); + }); +}; + +function done(stream, er, data) { + if (er) return stream.emit('error', er); + + if (data != null) // single equals check for both `null` and `undefined` + stream.push(data); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0'); + + if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming'); + + return stream.push(null); +} +},{"40":40,"79":79,"87":87}],83:[function(require,module,exports){ +(function (process,global,setImmediate){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, encoding, cb), and it'll handle all +// the drain event emission and buffering. + +'use strict'; + +/**/ + +var pna = require(76); +/**/ + +module.exports = Writable; + +/* */ +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; + this.next = null; +} + +// It seems a linked list but it is not +// there will be only 2 of these for each stream +function CorkedRequest(state) { + var _this = this; + + this.next = null; + this.entry = null; + this.finish = function () { + onCorkedFinish(_this, state); + }; +} +/* */ + +/**/ +var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick; +/**/ + +/**/ +var Duplex; +/**/ + +Writable.WritableState = WritableState; + +/**/ +var util = require(40); +util.inherits = require(87); +/**/ + +/**/ +var internalUtil = { + deprecate: require(106) +}; +/**/ + +/**/ +var Stream = require(86); +/**/ + +/**/ + +var Buffer = require(93).Buffer; +var OurUint8Array = global.Uint8Array || function () {}; +function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); +} +function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; +} + +/**/ + +var destroyImpl = require(85); + +util.inherits(Writable, Stream); + +function nop() {} + +function WritableState(options, stream) { + Duplex = Duplex || require(79); + + options = options || {}; + + // Duplex streams are both readable and writable, but share + // the same options object. + // However, some cases require setting options to different + // values for the readable and the writable sides of the duplex stream. + // These options can be provided separately as readableXXX and writableXXX. + var isDuplex = stream instanceof Duplex; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var writableHwm = options.writableHighWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + + if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm; + + // cast to ints. + this.highWaterMark = Math.floor(this.highWaterMark); + + // if _final has been called + this.finalCalled = false; + + // drain event flag. + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // has it been destroyed + this.destroyed = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.bufferedRequest = null; + this.lastBufferedRequest = null; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; + + // count buffered requests + this.bufferedRequestCount = 0; + + // allocate the first CorkedRequest, there is always + // one allocated and free to use, and we maintain at most two + this.corkedRequestsFree = new CorkedRequest(this); +} + +WritableState.prototype.getBuffer = function getBuffer() { + var current = this.bufferedRequest; + var out = []; + while (current) { + out.push(current); + current = current.next; + } + return out; +}; + +(function () { + try { + Object.defineProperty(WritableState.prototype, 'buffer', { + get: internalUtil.deprecate(function () { + return this.getBuffer(); + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') + }); + } catch (_) {} +})(); + +// Test _writableState for inheritance to account for Duplex streams, +// whose prototype chain only points to Readable. +var realHasInstance; +if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { + realHasInstance = Function.prototype[Symbol.hasInstance]; + Object.defineProperty(Writable, Symbol.hasInstance, { + value: function (object) { + if (realHasInstance.call(this, object)) return true; + if (this !== Writable) return false; + + return object && object._writableState instanceof WritableState; + } + }); +} else { + realHasInstance = function (object) { + return object instanceof this; + }; +} + +function Writable(options) { + Duplex = Duplex || require(79); + + // Writable ctor is applied to Duplexes, too. + // `realHasInstance` is necessary because using plain `instanceof` + // would return false, as no `_writableState` property is attached. + + // Trying to use the custom `instanceof` for Writable here will also break the + // Node.js LazyTransform implementation, which has a non-trivial getter for + // `_writableState` that would lead to infinite recursion. + if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { + return new Writable(options); + } + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + if (options) { + if (typeof options.write === 'function') this._write = options.write; + + if (typeof options.writev === 'function') this._writev = options.writev; + + if (typeof options.destroy === 'function') this._destroy = options.destroy; + + if (typeof options.final === 'function') this._final = options.final; + } + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function () { + this.emit('error', new Error('Cannot pipe, not readable')); +}; + +function writeAfterEnd(stream, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + pna.nextTick(cb, er); +} + +// Checks that a user-supplied chunk is valid, especially for the particular +// mode the stream is in. Currently this means that `null` is never accepted +// and undefined/non-string values are only allowed in object mode. +function validChunk(stream, state, chunk, cb) { + var valid = true; + var er = false; + + if (chunk === null) { + er = new TypeError('May not write null values to stream'); + } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + if (er) { + stream.emit('error', er); + pna.nextTick(cb, er); + valid = false; + } + return valid; +} + +Writable.prototype.write = function (chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + var isBuf = !state.objectMode && _isUint8Array(chunk); + + if (isBuf && !Buffer.isBuffer(chunk)) { + chunk = _uint8ArrayToBuffer(chunk); + } + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; + + if (typeof cb !== 'function') cb = nop; + + if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); + } + + return ret; +}; + +Writable.prototype.cork = function () { + var state = this._writableState; + + state.corked++; +}; + +Writable.prototype.uncork = function () { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); + } +}; + +Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { + // node::ParseEncoding() requires lower case. + if (typeof encoding === 'string') encoding = encoding.toLowerCase(); + if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); + this._writableState.defaultEncoding = encoding; + return this; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding); + } + return chunk; +} + +Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function () { + return this._writableState.highWaterMark; + } +}); + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { + if (!isBuf) { + var newChunk = decodeChunk(state, chunk, encoding); + if (chunk !== newChunk) { + isBuf = true; + encoding = 'buffer'; + chunk = newChunk; + } + } + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) state.needDrain = true; + + if (state.writing || state.corked) { + var last = state.lastBufferedRequest; + state.lastBufferedRequest = { + chunk: chunk, + encoding: encoding, + isBuf: isBuf, + callback: cb, + next: null + }; + if (last) { + last.next = state.lastBufferedRequest; + } else { + state.bufferedRequest = state.lastBufferedRequest; + } + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + + if (sync) { + // defer the callback if we are being called synchronously + // to avoid piling up things on the stack + pna.nextTick(cb, er); + // this can emit finish, and it will always happen + // after error + pna.nextTick(finishMaybe, stream, state); + stream._writableState.errorEmitted = true; + stream.emit('error', er); + } else { + // the caller expect this to happen before if + // it is async + cb(er); + stream._writableState.errorEmitted = true; + stream.emit('error', er); + // this can emit finish, but finish must + // always follow error + finishMaybe(stream, state); + } +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) onwriteError(stream, state, sync, er, cb);else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(state); + + if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { + clearBuffer(stream, state); + } + + if (sync) { + /**/ + asyncWrite(afterWrite, stream, state, finished, cb); + /**/ + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + var entry = state.bufferedRequest; + + if (stream._writev && entry && entry.next) { + // Fast case, write everything using _writev() + var l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + + var count = 0; + var allBuffers = true; + while (entry) { + buffer[count] = entry; + if (!entry.isBuf) allBuffers = false; + entry = entry.next; + count += 1; + } + buffer.allBuffers = allBuffers; + + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is almost always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + if (holder.next) { + state.corkedRequestsFree = holder.next; + holder.next = null; + } else { + state.corkedRequestsFree = new CorkedRequest(state); + } + state.bufferedRequestCount = 0; + } else { + // Slow case, write chunks one-by-one + while (entry) { + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + entry = entry.next; + state.bufferedRequestCount--; + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + break; + } + } + + if (entry === null) state.lastBufferedRequest = null; + } + + state.bufferedRequest = entry; + state.bufferProcessing = false; +} + +Writable.prototype._write = function (chunk, encoding, cb) { + cb(new Error('_write() is not implemented')); +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function (chunk, encoding, cb) { + var state = this._writableState; + + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) endWritable(this, state, cb); +}; + +function needFinish(state) { + return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; +} +function callFinal(stream, state) { + stream._final(function (err) { + state.pendingcb--; + if (err) { + stream.emit('error', err); + } + state.prefinished = true; + stream.emit('prefinish'); + finishMaybe(stream, state); + }); +} +function prefinish(stream, state) { + if (!state.prefinished && !state.finalCalled) { + if (typeof stream._final === 'function') { + state.pendingcb++; + state.finalCalled = true; + pna.nextTick(callFinal, stream, state); + } else { + state.prefinished = true; + stream.emit('prefinish'); + } + } +} + +function finishMaybe(stream, state) { + var need = needFinish(state); + if (need) { + prefinish(stream, state); + if (state.pendingcb === 0) { + state.finished = true; + stream.emit('finish'); + } + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) pna.nextTick(cb);else stream.once('finish', cb); + } + state.ended = true; + stream.writable = false; +} + +function onCorkedFinish(corkReq, state, err) { + var entry = corkReq.entry; + corkReq.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + if (state.corkedRequestsFree) { + state.corkedRequestsFree.next = corkReq; + } else { + state.corkedRequestsFree = corkReq; + } +} + +Object.defineProperty(Writable.prototype, 'destroyed', { + get: function () { + if (this._writableState === undefined) { + return false; + } + return this._writableState.destroyed; + }, + set: function (value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._writableState) { + return; + } + + // backward compatibility, the user is explicitly + // managing destroyed + this._writableState.destroyed = value; + } +}); + +Writable.prototype.destroy = destroyImpl.destroy; +Writable.prototype._undestroy = destroyImpl.undestroy; +Writable.prototype._destroy = function (err, cb) { + this.end(); + cb(err); +}; +}).call(this,require(77),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require(105).setImmediate) + +},{"105":105,"106":106,"40":40,"76":76,"77":77,"79":79,"85":85,"86":86,"87":87,"93":93}],84:[function(require,module,exports){ +'use strict'; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Buffer = require(93).Buffer; +var util = require(34); + +function copyBuffer(src, target, offset) { + src.copy(target, offset); +} + +module.exports = function () { + function BufferList() { + _classCallCheck(this, BufferList); + + this.head = null; + this.tail = null; + this.length = 0; + } + + BufferList.prototype.push = function push(v) { + var entry = { data: v, next: null }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; + }; + + BufferList.prototype.unshift = function unshift(v) { + var entry = { data: v, next: this.head }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; + }; + + BufferList.prototype.shift = function shift() { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; + }; + + BufferList.prototype.clear = function clear() { + this.head = this.tail = null; + this.length = 0; + }; + + BufferList.prototype.join = function join(s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + while (p = p.next) { + ret += s + p.data; + }return ret; + }; + + BufferList.prototype.concat = function concat(n) { + if (this.length === 0) return Buffer.alloc(0); + if (this.length === 1) return this.head.data; + var ret = Buffer.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + while (p) { + copyBuffer(p.data, ret, i); + i += p.data.length; + p = p.next; + } + return ret; + }; + + return BufferList; +}(); + +if (util && util.inspect && util.inspect.custom) { + module.exports.prototype[util.inspect.custom] = function () { + var obj = util.inspect({ length: this.length }); + return this.constructor.name + ' ' + obj; + }; +} +},{"34":34,"93":93}],85:[function(require,module,exports){ +'use strict'; + +/**/ + +var pna = require(76); +/**/ + +// undocumented cb() API, needed for core, not for public API +function destroy(err, cb) { + var _this = this; + + var readableDestroyed = this._readableState && this._readableState.destroyed; + var writableDestroyed = this._writableState && this._writableState.destroyed; + + if (readableDestroyed || writableDestroyed) { + if (cb) { + cb(err); + } else if (err && (!this._writableState || !this._writableState.errorEmitted)) { + pna.nextTick(emitErrorNT, this, err); + } + return this; + } + + // we set destroyed to true before firing error callbacks in order + // to make it re-entrance safe in case destroy() is called within callbacks + + if (this._readableState) { + this._readableState.destroyed = true; + } + + // if this is a duplex stream mark the writable part as destroyed as well + if (this._writableState) { + this._writableState.destroyed = true; + } + + this._destroy(err || null, function (err) { + if (!cb && err) { + pna.nextTick(emitErrorNT, _this, err); + if (_this._writableState) { + _this._writableState.errorEmitted = true; + } + } else if (cb) { + cb(err); + } + }); + + return this; +} + +function undestroy() { + if (this._readableState) { + this._readableState.destroyed = false; + this._readableState.reading = false; + this._readableState.ended = false; + this._readableState.endEmitted = false; + } + + if (this._writableState) { + this._writableState.destroyed = false; + this._writableState.ended = false; + this._writableState.ending = false; + this._writableState.finished = false; + this._writableState.errorEmitted = false; + } +} + +function emitErrorNT(self, err) { + self.emit('error', err); +} + +module.exports = { + destroy: destroy, + undestroy: undestroy +}; +},{"76":76}],86:[function(require,module,exports){ +module.exports = require(62).EventEmitter; + +},{"62":62}],87:[function(require,module,exports){ +arguments[4][65][0].apply(exports,arguments) +},{"65":65}],88:[function(require,module,exports){ +module.exports = require(89).PassThrough + +},{"89":89}],89:[function(require,module,exports){ +exports = module.exports = require(81); +exports.Stream = exports; +exports.Readable = exports; +exports.Writable = require(83); +exports.Duplex = require(79); +exports.Transform = require(82); +exports.PassThrough = require(80); + +},{"79":79,"80":80,"81":81,"82":82,"83":83}],90:[function(require,module,exports){ +module.exports = require(89).Transform + +},{"89":89}],91:[function(require,module,exports){ +module.exports = require(83); + +},{"83":83}],92:[function(require,module,exports){ +'use strict' +var Buffer = require(35).Buffer +var inherits = require(65) +var HashBase = require(63) + +var ARRAY16 = new Array(16) + +var zl = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 +] + +var zr = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 +] + +var sl = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 +] + +var sr = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 +] + +var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e] +var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000] + +function RIPEMD160 () { + HashBase.call(this, 64) + + // state + this._a = 0x67452301 + this._b = 0xefcdab89 + this._c = 0x98badcfe + this._d = 0x10325476 + this._e = 0xc3d2e1f0 +} + +inherits(RIPEMD160, HashBase) + +RIPEMD160.prototype._update = function () { + var words = ARRAY16 + for (var j = 0; j < 16; ++j) words[j] = this._block.readInt32LE(j * 4) + + var al = this._a | 0 + var bl = this._b | 0 + var cl = this._c | 0 + var dl = this._d | 0 + var el = this._e | 0 + + var ar = this._a | 0 + var br = this._b | 0 + var cr = this._c | 0 + var dr = this._d | 0 + var er = this._e | 0 + + // computation + for (var i = 0; i < 80; i += 1) { + var tl + var tr + if (i < 16) { + tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i]) + tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i]) + } else if (i < 32) { + tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i]) + tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i]) + } else if (i < 48) { + tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i]) + tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i]) + } else if (i < 64) { + tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i]) + tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i]) + } else { // if (i<80) { + tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i]) + tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i]) + } + + al = el + el = dl + dl = rotl(cl, 10) + cl = bl + bl = tl + + ar = er + er = dr + dr = rotl(cr, 10) + cr = br + br = tr + } + + // update state + var t = (this._b + cl + dr) | 0 + this._b = (this._c + dl + er) | 0 + this._c = (this._d + el + ar) | 0 + this._d = (this._e + al + br) | 0 + this._e = (this._a + bl + cr) | 0 + this._a = t +} + +RIPEMD160.prototype._digest = function () { + // create padding and handle blocks + this._block[this._blockOffset++] = 0x80 + if (this._blockOffset > 56) { + this._block.fill(0, this._blockOffset, 64) + this._update() + this._blockOffset = 0 + } + + this._block.fill(0, this._blockOffset, 56) + this._block.writeUInt32LE(this._length[0], 56) + this._block.writeUInt32LE(this._length[1], 60) + this._update() + + // produce result + var buffer = Buffer.alloc ? Buffer.alloc(20) : new Buffer(20) + buffer.writeInt32LE(this._a, 0) + buffer.writeInt32LE(this._b, 4) + buffer.writeInt32LE(this._c, 8) + buffer.writeInt32LE(this._d, 12) + buffer.writeInt32LE(this._e, 16) + return buffer +} + +function rotl (x, n) { + return (x << n) | (x >>> (32 - n)) +} + +function fn1 (a, b, c, d, e, m, k, s) { + return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0 +} + +function fn2 (a, b, c, d, e, m, k, s) { + return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0 +} + +function fn3 (a, b, c, d, e, m, k, s) { + return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0 +} + +function fn4 (a, b, c, d, e, m, k, s) { + return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0 +} + +function fn5 (a, b, c, d, e, m, k, s) { + return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0 +} + +module.exports = RIPEMD160 + +},{"35":35,"63":63,"65":65}],93:[function(require,module,exports){ +/* eslint-disable node/no-deprecated-api */ +var buffer = require(35) +var Buffer = buffer.Buffer + +// alternative to using Object.keys for old browsers +function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] + } +} +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer +} else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer +} + +function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) +} + +// Copy static methods from Buffer +copyProps(Buffer, SafeBuffer) + +SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) +} + +SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf +} + +SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) +} + +SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) +} + +},{"35":35}],94:[function(require,module,exports){ +(function (process,Buffer){ +!function(globals){ +'use strict' + +//*** UMD BEGIN +if (typeof define !== 'undefined' && define.amd) { //require.js / AMD + define([], function() { + return secureRandom + }) +} else if (typeof module !== 'undefined' && module.exports) { //CommonJS + module.exports = secureRandom +} else { //script / browser + globals.secureRandom = secureRandom +} +//*** UMD END + +//options.type is the only valid option +function secureRandom(count, options) { + options = options || {type: 'Array'} + //we check for process.pid to prevent browserify from tricking us + if (typeof process != 'undefined' && typeof process.pid == 'number') { + return nodeRandom(count, options) + } else { + var crypto = window.crypto || window.msCrypto + if (!crypto) throw new Error("Your browser does not support window.crypto.") + return browserRandom(count, options) + } +} + +function nodeRandom(count, options) { + var crypto = require(34) + var buf = crypto.randomBytes(count) + + switch (options.type) { + case 'Array': + return [].slice.call(buf) + case 'Buffer': + return buf + case 'Uint8Array': + var arr = new Uint8Array(count) + for (var i = 0; i < count; ++i) { arr[i] = buf.readUInt8(i) } + return arr + default: + throw new Error(options.type + " is unsupported.") + } +} + +function browserRandom(count, options) { + var nativeArr = new Uint8Array(count) + var crypto = window.crypto || window.msCrypto + crypto.getRandomValues(nativeArr) + + switch (options.type) { + case 'Array': + return [].slice.call(nativeArr) + case 'Buffer': + try { var b = new Buffer(1) } catch(e) { throw new Error('Buffer not supported in this environment. Use Node.js or Browserify for browser support.')} + return new Buffer(nativeArr) + case 'Uint8Array': + return nativeArr + default: + throw new Error(options.type + " is unsupported.") + } +} + +secureRandom.randomArray = function(byteCount) { + return secureRandom(byteCount, {type: 'Array'}) +} + +secureRandom.randomUint8Array = function(byteCount) { + return secureRandom(byteCount, {type: 'Uint8Array'}) +} + +secureRandom.randomBuffer = function(byteCount) { + return secureRandom(byteCount, {type: 'Buffer'}) +} + + +}(this); + +}).call(this,require(77),require(35).Buffer) + +},{"34":34,"35":35,"77":77}],95:[function(require,module,exports){ +var Buffer = require(93).Buffer + +// prototype class for hash functions +function Hash (blockSize, finalSize) { + this._block = Buffer.alloc(blockSize) + this._finalSize = finalSize + this._blockSize = blockSize + this._len = 0 +} + +Hash.prototype.update = function (data, enc) { + if (typeof data === 'string') { + enc = enc || 'utf8' + data = Buffer.from(data, enc) + } + + var block = this._block + var blockSize = this._blockSize + var length = data.length + var accum = this._len + + for (var offset = 0; offset < length;) { + var assigned = accum % blockSize + var remainder = Math.min(length - offset, blockSize - assigned) + + for (var i = 0; i < remainder; i++) { + block[assigned + i] = data[offset + i] + } + + accum += remainder + offset += remainder + + if ((accum % blockSize) === 0) { + this._update(block) + } + } + + this._len += length + return this +} + +Hash.prototype.digest = function (enc) { + var rem = this._len % this._blockSize + + this._block[rem] = 0x80 + + // zero (rem + 1) trailing bits, where (rem + 1) is the smallest + // non-negative solution to the equation (length + 1 + (rem + 1)) === finalSize mod blockSize + this._block.fill(0, rem + 1) + + if (rem >= this._finalSize) { + this._update(this._block) + this._block.fill(0) + } + + var bits = this._len * 8 + + // uint32 + if (bits <= 0xffffffff) { + this._block.writeUInt32BE(bits, this._blockSize - 4) + + // uint64 + } else { + var lowBits = (bits & 0xffffffff) >>> 0 + var highBits = (bits - lowBits) / 0x100000000 + + this._block.writeUInt32BE(highBits, this._blockSize - 8) + this._block.writeUInt32BE(lowBits, this._blockSize - 4) + } + + this._update(this._block) + var hash = this._hash() + + return enc ? hash.toString(enc) : hash +} + +Hash.prototype._update = function () { + throw new Error('_update must be implemented by subclass') +} + +module.exports = Hash + +},{"93":93}],96:[function(require,module,exports){ +var exports = module.exports = function SHA (algorithm) { + algorithm = algorithm.toLowerCase() + + var Algorithm = exports[algorithm] + if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)') + + return new Algorithm() +} + +exports.sha = require(97) +exports.sha1 = require(98) +exports.sha224 = require(99) +exports.sha256 = require(100) +exports.sha384 = require(101) +exports.sha512 = require(102) + +},{"100":100,"101":101,"102":102,"97":97,"98":98,"99":99}],97:[function(require,module,exports){ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined + * in FIPS PUB 180-1 + * This source code is derived from sha1.js of the same repository. + * The difference between SHA-0 and SHA-1 is just a bitwise rotate left + * operation was added. + */ + +var inherits = require(65) +var Hash = require(95) +var Buffer = require(93).Buffer + +var K = [ + 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 +] + +var W = new Array(80) + +function Sha () { + this.init() + this._w = W + + Hash.call(this, 64, 56) +} + +inherits(Sha, Hash) + +Sha.prototype.init = function () { + this._a = 0x67452301 + this._b = 0xefcdab89 + this._c = 0x98badcfe + this._d = 0x10325476 + this._e = 0xc3d2e1f0 + + return this +} + +function rotl5 (num) { + return (num << 5) | (num >>> 27) +} + +function rotl30 (num) { + return (num << 30) | (num >>> 2) +} + +function ft (s, b, c, d) { + if (s === 0) return (b & c) | ((~b) & d) + if (s === 2) return (b & c) | (b & d) | (c & d) + return b ^ c ^ d +} + +Sha.prototype._update = function (M) { + var W = this._w + + var a = this._a | 0 + var b = this._b | 0 + var c = this._c | 0 + var d = this._d | 0 + var e = this._e | 0 + + for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) + for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16] + + for (var j = 0; j < 80; ++j) { + var s = ~~(j / 20) + var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0 + + e = d + d = c + c = rotl30(b) + b = a + a = t + } + + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 +} + +Sha.prototype._hash = function () { + var H = Buffer.allocUnsafe(20) + + H.writeInt32BE(this._a | 0, 0) + H.writeInt32BE(this._b | 0, 4) + H.writeInt32BE(this._c | 0, 8) + H.writeInt32BE(this._d | 0, 12) + H.writeInt32BE(this._e | 0, 16) + + return H +} + +module.exports = Sha + +},{"65":65,"93":93,"95":95}],98:[function(require,module,exports){ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ + +var inherits = require(65) +var Hash = require(95) +var Buffer = require(93).Buffer + +var K = [ + 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 +] + +var W = new Array(80) + +function Sha1 () { + this.init() + this._w = W + + Hash.call(this, 64, 56) +} + +inherits(Sha1, Hash) + +Sha1.prototype.init = function () { + this._a = 0x67452301 + this._b = 0xefcdab89 + this._c = 0x98badcfe + this._d = 0x10325476 + this._e = 0xc3d2e1f0 + + return this +} + +function rotl1 (num) { + return (num << 1) | (num >>> 31) +} + +function rotl5 (num) { + return (num << 5) | (num >>> 27) +} + +function rotl30 (num) { + return (num << 30) | (num >>> 2) +} + +function ft (s, b, c, d) { + if (s === 0) return (b & c) | ((~b) & d) + if (s === 2) return (b & c) | (b & d) | (c & d) + return b ^ c ^ d +} + +Sha1.prototype._update = function (M) { + var W = this._w + + var a = this._a | 0 + var b = this._b | 0 + var c = this._c | 0 + var d = this._d | 0 + var e = this._e | 0 + + for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) + for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]) + + for (var j = 0; j < 80; ++j) { + var s = ~~(j / 20) + var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0 + + e = d + d = c + c = rotl30(b) + b = a + a = t + } + + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 +} + +Sha1.prototype._hash = function () { + var H = Buffer.allocUnsafe(20) + + H.writeInt32BE(this._a | 0, 0) + H.writeInt32BE(this._b | 0, 4) + H.writeInt32BE(this._c | 0, 8) + H.writeInt32BE(this._d | 0, 12) + H.writeInt32BE(this._e | 0, 16) + + return H +} + +module.exports = Sha1 + +},{"65":65,"93":93,"95":95}],99:[function(require,module,exports){ +/** + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ + +var inherits = require(65) +var Sha256 = require(100) +var Hash = require(95) +var Buffer = require(93).Buffer + +var W = new Array(64) + +function Sha224 () { + this.init() + + this._w = W // new Array(64) + + Hash.call(this, 64, 56) +} + +inherits(Sha224, Sha256) + +Sha224.prototype.init = function () { + this._a = 0xc1059ed8 + this._b = 0x367cd507 + this._c = 0x3070dd17 + this._d = 0xf70e5939 + this._e = 0xffc00b31 + this._f = 0x68581511 + this._g = 0x64f98fa7 + this._h = 0xbefa4fa4 + + return this +} + +Sha224.prototype._hash = function () { + var H = Buffer.allocUnsafe(28) + + H.writeInt32BE(this._a, 0) + H.writeInt32BE(this._b, 4) + H.writeInt32BE(this._c, 8) + H.writeInt32BE(this._d, 12) + H.writeInt32BE(this._e, 16) + H.writeInt32BE(this._f, 20) + H.writeInt32BE(this._g, 24) + + return H +} + +module.exports = Sha224 + +},{"100":100,"65":65,"93":93,"95":95}],100:[function(require,module,exports){ +/** + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ + +var inherits = require(65) +var Hash = require(95) +var Buffer = require(93).Buffer + +var K = [ + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 +] + +var W = new Array(64) + +function Sha256 () { + this.init() + + this._w = W // new Array(64) + + Hash.call(this, 64, 56) +} + +inherits(Sha256, Hash) + +Sha256.prototype.init = function () { + this._a = 0x6a09e667 + this._b = 0xbb67ae85 + this._c = 0x3c6ef372 + this._d = 0xa54ff53a + this._e = 0x510e527f + this._f = 0x9b05688c + this._g = 0x1f83d9ab + this._h = 0x5be0cd19 + + return this +} + +function ch (x, y, z) { + return z ^ (x & (y ^ z)) +} + +function maj (x, y, z) { + return (x & y) | (z & (x | y)) +} + +function sigma0 (x) { + return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10) +} + +function sigma1 (x) { + return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7) +} + +function gamma0 (x) { + return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3) +} + +function gamma1 (x) { + return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10) +} + +Sha256.prototype._update = function (M) { + var W = this._w + + var a = this._a | 0 + var b = this._b | 0 + var c = this._c | 0 + var d = this._d | 0 + var e = this._e | 0 + var f = this._f | 0 + var g = this._g | 0 + var h = this._h | 0 + + for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) + for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0 + + for (var j = 0; j < 64; ++j) { + var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0 + var T2 = (sigma0(a) + maj(a, b, c)) | 0 + + h = g + g = f + f = e + e = (d + T1) | 0 + d = c + c = b + b = a + a = (T1 + T2) | 0 + } + + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 + this._f = (f + this._f) | 0 + this._g = (g + this._g) | 0 + this._h = (h + this._h) | 0 +} + +Sha256.prototype._hash = function () { + var H = Buffer.allocUnsafe(32) + + H.writeInt32BE(this._a, 0) + H.writeInt32BE(this._b, 4) + H.writeInt32BE(this._c, 8) + H.writeInt32BE(this._d, 12) + H.writeInt32BE(this._e, 16) + H.writeInt32BE(this._f, 20) + H.writeInt32BE(this._g, 24) + H.writeInt32BE(this._h, 28) + + return H +} + +module.exports = Sha256 + +},{"65":65,"93":93,"95":95}],101:[function(require,module,exports){ +var inherits = require(65) +var SHA512 = require(102) +var Hash = require(95) +var Buffer = require(93).Buffer + +var W = new Array(160) + +function Sha384 () { + this.init() + this._w = W + + Hash.call(this, 128, 112) +} + +inherits(Sha384, SHA512) + +Sha384.prototype.init = function () { + this._ah = 0xcbbb9d5d + this._bh = 0x629a292a + this._ch = 0x9159015a + this._dh = 0x152fecd8 + this._eh = 0x67332667 + this._fh = 0x8eb44a87 + this._gh = 0xdb0c2e0d + this._hh = 0x47b5481d + + this._al = 0xc1059ed8 + this._bl = 0x367cd507 + this._cl = 0x3070dd17 + this._dl = 0xf70e5939 + this._el = 0xffc00b31 + this._fl = 0x68581511 + this._gl = 0x64f98fa7 + this._hl = 0xbefa4fa4 + + return this +} + +Sha384.prototype._hash = function () { + var H = Buffer.allocUnsafe(48) + + function writeInt64BE (h, l, offset) { + H.writeInt32BE(h, offset) + H.writeInt32BE(l, offset + 4) + } + + writeInt64BE(this._ah, this._al, 0) + writeInt64BE(this._bh, this._bl, 8) + writeInt64BE(this._ch, this._cl, 16) + writeInt64BE(this._dh, this._dl, 24) + writeInt64BE(this._eh, this._el, 32) + writeInt64BE(this._fh, this._fl, 40) + + return H +} + +module.exports = Sha384 + +},{"102":102,"65":65,"93":93,"95":95}],102:[function(require,module,exports){ +var inherits = require(65) +var Hash = require(95) +var Buffer = require(93).Buffer + +var K = [ + 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, + 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, + 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, + 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, + 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, + 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, + 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, + 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, + 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, + 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, + 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, + 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, + 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, + 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, + 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, + 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, + 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, + 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, + 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, + 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, + 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, + 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, + 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, + 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, + 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, + 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, + 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, + 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, + 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, + 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, + 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, + 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, + 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, + 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, + 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, + 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, + 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, + 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, + 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, + 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 +] + +var W = new Array(160) + +function Sha512 () { + this.init() + this._w = W + + Hash.call(this, 128, 112) +} + +inherits(Sha512, Hash) + +Sha512.prototype.init = function () { + this._ah = 0x6a09e667 + this._bh = 0xbb67ae85 + this._ch = 0x3c6ef372 + this._dh = 0xa54ff53a + this._eh = 0x510e527f + this._fh = 0x9b05688c + this._gh = 0x1f83d9ab + this._hh = 0x5be0cd19 + + this._al = 0xf3bcc908 + this._bl = 0x84caa73b + this._cl = 0xfe94f82b + this._dl = 0x5f1d36f1 + this._el = 0xade682d1 + this._fl = 0x2b3e6c1f + this._gl = 0xfb41bd6b + this._hl = 0x137e2179 + + return this +} + +function Ch (x, y, z) { + return z ^ (x & (y ^ z)) +} + +function maj (x, y, z) { + return (x & y) | (z & (x | y)) +} + +function sigma0 (x, xl) { + return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25) +} + +function sigma1 (x, xl) { + return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23) +} + +function Gamma0 (x, xl) { + return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7) +} + +function Gamma0l (x, xl) { + return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25) +} + +function Gamma1 (x, xl) { + return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6) +} + +function Gamma1l (x, xl) { + return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26) +} + +function getCarry (a, b) { + return (a >>> 0) < (b >>> 0) ? 1 : 0 +} + +Sha512.prototype._update = function (M) { + var W = this._w + + var ah = this._ah | 0 + var bh = this._bh | 0 + var ch = this._ch | 0 + var dh = this._dh | 0 + var eh = this._eh | 0 + var fh = this._fh | 0 + var gh = this._gh | 0 + var hh = this._hh | 0 + + var al = this._al | 0 + var bl = this._bl | 0 + var cl = this._cl | 0 + var dl = this._dl | 0 + var el = this._el | 0 + var fl = this._fl | 0 + var gl = this._gl | 0 + var hl = this._hl | 0 + + for (var i = 0; i < 32; i += 2) { + W[i] = M.readInt32BE(i * 4) + W[i + 1] = M.readInt32BE(i * 4 + 4) + } + for (; i < 160; i += 2) { + var xh = W[i - 15 * 2] + var xl = W[i - 15 * 2 + 1] + var gamma0 = Gamma0(xh, xl) + var gamma0l = Gamma0l(xl, xh) + + xh = W[i - 2 * 2] + xl = W[i - 2 * 2 + 1] + var gamma1 = Gamma1(xh, xl) + var gamma1l = Gamma1l(xl, xh) + + // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] + var Wi7h = W[i - 7 * 2] + var Wi7l = W[i - 7 * 2 + 1] + + var Wi16h = W[i - 16 * 2] + var Wi16l = W[i - 16 * 2 + 1] + + var Wil = (gamma0l + Wi7l) | 0 + var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0 + Wil = (Wil + gamma1l) | 0 + Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0 + Wil = (Wil + Wi16l) | 0 + Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0 + + W[i] = Wih + W[i + 1] = Wil + } + + for (var j = 0; j < 160; j += 2) { + Wih = W[j] + Wil = W[j + 1] + + var majh = maj(ah, bh, ch) + var majl = maj(al, bl, cl) + + var sigma0h = sigma0(ah, al) + var sigma0l = sigma0(al, ah) + var sigma1h = sigma1(eh, el) + var sigma1l = sigma1(el, eh) + + // t1 = h + sigma1 + ch + K[j] + W[j] + var Kih = K[j] + var Kil = K[j + 1] + + var chh = Ch(eh, fh, gh) + var chl = Ch(el, fl, gl) + + var t1l = (hl + sigma1l) | 0 + var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0 + t1l = (t1l + chl) | 0 + t1h = (t1h + chh + getCarry(t1l, chl)) | 0 + t1l = (t1l + Kil) | 0 + t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0 + t1l = (t1l + Wil) | 0 + t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0 + + // t2 = sigma0 + maj + var t2l = (sigma0l + majl) | 0 + var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0 + + hh = gh + hl = gl + gh = fh + gl = fl + fh = eh + fl = el + el = (dl + t1l) | 0 + eh = (dh + t1h + getCarry(el, dl)) | 0 + dh = ch + dl = cl + ch = bh + cl = bl + bh = ah + bl = al + al = (t1l + t2l) | 0 + ah = (t1h + t2h + getCarry(al, t1l)) | 0 + } + + this._al = (this._al + al) | 0 + this._bl = (this._bl + bl) | 0 + this._cl = (this._cl + cl) | 0 + this._dl = (this._dl + dl) | 0 + this._el = (this._el + el) | 0 + this._fl = (this._fl + fl) | 0 + this._gl = (this._gl + gl) | 0 + this._hl = (this._hl + hl) | 0 + + this._ah = (this._ah + ah + getCarry(this._al, al)) | 0 + this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0 + this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0 + this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0 + this._eh = (this._eh + eh + getCarry(this._el, el)) | 0 + this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0 + this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0 + this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0 +} + +Sha512.prototype._hash = function () { + var H = Buffer.allocUnsafe(64) + + function writeInt64BE (h, l, offset) { + H.writeInt32BE(h, offset) + H.writeInt32BE(l, offset + 4) + } + + writeInt64BE(this._ah, this._al, 0) + writeInt64BE(this._bh, this._bl, 8) + writeInt64BE(this._ch, this._cl, 16) + writeInt64BE(this._dh, this._dl, 24) + writeInt64BE(this._eh, this._el, 32) + writeInt64BE(this._fh, this._fl, 40) + writeInt64BE(this._gh, this._gl, 48) + writeInt64BE(this._hh, this._hl, 56) + + return H +} + +module.exports = Sha512 + +},{"65":65,"93":93,"95":95}],103:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +module.exports = Stream; + +var EE = require(62).EventEmitter; +var inherits = require(65); + +inherits(Stream, EE); +Stream.Readable = require(89); +Stream.Writable = require(91); +Stream.Duplex = require(78); +Stream.Transform = require(90); +Stream.PassThrough = require(88); + +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; + + + +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. + +function Stream() { + EE.call(this); +} + +Stream.prototype.pipe = function(dest, options) { + var source = this; + + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } + } + + source.on('data', ondata); + + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } + + dest.on('drain', ondrain); + + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } + + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; + + dest.end(); + } + + + function onclose() { + if (didOnEnd) return; + didOnEnd = true; + + if (typeof dest.destroy === 'function') dest.destroy(); + } + + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } + + source.on('error', onerror); + dest.on('error', onerror); + + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); + + source.removeListener('end', onend); + source.removeListener('close', onclose); + + source.removeListener('error', onerror); + dest.removeListener('error', onerror); + + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); + + dest.removeListener('close', cleanup); + } + + source.on('end', cleanup); + source.on('close', cleanup); + + dest.on('close', cleanup); + + dest.emit('pipe', source); + + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; + +},{"62":62,"65":65,"78":78,"88":88,"89":89,"90":90,"91":91}],104:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +'use strict'; + +/**/ + +var Buffer = require(93).Buffer; +/**/ + +var isEncoding = Buffer.isEncoding || function (encoding) { + encoding = '' + encoding; + switch (encoding && encoding.toLowerCase()) { + case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': + return true; + default: + return false; + } +}; + +function _normalizeEncoding(enc) { + if (!enc) return 'utf8'; + var retried; + while (true) { + switch (enc) { + case 'utf8': + case 'utf-8': + return 'utf8'; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return 'utf16le'; + case 'latin1': + case 'binary': + return 'latin1'; + case 'base64': + case 'ascii': + case 'hex': + return enc; + default: + if (retried) return; // undefined + enc = ('' + enc).toLowerCase(); + retried = true; + } + } +}; + +// Do not cache `Buffer.isEncoding` when checking encoding names as some +// modules monkey-patch it to support additional encodings +function normalizeEncoding(enc) { + var nenc = _normalizeEncoding(enc); + if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); + return nenc || enc; +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. +exports.StringDecoder = StringDecoder; +function StringDecoder(encoding) { + this.encoding = normalizeEncoding(encoding); + var nb; + switch (this.encoding) { + case 'utf16le': + this.text = utf16Text; + this.end = utf16End; + nb = 4; + break; + case 'utf8': + this.fillLast = utf8FillLast; + nb = 4; + break; + case 'base64': + this.text = base64Text; + this.end = base64End; + nb = 3; + break; + default: + this.write = simpleWrite; + this.end = simpleEnd; + return; + } + this.lastNeed = 0; + this.lastTotal = 0; + this.lastChar = Buffer.allocUnsafe(nb); +} + +StringDecoder.prototype.write = function (buf) { + if (buf.length === 0) return ''; + var r; + var i; + if (this.lastNeed) { + r = this.fillLast(buf); + if (r === undefined) return ''; + i = this.lastNeed; + this.lastNeed = 0; + } else { + i = 0; + } + if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); + return r || ''; +}; + +StringDecoder.prototype.end = utf8End; + +// Returns only complete characters in a Buffer +StringDecoder.prototype.text = utf8Text; + +// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer +StringDecoder.prototype.fillLast = function (buf) { + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); + } + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); + this.lastNeed -= buf.length; +}; + +// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a +// continuation byte. If an invalid byte is detected, -2 is returned. +function utf8CheckByte(byte) { + if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; + return byte >> 6 === 0x02 ? -1 : -2; +} + +// Checks at most 3 bytes at the end of a Buffer in order to detect an +// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) +// needed to complete the UTF-8 character (if applicable) are returned. +function utf8CheckIncomplete(self, buf, i) { + var j = buf.length - 1; + if (j < i) return 0; + var nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 1; + return nb; + } + if (--j < i || nb === -2) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 2; + return nb; + } + if (--j < i || nb === -2) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) { + if (nb === 2) nb = 0;else self.lastNeed = nb - 3; + } + return nb; + } + return 0; +} + +// Validates as many continuation bytes for a multi-byte UTF-8 character as +// needed or are available. If we see a non-continuation byte where we expect +// one, we "replace" the validated continuation bytes we've seen so far with +// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding +// behavior. The continuation byte check is included three times in the case +// where all of the continuation bytes for a character exist in the same buffer. +// It is also done this way as a slight performance increase instead of using a +// loop. +function utf8CheckExtraBytes(self, buf, p) { + if ((buf[0] & 0xC0) !== 0x80) { + self.lastNeed = 0; + return '\ufffd'; + } + if (self.lastNeed > 1 && buf.length > 1) { + if ((buf[1] & 0xC0) !== 0x80) { + self.lastNeed = 1; + return '\ufffd'; + } + if (self.lastNeed > 2 && buf.length > 2) { + if ((buf[2] & 0xC0) !== 0x80) { + self.lastNeed = 2; + return '\ufffd'; + } + } + } +} + +// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. +function utf8FillLast(buf) { + var p = this.lastTotal - this.lastNeed; + var r = utf8CheckExtraBytes(this, buf, p); + if (r !== undefined) return r; + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, p, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); + } + buf.copy(this.lastChar, p, 0, buf.length); + this.lastNeed -= buf.length; +} + +// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a +// partial character, the character's bytes are buffered until the required +// number of bytes are available. +function utf8Text(buf, i) { + var total = utf8CheckIncomplete(this, buf, i); + if (!this.lastNeed) return buf.toString('utf8', i); + this.lastTotal = total; + var end = buf.length - (total - this.lastNeed); + buf.copy(this.lastChar, 0, end); + return buf.toString('utf8', i, end); +} + +// For UTF-8, a replacement character is added when ending on a partial +// character. +function utf8End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + '\ufffd'; + return r; +} + +// UTF-16LE typically needs two bytes per character, but even if we have an even +// number of bytes available, we need to check if we end on a leading/high +// surrogate. In that case, we need to wait for the next two bytes in order to +// decode the last character properly. +function utf16Text(buf, i) { + if ((buf.length - i) % 2 === 0) { + var r = buf.toString('utf16le', i); + if (r) { + var c = r.charCodeAt(r.length - 1); + if (c >= 0xD800 && c <= 0xDBFF) { + this.lastNeed = 2; + this.lastTotal = 4; + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + return r.slice(0, -1); + } + } + return r; + } + this.lastNeed = 1; + this.lastTotal = 2; + this.lastChar[0] = buf[buf.length - 1]; + return buf.toString('utf16le', i, buf.length - 1); +} + +// For UTF-16LE we do not explicitly append special replacement characters if we +// end on a partial character, we simply let v8 handle that. +function utf16End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) { + var end = this.lastTotal - this.lastNeed; + return r + this.lastChar.toString('utf16le', 0, end); + } + return r; +} + +function base64Text(buf, i) { + var n = (buf.length - i) % 3; + if (n === 0) return buf.toString('base64', i); + this.lastNeed = 3 - n; + this.lastTotal = 3; + if (n === 1) { + this.lastChar[0] = buf[buf.length - 1]; + } else { + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + } + return buf.toString('base64', i, buf.length - n); +} + +function base64End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); + return r; +} + +// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) +function simpleWrite(buf) { + return buf.toString(this.encoding); +} + +function simpleEnd(buf) { + return buf && buf.length ? this.write(buf) : ''; +} +},{"93":93}],105:[function(require,module,exports){ +(function (setImmediate,clearImmediate){ +var nextTick = require(77).nextTick; +var apply = Function.prototype.apply; +var slice = Array.prototype.slice; +var immediateIds = {}; +var nextImmediateId = 0; + +// DOM APIs, for completeness + +exports.setTimeout = function() { + return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); +}; +exports.setInterval = function() { + return new Timeout(apply.call(setInterval, window, arguments), clearInterval); +}; +exports.clearTimeout = +exports.clearInterval = function(timeout) { timeout.close(); }; + +function Timeout(id, clearFn) { + this._id = id; + this._clearFn = clearFn; +} +Timeout.prototype.unref = Timeout.prototype.ref = function() {}; +Timeout.prototype.close = function() { + this._clearFn.call(window, this._id); +}; + +// Does not start the time, just sets up the members needed. +exports.enroll = function(item, msecs) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = msecs; +}; + +exports.unenroll = function(item) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = -1; +}; + +exports._unrefActive = exports.active = function(item) { + clearTimeout(item._idleTimeoutId); + + var msecs = item._idleTimeout; + if (msecs >= 0) { + item._idleTimeoutId = setTimeout(function onTimeout() { + if (item._onTimeout) + item._onTimeout(); + }, msecs); + } +}; + +// That's not how node.js implements it but the exposed api is the same. +exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { + var id = nextImmediateId++; + var args = arguments.length < 2 ? false : slice.call(arguments, 1); + + immediateIds[id] = true; + + nextTick(function onNextTick() { + if (immediateIds[id]) { + // fn.call() is faster so we optimize for the common use-case + // @see http://jsperf.com/call-apply-segu + if (args) { + fn.apply(null, args); + } else { + fn.call(null); + } + // Prevent ids from leaking + exports.clearImmediate(id); + } + }); + + return id; +}; + +exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) { + delete immediateIds[id]; +}; +}).call(this,require(105).setImmediate,require(105).clearImmediate) + +},{"105":105,"77":77}],106:[function(require,module,exports){ +(function (global){ + +/** + * Module exports. + */ + +module.exports = deprecate; + +/** + * Mark that a method should not be used. + * Returns a modified function which warns once by default. + * + * If `localStorage.noDeprecation = true` is set, then it is a no-op. + * + * If `localStorage.throwDeprecation = true` is set, then deprecated functions + * will throw an Error when invoked. + * + * If `localStorage.traceDeprecation = true` is set, then deprecated functions + * will invoke `console.trace()` instead of `console.error()`. + * + * @param {Function} fn - the function to deprecate + * @param {String} msg - the string to print to the console when `fn` is invoked + * @returns {Function} a new "deprecated" version of `fn` + * @api public + */ + +function deprecate (fn, msg) { + if (config('noDeprecation')) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (config('throwDeprecation')) { + throw new Error(msg); + } else if (config('traceDeprecation')) { + console.trace(msg); + } else { + console.warn(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +} + +/** + * Checks `localStorage` for boolean values for the given `name`. + * + * @param {String} name + * @returns {Boolean} + * @api private + */ + +function config (name) { + // accessing global.localStorage can trigger a DOMException in sandboxed iframes + try { + if (!global.localStorage) return false; + } catch (_) { + return false; + } + var val = global.localStorage[name]; + if (null == val) return false; + return String(val).toLowerCase() === 'true'; +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],107:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],108:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require(107); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require(65); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require(77),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"107":107,"65":65,"77":77}]},{},[1])(1) +}); + +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJkaXN0L2Jyb3dzZXIuanMiLCJkaXN0L2NoYWluL3NyYy9BY2NvdW50TG9naW4uanMiLCJkaXN0L2NoYWluL3NyYy9DaGFpblR5cGVzLmpzIiwiZGlzdC9jaGFpbi9zcmMvT2JqZWN0SWQuanMiLCJkaXN0L2NoYWluL3NyYy9UcmFuc2FjdGlvbkJ1aWxkZXIuanMiLCJkaXN0L2NoYWluL3NyYy9zdGF0ZS5qcyIsImRpc3QvZWNjL2luZGV4LmpzIiwiZGlzdC9lY2Mvc3JjL0JyYWluS2V5LmpzIiwiZGlzdC9lY2Mvc3JjL0tleVV0aWxzLmpzIiwiZGlzdC9lY2Mvc3JjL1ByaXZhdGVLZXkuanMiLCJkaXN0L2VjYy9zcmMvUHVibGljS2V5LmpzIiwiZGlzdC9lY2Mvc3JjL2FkZHJlc3MuanMiLCJkaXN0L2VjYy9zcmMvYWVzLmpzIiwiZGlzdC9lY2Mvc3JjL2VjZHNhLmpzIiwiZGlzdC9lY2Mvc3JjL2Vjc2lnbmF0dXJlLmpzIiwiZGlzdC9lY2Mvc3JjL2VuZm9yY2VfdHlwZXMuanMiLCJkaXN0L2VjYy9zcmMvaGFzaC5qcyIsImRpc3QvZWNjL3NyYy9zaWduYXR1cmUuanMiLCJkaXN0L3NlcmlhbGl6ZXIvaW5kZXguanMiLCJkaXN0L3NlcmlhbGl6ZXIvc3JjL0Zhc3RQYXJzZXIuanMiLCJkaXN0L3NlcmlhbGl6ZXIvc3JjL1NlcmlhbGl6ZXJWYWxpZGF0aW9uLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9lcnJvcl93aXRoX2NhdXNlLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9vcGVyYXRpb25zLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9zZXJpYWxpemVyLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy90ZW1wbGF0ZS5qcyIsImRpc3Qvc2VyaWFsaXplci9zcmMvdHlwZXMuanMiLCJub2RlX21vZHVsZXMvYXNzZXJ0L2Fzc2VydC5qcyIsIm5vZGVfbW9kdWxlcy9iYXNlLXgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JpZ2kvbGliL2JpZ2kuanMiLCJub2RlX21vZHVsZXMvYmlnaS9saWIvY29udmVydC5qcyIsIm5vZGVfbW9kdWxlcy9iaWdpL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9iaWdpL3BhY2thZ2UuanNvbiIsIm5vZGVfbW9kdWxlcy9icm93c2VyLXJlc29sdmUvZW1wdHkuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JzNTgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnl0ZWJ1ZmZlci9kaXN0L2J5dGVidWZmZXIuanMiLCJub2RlX21vZHVsZXMvY2lwaGVyLWJhc2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzIiwibm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvbWQ1LmpzIiwibm9kZV9tb2R1bGVzL2NyZWF0ZS1obWFjL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhtYWMvbGVnYWN5LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9hZXMuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2NpcGhlci1jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9lbmMtYmFzZTY0LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9lbmMtaGV4LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9ldnBrZGYuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2htYWMuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL21kNS5qcyIsIm5vZGVfbW9kdWxlcy9jcnlwdG8tanMvc2hhMS5qcyIsIm5vZGVfbW9kdWxlcy9kZWVwLWVxdWFsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2RlZXAtZXF1YWwvbGliL2lzX2FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9kZWVwLWVxdWFsL2xpYi9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2VjdXJ2ZS9saWIvY3VydmUuanMiLCJub2RlX21vZHVsZXMvZWN1cnZlL2xpYi9jdXJ2ZXMuanNvbiIsIm5vZGVfbW9kdWxlcy9lY3VydmUvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2VjdXJ2ZS9saWIvbmFtZXMuanMiLCJub2RlX21vZHVsZXMvZWN1cnZlL2xpYi9wb2ludC5qcyIsIm5vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwibm9kZV9tb2R1bGVzL2hhc2gtYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvaXMtYnVmZmVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9uZy9kaXN0L2xvbmcuanMiLCJub2RlX21vZHVsZXMvbWQ1LmpzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcGVlcnBsYXlzanMtd3MvZGlzdC9zcmMvQXBpSW5zdGFuY2VzLmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0NoYWluQ29uZmlnLmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0NoYWluV2ViU29ja2V0LmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0Nvbm5lY3Rpb25NYW5hZ2VyLmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0dyYXBoZW5lQXBpLmpzIiwibm9kZV9tb2R1bGVzL3Byb2Nlc3MtbmV4dGljay1hcmdzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LWJyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9CdWZmZXJMaXN0LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9kZXN0cm95LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0tYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLWJyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUtYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yaXBlbWQxNjAvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2FmZS1idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2VjdXJlLXJhbmRvbS9saWIvc2VjdXJlLXJhbmRvbS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvaGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2hhLmpzL3NoYS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhMS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhMjI0LmpzIiwibm9kZV9tb2R1bGVzL3NoYS5qcy9zaGEyNTYuanMiLCJub2RlX21vZHVsZXMvc2hhLmpzL3NoYTM4NC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhNTEyLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2xpYi9zdHJpbmdfZGVjb2Rlci5qcyIsIm5vZGVfbW9kdWxlcy90aW1lcnMtYnJvd3NlcmlmeS9tYWluLmpzIiwibm9kZV9tb2R1bGVzL3V0aWwtZGVwcmVjYXRlL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvdXRpbC9zdXBwb3J0L2lzQnVmZmVyQnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy91dGlsL3V0aWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbHFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNuT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2hPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3hPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUM3VEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDelBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdk1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1Z0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3pPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNyckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDcitDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM3dkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbHFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdk9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy8yQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdnZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDenJDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TEE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzEvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM5cUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBOzs7O0FDREE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7O0FDREE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25LQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3ZTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfcGVlcnBsYXlzanNXcyA9IHJlcXVpcmUoNzApO1xuXG52YXIgX3BlZXJwbGF5c2pzV3MyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcGVlcnBsYXlzanNXcyk7XG5cbnZhciBfUHJpdmF0ZUtleSA9IHJlcXVpcmUoMTApO1xuXG52YXIgX1ByaXZhdGVLZXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUHJpdmF0ZUtleSk7XG5cbnZhciBfUHVibGljS2V5ID0gcmVxdWlyZSgxMSk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbnZhciBfc2lnbmF0dXJlID0gcmVxdWlyZSgxOCk7XG5cbnZhciBfc2lnbmF0dXJlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3NpZ25hdHVyZSk7XG5cbnZhciBfS2V5VXRpbHMgPSByZXF1aXJlKDkpO1xuXG52YXIgX0tleVV0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0tleVV0aWxzKTtcblxudmFyIF9UcmFuc2FjdGlvbkJ1aWxkZXIgPSByZXF1aXJlKDUpO1xuXG52YXIgX1RyYW5zYWN0aW9uQnVpbGRlcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9UcmFuc2FjdGlvbkJ1aWxkZXIpO1xuXG52YXIgX0FjY291bnRMb2dpbiA9IHJlcXVpcmUoMik7XG5cbnZhciBfQWNjb3VudExvZ2luMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0FjY291bnRMb2dpbik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgUHJpdmF0ZUtleTogX1ByaXZhdGVLZXkyLmRlZmF1bHQsXG4gIFB1YmxpY0tleTogX1B1YmxpY0tleTIuZGVmYXVsdCxcbiAgU2lnbmF0dXJlOiBfc2lnbmF0dXJlMi5kZWZhdWx0LFxuICBrZXk6IF9LZXlVdGlsczIuZGVmYXVsdCxcbiAgVHJhbnNhY3Rpb25CdWlsZGVyOiBfVHJhbnNhY3Rpb25CdWlsZGVyMi5kZWZhdWx0LFxuICBMb2dpbjogX0FjY291bnRMb2dpbjIuZGVmYXVsdCxcbiAgcGVlcnBsYXlzanNfd3M6IF9wZWVycGxheXNqc1dzMi5kZWZhdWx0XG59O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX1ByaXZhdGVLZXkgPSByZXF1aXJlKDEwKTtcblxudmFyIF9Qcml2YXRlS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1ByaXZhdGVLZXkpO1xuXG52YXIgX0tleVV0aWxzID0gcmVxdWlyZSg5KTtcblxudmFyIF9LZXlVdGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9LZXlVdGlscyk7XG5cbnZhciBfc3RhdGUgPSByZXF1aXJlKDYpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgX2tleUNhY2hlUHJpdiA9IHt9O1xudmFyIF9rZXlDYWNoZVB1YiA9IHt9O1xuXG52YXIgQWNjb3VudExvZ2luID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBBY2NvdW50TG9naW4oKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEFjY291bnRMb2dpbik7XG5cbiAgICB2YXIgc3RhdGUgPSB7IGxvZ2dlZEluOiBmYWxzZSwgcm9sZXM6IFsnYWN0aXZlJywgJ293bmVyJywgJ21lbW8nXSB9O1xuICAgIHRoaXMuZ2V0ID0gKDAsIF9zdGF0ZS5nZXQpKHN0YXRlKTtcbiAgICB0aGlzLnNldCA9ICgwLCBfc3RhdGUuc2V0KShzdGF0ZSk7XG5cbiAgICB0aGlzLnN1YnMgPSB7fTtcbiAgfVxuXG4gIEFjY291bnRMb2dpbi5wcm90b3R5cGUuYWRkU3Vic2NyaXB0aW9uID0gZnVuY3Rpb24gYWRkU3Vic2NyaXB0aW9uKGNiKSB7XG4gICAgdGhpcy5zdWJzW2NiXSA9IGNiO1xuICB9O1xuXG4gIEFjY291bnRMb2dpbi5wcm90b3R5cGUuc2V0Um9sZXMgPSBmdW5jdGlvbiBzZXRSb2xlcyhyb2xlcykge1xuICAgIHRoaXMuc2V0KCdyb2xlcycsIHJvbGVzKTtcbiAgfTtcblxuICBBY2NvdW50TG9naW4ucHJvdG90eXBlLmdlbmVyYXRlS2V5cyA9IGZ1bmN0aW9uIGdlbmVyYXRlS2V5cyhhY2NvdW50TmFtZSwgcGFzc3dvcmQsIHJvbGVzLCBwcmVmaXgpIHtcbiAgICBpZiAoIWFjY291bnROYW1lIHx8ICFwYXNzd29yZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBY2NvdW50IG5hbWUgb3IgcGFzc3dvcmQgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAocGFzc3dvcmQubGVuZ3RoIDwgMTIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFzc3dvcmQgbXVzdCBoYXZlIGF0IGxlYXN0IDEyIGNoYXJhY3RlcnMnKTtcbiAgICB9XG5cbiAgICB2YXIgcHJpdktleXMgPSB7fTtcbiAgICB2YXIgcHViS2V5cyA9IHt9O1xuXG4gICAgKHJvbGVzIHx8IHRoaXMuZ2V0KCdyb2xlcycpKS5mb3JFYWNoKGZ1bmN0aW9uIChyb2xlKSB7XG4gICAgICB2YXIgc2VlZCA9IHBhc3N3b3JkICsgYWNjb3VudE5hbWUgKyByb2xlO1xuICAgICAgdmFyIHBrZXkgPSBfa2V5Q2FjaGVQcml2W3NlZWRdID8gX2tleUNhY2hlUHJpdltzZWVkXSA6IF9Qcml2YXRlS2V5Mi5kZWZhdWx0LmZyb21TZWVkKF9LZXlVdGlsczIuZGVmYXVsdC5ub3JtYWxpemVfYnJhaW5LZXkoc2VlZCkpO1xuICAgICAgX2tleUNhY2hlUHJpdltzZWVkXSA9IHBrZXk7XG5cbiAgICAgIHByaXZLZXlzW3JvbGVdID0gcGtleTtcbiAgICAgIHB1YktleXNbcm9sZV0gPSBfa2V5Q2FjaGVQdWJbc2VlZF0gPyBfa2V5Q2FjaGVQdWJbc2VlZF0gOiBwa2V5LnRvUHVibGljS2V5KCkudG9TdHJpbmcocHJlZml4KTtcblxuICAgICAgX2tleUNhY2hlUHViW3NlZWRdID0gcHViS2V5c1tyb2xlXTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7IHByaXZLZXlzOiBwcml2S2V5cywgcHViS2V5czogcHViS2V5cyB9O1xuICB9O1xuXG4gIEFjY291bnRMb2dpbi5wcm90b3R5cGUuY2hlY2tLZXlzID0gZnVuY3Rpb24gY2hlY2tLZXlzKF9yZWYpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIGFjY291bnROYW1lID0gX3JlZi5hY2NvdW50TmFtZSxcbiAgICAgICAgcGFzc3dvcmQgPSBfcmVmLnBhc3N3b3JkLFxuICAgICAgICBhdXRocyA9IF9yZWYuYXV0aHM7XG5cbiAgICBpZiAoIWFjY291bnROYW1lIHx8ICFwYXNzd29yZCB8fCAhYXV0aHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2hlY2tLZXlzOiBNaXNzaW5nIGlucHV0cycpO1xuICAgIH1cblxuICAgIHZhciBoYXNLZXkgPSBmYWxzZTtcbiAgICB2YXIgcm9sZXMgPSBPYmplY3Qua2V5cyhhdXRocyk7XG5cbiAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiBfbG9vcChpLCBsZW4pIHtcbiAgICAgIHZhciByb2xlID0gcm9sZXNbaV07XG5cbiAgICAgIHZhciBfZ2VuZXJhdGVLZXlzID0gX3RoaXMuZ2VuZXJhdGVLZXlzKGFjY291bnROYW1lLCBwYXNzd29yZCwgW3JvbGVdKSxcbiAgICAgICAgICBwcml2S2V5cyA9IF9nZW5lcmF0ZUtleXMucHJpdktleXMsXG4gICAgICAgICAgcHViS2V5cyA9IF9nZW5lcmF0ZUtleXMucHViS2V5cztcblxuICAgICAgYXV0aHNbcm9sZV0uZm9yRWFjaChmdW5jdGlvbiAocm9sZUtleSkge1xuICAgICAgICBpZiAocm9sZUtleVswXSA9PT0gcHViS2V5c1tyb2xlXSkge1xuICAgICAgICAgIGhhc0tleSA9IHRydWU7XG4gICAgICAgICAgX3RoaXMuc2V0KHJvbGUsIHsgcHJpdjogcHJpdktleXNbcm9sZV0sIHB1YjogcHViS2V5c1tyb2xlXSB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSByb2xlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgX2xvb3AoaSwgbGVuKTtcbiAgICB9XG5cbiAgICBpZiAoaGFzS2V5KSB7XG4gICAgICB0aGlzLnNldCgnbmFtZScsIGFjY291bnROYW1lKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldCgnbG9nZ2VkSW4nLCBoYXNLZXkpO1xuXG4gICAgcmV0dXJuIGhhc0tleTtcbiAgfTtcblxuICBBY2NvdW50TG9naW4ucHJvdG90eXBlLnNpZ25UcmFuc2FjdGlvbiA9IGZ1bmN0aW9uIHNpZ25UcmFuc2FjdGlvbih0cikge1xuICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgdmFyIGhhc0tleSA9IGZhbHNlO1xuXG4gICAgdGhpcy5nZXQoJ3JvbGVzJykuZm9yRWFjaChmdW5jdGlvbiAocm9sZSkge1xuICAgICAgdmFyIG15S2V5ID0gX3RoaXMyLmdldChyb2xlKTtcblxuICAgICAgaWYgKG15S2V5KSB7XG4gICAgICAgIGhhc0tleSA9IHRydWU7XG4gICAgICAgIGNvbnNvbGUubG9nKCdhZGRpbmcgc2lnbmVyOicsIG15S2V5LnB1Yik7XG4gICAgICAgIHRyLmFkZF9zaWduZXIobXlLZXkucHJpdiwgbXlLZXkucHViKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmICghaGFzS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBkbyBub3QgaGF2ZSBhbnkgcHJpdmF0ZSBrZXlzIHRvIHNpZ24gdGhpcyB0cmFuc2FjdGlvbicpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gQWNjb3VudExvZ2luO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBuZXcgQWNjb3VudExvZ2luKCk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbnZhciByZXNlcnZlZF9zcGFjZXMgPSB7XG4gIHJlbGF0aXZlX3Byb3RvY29sX2lkczogMCxcbiAgcHJvdG9jb2xfaWRzOiAxLFxuICBpbXBsZW1lbnRhdGlvbl9pZHM6IDJcbn07XG5cbnZhciBvYmplY3RfdHlwZSA9IHtcbiAgbnVsbDogMCxcbiAgYmFzZTogMSxcbiAgYWNjb3VudDogMixcbiAgYXNzZXQ6IDMsXG4gIGZvcmNlX3NldHRsZW1lbnQ6IDQsXG4gIGNvbW1pdHRlZV9tZW1iZXI6IDUsXG4gIHdpdG5lc3M6IDYsXG4gIGxpbWl0X29yZGVyOiA3LFxuICBjYWxsX29yZGVyOiA4LFxuICBjdXN0b206IDksXG4gIHByb3Bvc2FsOiAxMCxcbiAgb3BlcmF0aW9uX2hpc3Rvcnk6IDExLFxuICB3aXRoZHJhd19wZXJtaXNzaW9uOiAxMixcbiAgdmVzdGluZ19iYWxhbmNlOiAxMyxcbiAgd29ya2VyOiAxNCxcbiAgYmFsYW5jZTogMTUsXG4gIHRvdXJuYW1lbnQ6IDE2LFxuICB0b3VybmFtZW50X2RldGFpbHM6IDE3LFxuICBtYXRjaDogMTgsXG4gIGdhbWU6IDE5LFxuICBzcG9ydDogMjAsXG4gIGV2ZW50X2dyb3VwOiAyMSxcbiAgZXZlbnQ6IDIyLFxuICBiZXR0aW5nX21hcmtldF9ydWxlczogMjMsXG4gIGJldHRpbmdfbWFya2V0X2dyb3VwOiAyNCxcbiAgYmV0dGluZ19tYXJrZXQ6IDI1LFxuICBiZXQ6IDI2XG59O1xuXG52YXIgaW1wbF9vYmplY3RfdHlwZSA9IHtcbiAgZ2xvYmFsX3Byb3BlcnR5OiAwLFxuICBkeW5hbWljX2dsb2JhbF9wcm9wZXJ0eTogMSxcbiAgcmVzZXJ2ZWQwOiAyLFxuICBhc3NldF9keW5hbWljX2RhdGE6IDMsXG4gIGFzc2V0X2JpdGFzc2V0X2RhdGE6IDQsXG4gIGFjY291bnRfYmFsYW5jZTogNSxcbiAgYWNjb3VudF9zdGF0aXN0aWNzOiA2LFxuICB0cmFuc2FjdGlvbjogNyxcbiAgYmxvY2tfc3VtbWFyeTogOCxcbiAgYWNjb3VudF90cmFuc2FjdGlvbl9oaXN0b3J5OiA5LFxuICBibGluZGVkX2JhbGFuY2U6IDEwLFxuICBjaGFpbl9wcm9wZXJ0eTogMTEsXG4gIHdpdG5lc3Nfc2NoZWR1bGU6IDEyLFxuICBidWRnZXRfcmVjb3JkOiAxMyxcbiAgc3BlY2lhbF9hdXRob3JpdHk6IDE0LFxuICBidXliYWNrOiAxNSxcbiAgZmJhX2FjY3VtdWxhdG9yOiAxNixcbiAgYmV0dGluZ19tYXJrZXRfcG9zaXRpb246IDE3LFxuICBnbG9iYWxfYmV0dGluZ19zdGF0aXN0aWNzOiAxOCxcbiAgYXNzZXRfZGl2aWRlbmRfZGF0YTogMTksXG4gIHBlbmRpbmdfZGl2aWRlbmRfcGF5b3V0X2JhbGFuY2VfZm9yX2hvbGRlcjogMjAsXG4gIGRpc3RyaWJ1dGVkX2RpdmlkZW5kX2JhbGFuY2VfZGF0YTogMjFcbn07XG5cbnZhciB2b3RlX3R5cGUgPSB7XG4gIGNvbW1pdHRlZTogMCxcbiAgd2l0bmVzczogMSxcbiAgd29ya2VyOiAyXG59O1xuXG52YXIgb3BlcmF0aW9ucyA9IHtcbiAgdHJhbnNmZXI6IDAsXG4gIGxpbWl0X29yZGVyX2NyZWF0ZTogMSxcbiAgbGltaXRfb3JkZXJfY2FuY2VsOiAyLFxuICBjYWxsX29yZGVyX3VwZGF0ZTogMyxcbiAgZmlsbF9vcmRlcjogNCxcbiAgYWNjb3VudF9jcmVhdGU6IDUsXG4gIGFjY291bnRfdXBkYXRlOiA2LFxuICBhY2NvdW50X3doaXRlbGlzdDogNyxcbiAgYWNjb3VudF91cGdyYWRlOiA4LFxuICBhY2NvdW50X3RyYW5zZmVyOiA5LFxuICBhc3NldF9jcmVhdGU6IDEwLFxuICBhc3NldF91cGRhdGU6IDExLFxuICBhc3NldF91cGRhdGVfYml0YXNzZXQ6IDEyLFxuICBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnM6IDEzLFxuICBhc3NldF9pc3N1ZTogMTQsXG4gIGFzc2V0X3Jlc2VydmU6IDE1LFxuICBhc3NldF9mdW5kX2ZlZV9wb29sOiAxNixcbiAgYXNzZXRfc2V0dGxlOiAxNyxcbiAgYXNzZXRfZ2xvYmFsX3NldHRsZTogMTgsXG4gIGFzc2V0X3B1Ymxpc2hfZmVlZDogMTksXG4gIHdpdG5lc3NfY3JlYXRlOiAyMCxcbiAgd2l0bmVzc191cGRhdGU6IDIxLFxuICBwcm9wb3NhbF9jcmVhdGU6IDIyLFxuICBwcm9wb3NhbF91cGRhdGU6IDIzLFxuICBwcm9wb3NhbF9kZWxldGU6IDI0LFxuICB3aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZTogMjUsXG4gIHdpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlOiAyNixcbiAgd2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbTogMjcsXG4gIHdpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlOiAyOCxcbiAgY29tbWl0dGVlX21lbWJlcl9jcmVhdGU6IDI5LFxuICBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZTogMzAsXG4gIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzOiAzMSxcbiAgdmVzdGluZ19iYWxhbmNlX2NyZWF0ZTogMzIsXG4gIHZlc3RpbmdfYmFsYW5jZV93aXRoZHJhdzogMzMsXG4gIHdvcmtlcl9jcmVhdGU6IDM0LFxuICBjdXN0b206IDM1LFxuICBhc3NlcnQ6IDM2LFxuICBiYWxhbmNlX2NsYWltOiAzNyxcbiAgb3ZlcnJpZGVfdHJhbnNmZXI6IDM4LFxuICB0cmFuc2Zlcl90b19ibGluZDogMzksXG4gIGJsaW5kX3RyYW5zZmVyOiA0MCxcbiAgdHJhbnNmZXJfZnJvbV9ibGluZDogNDEsXG4gIGFzc2V0X3NldHRsZV9jYW5jZWw6IDQyLFxuICBhc3NldF9jbGFpbV9mZWVzOiA0MyxcbiAgZmJhX2Rpc3RyaWJ1dGVfb3BlcmF0aW9uOiA0NCxcbiAgdG91cm5hbWVudF9jcmVhdGU6IDQ1LFxuICB0b3VybmFtZW50X2pvaW46IDQ2LFxuICBnYW1lX21vdmU6IDQ3LFxuICBhc3NldF91cGRhdGVfZGl2aWRlbmQ6IDQ4LFxuICBhc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb246IDQ5LFxuICB0b3VybmFtZW50X3BheW91dDogNTAsXG4gIHRvdXJuYW1lbnRfbGVhdmU6IDUxLFxuICBzcG9ydF9jcmVhdGU6IDUyLFxuICBzcG9ydF91cGRhdGU6IDUzLFxuICBldmVudF9ncm91cF9jcmVhdGU6IDU0LFxuICBldmVudF9ncm91cF91cGRhdGU6IDU1LFxuICBldmVudF9jcmVhdGU6IDU2LFxuICBldmVudF91cGRhdGU6IDU3LFxuICBiZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGU6IDU4LFxuICBiZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGU6IDU5LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGU6IDYwLFxuICBiZXR0aW5nX21hcmtldF9jcmVhdGU6IDYxLFxuICBiZXRfcGxhY2U6IDYyLFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlOiA2MyxcbiAgYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWQ6IDY0LFxuICBiZXRfYWRqdXN0ZWQ6IDY1LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWw6IDY2LFxuICBiZXRfbWF0Y2hlZDogNjcsXG4gIGJldF9jYW5jZWw6IDY4LFxuICBiZXRfY2FuY2VsZWQ6IDY5LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGU6IDcwLFxuICBiZXR0aW5nX21hcmtldF91cGRhdGU6IDcxLFxuICBldmVudF91cGRhdGVfc3RhdHVzOiA3MlxufTtcblxudmFyIENoYWluVHlwZXMgPSB7XG4gIHJlc2VydmVkX3NwYWNlczogcmVzZXJ2ZWRfc3BhY2VzLFxuICBvYmplY3RfdHlwZTogb2JqZWN0X3R5cGUsXG4gIGltcGxfb2JqZWN0X3R5cGU6IGltcGxfb2JqZWN0X3R5cGUsXG4gIHZvdGVfdHlwZTogdm90ZV90eXBlLFxuICBvcGVyYXRpb25zOiBvcGVyYXRpb25zXG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBDaGFpblR5cGVzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYnl0ZWJ1ZmZlciA9IHJlcXVpcmUoMzgpO1xuXG52YXIgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uID0gcmVxdWlyZSgyMSk7XG5cbnZhciBfU2VyaWFsaXplclZhbGlkYXRpb24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2VyaWFsaXplclZhbGlkYXRpb24pO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgREJfTUFYX0lOU1RBTkNFX0lEID0gX2J5dGVidWZmZXIuTG9uZy5mcm9tTnVtYmVyKE1hdGgucG93KDIsIDQ4KSAtIDEpO1xuXG52YXIgT2JqZWN0SWQgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIE9iamVjdElkKHNwYWNlLCB0eXBlLCBpbnN0YW5jZSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBPYmplY3RJZCk7XG5cbiAgICB0aGlzLnNwYWNlID0gc3BhY2U7XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB0aGlzLmluc3RhbmNlID0gaW5zdGFuY2U7XG4gICAgdmFyIGluc3RhbmNlX3N0cmluZyA9IHRoaXMuaW5zdGFuY2UudG9TdHJpbmcoKTtcbiAgICB2YXIgaWQgPSB0aGlzLnNwYWNlICsgJy4nICsgdGhpcy50eXBlICsgJy4nICsgaW5zdGFuY2Vfc3RyaW5nO1xuXG4gICAgaWYgKCFfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQuaXNfZGlnaXRzKGluc3RhbmNlX3N0cmluZykpIHtcbiAgICAgIHRocm93IG5ldyAoJ0ludmFsaWQgb2JqZWN0IGlkICcgKyBpZCkoKTtcbiAgICB9XG4gIH1cblxuICBPYmplY3RJZC5mcm9tU3RyaW5nID0gZnVuY3Rpb24gZnJvbVN0cmluZyh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZS5zcGFjZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLnR5cGUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZS5pbnN0YW5jZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdmFyIHBhcmFtcyA9IF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX21hdGNoKC9eKFswLTldKylcXC4oWzAtOV0rKVxcLihbMC05XSspJC8sIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZCh2YWx1ZSwgJ09iamVjdElkJyksICdPYmplY3RJZCcpO1xuICAgIHJldHVybiBuZXcgT2JqZWN0SWQocGFyc2VJbnQocGFyYW1zWzFdLCAxMCksIHBhcnNlSW50KHBhcmFtc1syXSwgMTApLCBfYnl0ZWJ1ZmZlci5Mb25nLmZyb21TdHJpbmcocGFyYW1zWzNdKSk7XG4gIH07XG5cbiAgT2JqZWN0SWQuZnJvbUxvbmcgPSBmdW5jdGlvbiBmcm9tTG9uZyhsb25nKSB7XG4gICAgdmFyIHNwYWNlID0gbG9uZy5zaGlmdFJpZ2h0KDU2KS50b0ludCgpO1xuICAgIHZhciB0eXBlID0gbG9uZy5zaGlmdFJpZ2h0KDQ4KS50b0ludCgpICYgMHgwMGZmOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgdmFyIGluc3RhbmNlID0gbG9uZy5hbmQoREJfTUFYX0lOU1RBTkNFX0lEKTtcbiAgICByZXR1cm4gbmV3IE9iamVjdElkKHNwYWNlLCB0eXBlLCBpbnN0YW5jZSk7XG4gIH07XG5cbiAgT2JqZWN0SWQuZnJvbUJ5dGVCdWZmZXIgPSBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIE9iamVjdElkLmZyb21Mb25nKGIucmVhZFVpbnQ2NCgpKTtcbiAgfTtcblxuICBPYmplY3RJZC5wcm90b3R5cGUudG9Mb25nID0gZnVuY3Rpb24gdG9Mb25nKCkge1xuICAgIHJldHVybiBfYnl0ZWJ1ZmZlci5Mb25nLmZyb21OdW1iZXIodGhpcy5zcGFjZSkuc2hpZnRMZWZ0KDU2KS5vcihfYnl0ZWJ1ZmZlci5Mb25nLmZyb21OdW1iZXIodGhpcy50eXBlKS5zaGlmdExlZnQoNDgpLm9yKHRoaXMuaW5zdGFuY2UpKTtcbiAgfTtcblxuICBPYmplY3RJZC5wcm90b3R5cGUuYXBwZW5kQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYikge1xuICAgIHJldHVybiBiLndyaXRlVWludDY0KHRoaXMudG9Mb25nKCkpO1xuICB9O1xuXG4gIE9iamVjdElkLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLnNwYWNlICsgJy4nICsgdGhpcy50eXBlICsgJy4nICsgdGhpcy5pbnN0YW5jZS50b1N0cmluZygpO1xuICB9O1xuXG4gIHJldHVybiBPYmplY3RJZDtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gT2JqZWN0SWQ7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfcGVlcnBsYXlzanNXcyA9IHJlcXVpcmUoJ3BlZXJwbGF5c2pzLXdzJyk7XG5cbnZhciBfZWNjID0gcmVxdWlyZSgnLi4vLi4vZWNjJyk7XG5cbnZhciBfc2VyaWFsaXplciA9IHJlcXVpcmUoJy4uLy4uL3NlcmlhbGl6ZXInKTtcblxudmFyIF9DaGFpblR5cGVzID0gcmVxdWlyZSgnLi9DaGFpblR5cGVzJyk7XG5cbnZhciBfQ2hhaW5UeXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpblR5cGVzKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIFRyYW5zYWN0aW9uQnVpbGRlciA9IGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gVHJhbnNhY3Rpb25CdWlsZGVyKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUcmFuc2FjdGlvbkJ1aWxkZXIpO1xuXG4gICAgdGhpcy5yZWZfYmxvY2tfbnVtID0gMDtcbiAgICB0aGlzLnJlZl9ibG9ja19wcmVmaXggPSAwO1xuICAgIHRoaXMuZXhwaXJhdGlvbiA9IDA7XG4gICAgdGhpcy5vcGVyYXRpb25zID0gW107XG4gICAgdGhpcy5zaWduYXR1cmVzID0gW107XG4gICAgdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzID0gW107XG5cbiAgICB0aGlzLmhlYWRfYmxvY2tfdGltZV9zdHJpbmcgPSBudWxsO1xuICAgIHRoaXMuY29tbWl0dGVlX21pbl9yZXZpZXcgPSBudWxsO1xuXG4gICAgLy8gc2VtaS1wcml2YXRlIG1ldGhvZCBiaW5kaW5nc1xuICAgIHRoaXMuX2Jyb2FkY2FzdCA9IHRoaXMuX2Jyb2FkY2FzdC5iaW5kKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAgICAgIEBhcmcge3N0cmluZ30gbmFtZSAtIGxpa2UgXCJ0cmFuc2ZlclwiXG4gICAgICAgIEBhcmcge29iamVjdH0gb3BlcmF0aW9uIC0gSlNPTiBtYXRjaGNoaW5nIHRoZSBvcGVyYXRpb24ncyBmb3JtYXRcbiAgICAqL1xuXG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5hZGRfdHlwZV9vcGVyYXRpb24gPSBmdW5jdGlvbiBhZGRfdHlwZV9vcGVyYXRpb24obmFtZSwgb3BlcmF0aW9uKSB7XG4gICAgdGhpcy5hZGRfb3BlcmF0aW9uKHRoaXMuZ2V0X3R5cGVfb3BlcmF0aW9uKG5hbWUsIG9wZXJhdGlvbikpO1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBUaGlzIGRvZXMgaXQgYWxsOiBzZXQgZmVlcywgZmluYWxpemUsIHNpZ24sIGFuZCBicm9hZGNhc3QgKGlmIHdhbnRlZCkuXG4gICAgICAgICBAYXJnIHtDb25maWRlbnRpYWxXYWxsZXR9IGN3YWxsZXQgLSBtdXN0IGJlIHVubG9ja2VkLCB1c2VkIHRvIGdhdGhlciBzaWduaW5nIGtleXNcbiAgICAgICAgIEBhcmcge2FycmF5PHN0cmluZz59IFtzaWduZXJfcHVia2V5cyA9IG51bGxdIC0gT3B0aW9uYWwgW1wiR1BIQWJjOURlZjAuLi5cIiwgLi4uXS4gIFRoZXNlIGFyZVxuICAgICAgICBhZGRpdGlvbmFsIHNpZ25pbmcga2V5cy4gIFNvbWUgYmFsYW5jZSBjbGFpbXMgcmVxdWlyZSBwcm9wcml0YXJ5IGFkZHJlc3MgZm9ybWF0cywgdGhlXG4gICAgICAgIHdpdG5lc3Mgbm9kZSBjYW4ndCB0ZWxsIHVzIHdoaWNoIG9uZXMgYXJlIG5lZWRlZCBzbyB0aGV5IG11c3QgYmUgcGFzc2VkIGluLiAgSWYgdGhlXG4gICAgICAgIHdpdG5lc3Mgbm9kZSBjYW4gZmlndXJlIG91dCBhIHNpZ25pbmcga2V5IChtb3N0bHkgYWxsIG90aGVyIHRyYW5zYWN0aW9ucyksIGl0IHNob3VsZFxuICAgICAgICBub3QgYmUgcGFzc2VkIGluIGhlcmUuXG4gICAgICAgICBAYXJnIHtib29sZWFufSBbYnJvYWRjYXN0ID0gZmFsc2VdXG4gICAgKi9cblxuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUucHJvY2Vzc190cmFuc2FjdGlvbiA9IGZ1bmN0aW9uIHByb2Nlc3NfdHJhbnNhY3Rpb24oY3dhbGxldCkge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgc2lnbmVyX3B1YmtleXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IG51bGw7XG4gICAgdmFyIGJyb2FkY2FzdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogZmFsc2U7XG4gICAgdmFyIHdhbGxldF9vYmplY3QgPSBjd2FsbGV0LndhbGxldC53YWxsZXRfb2JqZWN0O1xuXG5cbiAgICBpZiAoX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmNoYWluX2lkICE9PSB3YWxsZXRfb2JqZWN0LmdldCgnY2hhaW5faWQnKSkge1xuICAgICAgdmFyIHdhbGxldF9jaGFpbl9pZCA9IHdhbGxldF9vYmplY3QuZ2V0KCdjaGFpbl9pZCcpO1xuICAgICAgdmFyIGFwaV9jaGFpbl9pZCA9IF9wZWVycGxheXNqc1dzLkFwaXMuaW5zdGFuY2UoKS5jaGFpbl9pZDtcblxuICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdNaXNtYXRjaGVkIGNoYWluX2lkOyBleHBlY3RpbmcgJyArIHdhbGxldF9jaGFpbl9pZCArICcsIGJ1dCBnb3QgJyArIGFwaV9jaGFpbl9pZCk7XG5cbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc2V0X3JlcXVpcmVkX2ZlZXMoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBzaWduZXJfcHVia2V5c19hZGRlZCA9IHt9O1xuXG4gICAgICBpZiAoc2lnbmVyX3B1YmtleXMpIHtcbiAgICAgICAgLy8gQmFsYW5jZSBjbGFpbXMgYXJlIGJ5IGFkZHJlc3MsIG9ubHkgdGhlIHByaXZhdGVcbiAgICAgICAgLy8ga2V5IGhvbGRlciBjYW4ga25vdyBhYm91dCB0aGVzZSBhZGRpdGlvbmFsXG4gICAgICAgIC8vIHBvdGVudGlhbCBrZXlzLlxuICAgICAgICB2YXIgcHVia2V5cyA9IGN3YWxsZXQuZ2V0UHVia2V5c19oYXZpbmdfUHJpdmF0ZUtleShzaWduZXJfcHVia2V5cyk7XG5cbiAgICAgICAgaWYgKCFwdWJrZXlzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzaWduaW5nIGtleScpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhwdWJrZXlzKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0ga2V5cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIHZhciBwdWJrZXlfc3RyaW5nID0gcHVia2V5c1tpXTtcbiAgICAgICAgICB2YXIgcHJpdmF0ZV9rZXkgPSBjd2FsbGV0LmdldFByaXZhdGVLZXkocHVia2V5X3N0cmluZyk7XG4gICAgICAgICAgX3RoaXMuYWRkX3NpZ25lcihwcml2YXRlX2tleSwgcHVia2V5X3N0cmluZyk7XG4gICAgICAgICAgc2lnbmVyX3B1YmtleXNfYWRkZWRbcHVia2V5X3N0cmluZ10gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBfdGhpcy5nZXRfcG90ZW50aWFsX3NpZ25hdHVyZXMoKS50aGVuKGZ1bmN0aW9uIChfcmVmKSB7XG4gICAgICAgIHZhciBwdWJrZXlzID0gX3JlZi5wdWJrZXlzLFxuICAgICAgICAgICAgYWRkeXMgPSBfcmVmLmFkZHlzO1xuXG4gICAgICAgIHZhciBteV9wdWJrZXlzID0gY3dhbGxldC5nZXRQdWJrZXlzX2hhdmluZ19Qcml2YXRlS2V5KHB1YmtleXMsIGFkZHlzKTtcblxuICAgICAgICByZXR1cm4gX3RoaXMuZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMobXlfcHVia2V5cykudGhlbihmdW5jdGlvbiAocmVxdWlyZWRfcHVia2V5cykge1xuICAgICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMocmVxdWlyZWRfcHVia2V5cyk7XG5cbiAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9sZW4gPSBrZXlzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgX3B1YmtleV9zdHJpbmcgPSBrZXlzW19pXTtcblxuICAgICAgICAgICAgaWYgKCFzaWduZXJfcHVia2V5c19hZGRlZFtfcHVia2V5X3N0cmluZ10pIHtcbiAgICAgICAgICAgICAgdmFyIF9wcml2YXRlX2tleSA9IGN3YWxsZXQuZ2V0UHJpdmF0ZUtleShfcHVia2V5X3N0cmluZyk7XG5cbiAgICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgbm90IGhhcHBlbiwgZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMgd2lsbCBvbmx5XG4gICAgICAgICAgICAgIC8vIHJldHVybmVkIGtleXMgZnJvbSBteV9wdWJrZXlzXG4gICAgICAgICAgICAgIGlmICghX3ByaXZhdGVfa2V5KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHNpZ25pbmcga2V5IGZvciAnICsgX3B1YmtleV9zdHJpbmcpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgX3RoaXMuYWRkX3NpZ25lcihfcHJpdmF0ZV9rZXksIF9wdWJrZXlfc3RyaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBicm9hZGNhc3QgPyBfdGhpcy5icm9hZGNhc3QoKSA6IF90aGlzLnNlcmlhbGl6ZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqIFR5cGljYWxseSB0aGlzIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IGp1c3QgcHJpb3IgdG8gc2lnbmluZy5cbiAgICogT25jZSBmaW5hbGl6ZWQgdGhpcyB0cmFuc2FjdGlvbiBjYW4gbm90IGJlIGNoYW5nZWQuICovXG5cblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLmZpbmFsaXplID0gZnVuY3Rpb24gZmluYWxpemUoKSB7XG4gICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgIGlmIChfdGhpczIudHJfYnVmZmVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBmaW5hbGl6ZWQnKTtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZShfcGVlcnBsYXlzanNXcy5BcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYygnZ2V0X29iamVjdHMnLCBbWycyLjEuMCddXSkudGhlbihmdW5jdGlvbiAocikge1xuICAgICAgICBfdGhpczIuaGVhZF9ibG9ja190aW1lX3N0cmluZyA9IHJbMF0udGltZTtcblxuICAgICAgICBpZiAoX3RoaXMyLmV4cGlyYXRpb24gPT09IDApIHtcbiAgICAgICAgICBfdGhpczIuZXhwaXJhdGlvbiA9IF90aGlzMi5iYXNlX2V4cGlyYXRpb25fc2VjKCkgKyBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5leHBpcmVfaW5fc2VjcztcbiAgICAgICAgfVxuXG4gICAgICAgIF90aGlzMi5yZWZfYmxvY2tfbnVtID0gclswXS5oZWFkX2Jsb2NrX251bWJlciAmIDB4ZmZmZjsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgICBfdGhpczIucmVmX2Jsb2NrX3ByZWZpeCA9IEJ1ZmZlci5mcm9tKHJbMF0uaGVhZF9ibG9ja19pZCwgJ2hleCcpLnJlYWRVSW50MzJMRSg0KTtcbiAgICAgICAgLy8gREVCVUcgY29uc29sZS5sb2coXCJyZWZfYmxvY2tcIixAcmVmX2Jsb2NrX251bSxAcmVmX2Jsb2NrX3ByZWZpeCxyKVxuXG4gICAgICAgIHZhciBpdGVyYWJsZSA9IF90aGlzMi5vcGVyYXRpb25zO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBpdGVyYWJsZS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIHZhciBvcCA9IGl0ZXJhYmxlW2ldO1xuXG4gICAgICAgICAgaWYgKG9wWzFdLmZpbmFsaXplKSB7XG4gICAgICAgICAgICBvcFsxXS5maW5hbGl6ZSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfdHlwZSA9IF9zZXJpYWxpemVyLm9wcy5vcGVyYXRpb24uc3Rfb3BlcmF0aW9uc1tvcFswXV07XG4gICAgICAgICAgdmFyIGhleEJ1ZmZlciA9IF90eXBlLnRvQnVmZmVyKG9wWzFdKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ09wZXJhdGlvbiAlczogJU8gPT4gJXMgKCVkIGJ5dGVzKScsIF90eXBlLm9wZXJhdGlvbl9uYW1lLCBvcFsxXSwgaGV4QnVmZmVyLCBoZXhCdWZmZXIubGVuZ3RoIC8gMik7XG4gICAgICAgIH1cblxuICAgICAgICBfdGhpczIudHJfYnVmZmVyID0gX3NlcmlhbGl6ZXIub3BzLnRyYW5zYWN0aW9uLnRvQnVmZmVyKF90aGlzMik7XG4gICAgICB9KSk7XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqIEByZXR1cm4ge3N0cmluZ30gaGV4IHRyYW5zYWN0aW9uIElEICovXG5cblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLmlkID0gZnVuY3Rpb24gaWQoKSB7XG4gICAgaWYgKCF0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgZmluYWxpemVkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9lY2MuaGFzaC5zaGEyNTYodGhpcy50cl9idWZmZXIpLnRvU3RyaW5nKCdoZXgnKS5zdWJzdHJpbmcoMCwgNDApO1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBUeXBpY2FsbHkgb25lIHdpbGwgdXNlIHtAbGluayB0aGlzLmFkZF90eXBlX29wZXJhdGlvbn0gaW5zdGVhZC5cbiAgICAgICAgQGFyZyB7YXJyYXl9IG9wZXJhdGlvbiAtIFtvcGVyYXRpb25faWQsIG9wZXJhdGlvbl1cbiAgICAqL1xuXG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5hZGRfb3BlcmF0aW9uID0gZnVuY3Rpb24gYWRkX29wZXJhdGlvbihvcGVyYXRpb24pIHtcbiAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBmaW5hbGl6ZWQnKTtcbiAgICB9XG5cbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkob3BlcmF0aW9uLCAnb3BlcmF0aW9uJyk7XG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkob3BlcmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RpbmcgYXJyYXkgW29wZXJhdGlvbl9pZCwgb3BlcmF0aW9uXScpO1xuICAgIH1cblxuICAgIHRoaXMub3BlcmF0aW9ucy5wdXNoKG9wZXJhdGlvbik7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5nZXRfdHlwZV9vcGVyYXRpb24gPSBmdW5jdGlvbiBnZXRfdHlwZV9vcGVyYXRpb24obmFtZSwgb3BlcmF0aW9uKSB7XG4gICAgaWYgKHRoaXMudHJfYnVmZmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FscmVhZHkgZmluYWxpemVkJyk7XG4gICAgfVxuXG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKG5hbWUsICduYW1lJyk7XG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKG9wZXJhdGlvbiwgJ29wZXJhdGlvbicpO1xuICAgIHZhciBfdHlwZSA9IF9zZXJpYWxpemVyLm9wc1tuYW1lXTtcbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoX3R5cGUsICdVbmtub3duIG9wZXJhdGlvbiAnICsgbmFtZSk7XG4gICAgdmFyIG9wZXJhdGlvbl9pZCA9IF9DaGFpblR5cGVzMi5kZWZhdWx0Lm9wZXJhdGlvbnNbX3R5cGUub3BlcmF0aW9uX25hbWVdO1xuXG4gICAgaWYgKG9wZXJhdGlvbl9pZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gb3BlcmF0aW9uOiAnICsgX3R5cGUub3BlcmF0aW9uX25hbWUpO1xuICAgIH1cblxuICAgIGlmICghb3BlcmF0aW9uLmZlZSkge1xuICAgICAgb3BlcmF0aW9uLmZlZSA9IHsgYW1vdW50OiAwLCBhc3NldF9pZDogMCB9O1xuICAgIH1cblxuICAgIGlmIChuYW1lID09PSAncHJvcG9zYWxfY3JlYXRlJykge1xuICAgICAgLypcbiAgICAgICAgICAgICogUHJvcG9zYWxzIGludm9sdmluZyB0aGUgY29tbWl0dGVlIGFjY291bnQgcmVxdWlyZSBhIHJldmlld1xuICAgICAgICAgICAgKiBwZXJpb2QgdG8gYmUgc2V0LCBsb29rIGZvciB0aGVtIGhlcmVcbiAgICAgICAgICAgICovXG4gICAgICB2YXIgcmVxdWlyZXNSZXZpZXcgPSBmYWxzZTtcbiAgICAgIHZhciBleHRyYVJldmlldyA9IDA7XG5cbiAgICAgIG9wZXJhdGlvbi5wcm9wb3NlZF9vcHMuZm9yRWFjaChmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgdmFyIENPTU1JVFRFX0FDQ09VTlQgPSAwO1xuICAgICAgICB2YXIga2V5ID0gdm9pZCAwO1xuXG4gICAgICAgIHN3aXRjaCAob3Aub3BbMF0pIHtcbiAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAvLyB0cmFuc2ZlclxuICAgICAgICAgICAga2V5ID0gJ2Zyb20nO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDY6IC8vIGFjY291bnRfdXBkYXRlXG4gICAgICAgICAgY2FzZSAxNzpcbiAgICAgICAgICAgIC8vIGFzc2V0X3NldHRsZVxuICAgICAgICAgICAga2V5ID0gJ2FjY291bnQnO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDEwOiAvLyBhc3NldF9jcmVhdGVcbiAgICAgICAgICBjYXNlIDExOiAvLyBhc3NldF91cGRhdGVcbiAgICAgICAgICBjYXNlIDEyOiAvLyBhc3NldF91cGRhdGVfYml0YXNzZXRcbiAgICAgICAgICBjYXNlIDEzOiAvLyBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnNcbiAgICAgICAgICBjYXNlIDE0OiAvLyBhc3NldF9pc3N1ZVxuICAgICAgICAgIGNhc2UgMTg6IC8vIGFzc2V0X2dsb2JhbF9zZXR0bGVcbiAgICAgICAgICBjYXNlIDQzOlxuICAgICAgICAgICAgLy8gYXNzZXRfY2xhaW1fZmVlc1xuICAgICAgICAgICAga2V5ID0gJ2lzc3Vlcic7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgMTU6XG4gICAgICAgICAgICAvLyBhc3NldF9yZXNlcnZlXG4gICAgICAgICAgICBrZXkgPSAncGF5ZXInO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDE2OlxuICAgICAgICAgICAgLy8gYXNzZXRfZnVuZF9mZWVfcG9vbFxuICAgICAgICAgICAga2V5ID0gJ2Zyb21fYWNjb3VudCc7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgMjI6IC8vIHByb3Bvc2FsX2NyZWF0ZVxuICAgICAgICAgIGNhc2UgMjM6IC8vIHByb3Bvc2FsX3VwZGF0ZVxuICAgICAgICAgIGNhc2UgMjQ6XG4gICAgICAgICAgICAvLyBwcm9wb3NhbF9kZWxldGVcbiAgICAgICAgICAgIGtleSA9ICdmZWVfcGF5aW5nX2FjY291bnQnO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDMxOlxuICAgICAgICAgICAgLy8gY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnNcbiAgICAgICAgICAgIHJlcXVpcmVzUmV2aWV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGV4dHJhUmV2aWV3ID0gNjAgKiA2MCAqIDI0ICogMTM7IC8vIE1ha2UgdGhlIHJldmlldyBwZXJpb2QgMiB3ZWVrcyB0b3RhbFxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGtleSBpbiBvcC5vcFsxXSAmJiBvcC5vcFsxXVtrZXldID09PSBDT01NSVRURV9BQ0NPVU5UKSB7XG4gICAgICAgICAgcmVxdWlyZXNSZXZpZXcgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKCFvcGVyYXRpb24uZXhwaXJhdGlvbl90aW1lKSB7XG4gICAgICAgIHZhciBleHBlcmF0aW9uVGltZSA9IHRoaXMuYmFzZV9leHBpcmF0aW9uX3NlYygpO1xuICAgICAgICBvcGVyYXRpb24uZXhwaXJhdGlvbl90aW1lID0gZXhwZXJhdGlvblRpbWUgKyBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5leHBpcmVfaW5fc2Vjc19wcm9wb3NhbDtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcXVpcmVzUmV2aWV3KSB7XG4gICAgICAgIHZhciBvbmVfZGF5ID0gMjQgKiA2MCAqIDYwOyAvLyBPbmUgZGF5IGluIHNlY29uZHNcbiAgICAgICAgdmFyIG1heCA9IE1hdGgubWF4KHRoaXMuY29tbWl0ZWVfbWluX3Jldmlldywgb25lX2RheSwgX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcucmV2aWV3X2luX3NlY3NfY29tbWl0dGVlKTtcblxuICAgICAgICBvcGVyYXRpb24ucmV2aWV3X3BlcmlvZF9zZWNvbmRzID0gZXh0cmFSZXZpZXcgKyBtYXg7XG4gICAgICAgIC8qXG4gICAgICAgICAgICAgICAgKiBFeHBpcmF0aW9uIHRpbWUgbXVzdCBiZSBhdCBsZWFzdCBlcXVhbCB0b1xuICAgICAgICAgICAgICAgICogbm93ICsgcmV2aWV3X3BlcmlvZF9zZWNvbmRzLCBzbyB3ZSBhZGQgb25lIGhvdXIgdG8gbWFrZSBzdXJlXG4gICAgICAgICAgICAgICAgKi9cbiAgICAgICAgb3BlcmF0aW9uLmV4cGlyYXRpb25fdGltZSArPSA2MCAqIDYwICsgZXh0cmFSZXZpZXc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIG9wZXJhdGlvbl9pbnN0YW5jZSA9IF90eXBlLmZyb21PYmplY3Qob3BlcmF0aW9uKTtcbiAgICByZXR1cm4gW29wZXJhdGlvbl9pZCwgb3BlcmF0aW9uX2luc3RhbmNlXTtcbiAgfTtcblxuICAvKiBvcHRpb25hbDogZmV0Y2ggdGhlIGN1cnJlbnQgaGVhZCBibG9jayAqL1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUudXBkYXRlX2hlYWRfYmxvY2sgPSBmdW5jdGlvbiB1cGRhdGVfaGVhZF9ibG9jaygpIHtcbiAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgIHJldHVybiBfcGVlcnBsYXlzanNXcy5BcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYygnZ2V0X29iamVjdHMnLCBbWycyLjAuMCcsICcyLjEuMCddXSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICB2YXIgZyA9IHJlc1swXSxcbiAgICAgICAgICByID0gcmVzWzFdO1xuXG4gICAgICBfdGhpczMuaGVhZF9ibG9ja190aW1lX3N0cmluZyA9IHJbMF0udGltZTtcbiAgICAgIF90aGlzMy5jb21taXR0ZWVfbWluX3JldmlldyA9IGdbMF0ucGFyYW1ldGVycy5jb21taXR0ZWVfcHJvcG9zYWxfcmV2aWV3X3BlcmlvZDtcbiAgICB9KTtcbiAgfTtcblxuICAvKiogb3B0aW9uYWw6IHRoZXJlIGlzIGEgZGVhZnVsdCBleHBpcmF0aW9uICovXG5cblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLnNldF9leHBpcmVfc2Vjb25kcyA9IGZ1bmN0aW9uIHNldF9leHBpcmVfc2Vjb25kcyhzZWMpIHtcbiAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBmaW5hbGl6ZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLmV4cGlyYXRpb24gPSB0aGlzLmJhc2VfZXhwaXJhdGlvbl9zZWMoKSArIHNlYztcblxuICAgIHJldHVybiB0aGlzLmV4cGlyYXRpb247XG4gIH07XG5cbiAgLyogV3JhcHMgdGhpcyB0cmFuc2FjdGlvbiBpbiBhIHByb3Bvc2FsX2NyZWF0ZSB0cmFuc2FjdGlvbiAqL1xuXG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5wcm9wb3NlID0gZnVuY3Rpb24gcHJvcG9zZShwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucykge1xuICAgIGlmICh0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhbHJlYWR5IGZpbmFsaXplZCcpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5vcGVyYXRpb25zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhZGQgb3BlcmF0aW9uIGZpcnN0Jyk7XG4gICAgfVxuXG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKHByb3Bvc2FsX2NyZWF0ZV9vcHRpb25zLCAncHJvcG9zYWxfY3JlYXRlX29wdGlvbnMnKTtcbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkocHJvcG9zYWxfY3JlYXRlX29wdGlvbnMuZmVlX3BheWluZ19hY2NvdW50LCAncHJvcG9zYWxfY3JlYXRlX29wdGlvbnMuZmVlX3BheWluZ19hY2NvdW50Jyk7XG5cbiAgICB2YXIgcHJvcG9zZWRfb3BzID0gdGhpcy5vcGVyYXRpb25zLm1hcChmdW5jdGlvbiAob3ApIHtcbiAgICAgIHJldHVybiB7IG9wOiBvcCB9O1xuICAgIH0pO1xuXG4gICAgdGhpcy5vcGVyYXRpb25zID0gW107XG4gICAgdGhpcy5zaWduYXR1cmVzID0gW107XG4gICAgdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzID0gW107XG4gICAgcHJvcG9zYWxfY3JlYXRlX29wdGlvbnMucHJvcG9zZWRfb3BzID0gcHJvcG9zZWRfb3BzO1xuICAgIHRoaXMuYWRkX3R5cGVfb3BlcmF0aW9uKCdwcm9wb3NhbF9jcmVhdGUnLCBwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5oYXNfcHJvcG9zZWRfb3BlcmF0aW9uID0gZnVuY3Rpb24gaGFzX3Byb3Bvc2VkX29wZXJhdGlvbigpIHtcbiAgICB2YXIgaGFzUHJvcG9zZWQgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5vcGVyYXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoJ3Byb3Bvc2VkX29wcycgaW4gdGhpcy5vcGVyYXRpb25zW2ldWzFdKSB7XG4gICAgICAgIGhhc1Byb3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGhhc1Byb3Bvc2VkO1xuICB9O1xuXG4gIC8qKiBvcHRpb25hbDogdGhlIGZlZXMgY2FuIGJlIG9idGFpbmVkIGZyb20gdGhlIHdpdG5lc3Mgbm9kZSAqL1xuXG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5zZXRfcmVxdWlyZWRfZmVlcyA9IGZ1bmN0aW9uIHNldF9yZXF1aXJlZF9mZWVzKGFzc2V0X2lkKSB7XG4gICAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgICB2YXIgZmVlX3Bvb2wgPSB2b2lkIDA7XG5cbiAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBmaW5hbGl6ZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMub3BlcmF0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWRkIG9wZXJhdGlvbnMgZmlyc3QnKTtcbiAgICB9XG5cbiAgICB2YXIgb3BlcmF0aW9ucyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMub3BlcmF0aW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgdmFyIG9wID0gdGhpcy5vcGVyYXRpb25zW2ldO1xuICAgICAgb3BlcmF0aW9ucy5wdXNoKF9zZXJpYWxpemVyLm9wcy5vcGVyYXRpb24udG9PYmplY3Qob3ApKTtcbiAgICB9XG5cbiAgICBpZiAoIWFzc2V0X2lkKSB7XG4gICAgICB2YXIgb3AxX2ZlZSA9IG9wZXJhdGlvbnNbMF1bMV0uZmVlO1xuXG4gICAgICBpZiAob3AxX2ZlZSAmJiBvcDFfZmVlLmFzc2V0X2lkICE9PSBudWxsKSB7XG4gICAgICAgIGFzc2V0X2lkID0gb3AxX2ZlZS5hc3NldF9pZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFzc2V0X2lkID0gJzEuMy4wJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZXMgPSBbX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoJ2dldF9yZXF1aXJlZF9mZWVzJywgW29wZXJhdGlvbnMsIGFzc2V0X2lkXSldO1xuXG4gICAgaWYgKGFzc2V0X2lkICE9PSAnMS4zLjAnKSB7XG4gICAgICAvLyBUaGlzIGhhbmRsZXMgdGhlIGZhbGxiYWNrIHRvIHBheWluZyBmZWVzIGluIEJUUyBpZiB0aGUgZmVlIHBvb2wgaXMgZW1wdHkuXG4gICAgICBwcm9taXNlcy5wdXNoKF9wZWVycGxheXNqc1dzLkFwaXMuaW5zdGFuY2UoKS5kYl9hcGkoKS5leGVjKCdnZXRfcmVxdWlyZWRfZmVlcycsIFtvcGVyYXRpb25zLCAnMS4zLjAnXSkpO1xuICAgICAgcHJvbWlzZXMucHVzaChfcGVlcnBsYXlzanNXcy5BcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYygnZ2V0X29iamVjdHMnLCBbW2Fzc2V0X2lkXV0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oZnVuY3Rpb24gKHJlc3VsdHMpIHtcbiAgICAgIHZhciBmZWVzID0gcmVzdWx0c1swXSxcbiAgICAgICAgICBjb3JlRmVlcyA9IHJlc3VsdHNbMV0sXG4gICAgICAgICAgYXNzZXQgPSByZXN1bHRzWzJdO1xuXG4gICAgICBhc3NldCA9IGFzc2V0ID8gYXNzZXRbMF0gOiBudWxsO1xuXG4gICAgICB2YXIgZHluYW1pY1Byb21pc2UgPSBhc3NldF9pZCAhPT0gJzEuMy4wJyAmJiBhc3NldCA/IF9wZWVycGxheXNqc1dzLkFwaXMuaW5zdGFuY2UoKS5kYl9hcGkoKS5leGVjKCdnZXRfb2JqZWN0cycsIFtbYXNzZXQuZHluYW1pY19hc3NldF9kYXRhX2lkXV0pIDogbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBkeW5hbWljUHJvbWlzZS50aGVuKGZ1bmN0aW9uIChkeW5hbWljT2JqZWN0KSB7XG4gICAgICAgIGlmIChhc3NldF9pZCAhPT0gJzEuMy4wJykge1xuICAgICAgICAgIGZlZV9wb29sID0gZHluYW1pY09iamVjdCA/IGR5bmFtaWNPYmplY3RbMF0uZmVlX3Bvb2wgOiAwO1xuICAgICAgICAgIHZhciB0b3RhbEZlZXMgPSAwO1xuXG4gICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGZlZTsgaiA8IGNvcmVGZWVzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBmZWUgPSBjb3JlRmVlc1tqXTtcbiAgICAgICAgICAgIHRvdGFsRmVlcyArPSBmZWUuYW1vdW50O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0b3RhbEZlZXMgPiBwYXJzZUludChmZWVfcG9vbCwgMTApKSB7XG4gICAgICAgICAgICBmZWVzID0gY29yZUZlZXM7XG4gICAgICAgICAgICBhc3NldF9pZCA9ICcxLjMuMCc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvcG9zZWQgdHJhbnNhY3Rpb25zIG5lZWQgdG8gYmUgZmxhdHRlbmVkXG4gICAgICAgIHZhciBmbGF0X2Fzc2V0cyA9IFtdO1xuXG4gICAgICAgIHZhciBmbGF0dGVuID0gZnVuY3Rpb24gZmxhdHRlbihvYmopIHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBrID0gMCwgX2xlbjIgPSBvYmoubGVuZ3RoOyBrIDwgX2xlbjI7IGsrKykge1xuICAgICAgICAgICAgICB2YXIgaXRlbSA9IG9ialtrXTtcbiAgICAgICAgICAgICAgZmxhdHRlbihpdGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmxhdF9hc3NldHMucHVzaChvYmopO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBmbGF0dGVuKGZlZXMpO1xuXG4gICAgICAgIHZhciBhc3NldF9pbmRleCA9IDA7XG5cbiAgICAgICAgdmFyIHNldF9mZWUgPSBmdW5jdGlvbiBzZXRfZmVlKG9wZXJhdGlvbikge1xuICAgICAgICAgIGlmICghb3BlcmF0aW9uLmZlZSB8fCBvcGVyYXRpb24uZmVlLmFtb3VudCA9PT0gMCB8fCBvcGVyYXRpb24uZmVlLmFtb3VudC50b1N0cmluZyAmJiBvcGVyYXRpb24uZmVlLmFtb3VudC50b1N0cmluZygpID09PSAnMCcgLy8gTG9uZ1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgICBvcGVyYXRpb24uZmVlID0gZmxhdF9hc3NldHNbYXNzZXRfaW5kZXhdO1xuICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIm5ldyBvcGVyYXRpb24uZmVlXCIsIG9wZXJhdGlvbi5mZWUpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIm9sZCBvcGVyYXRpb24uZmVlXCIsIG9wZXJhdGlvbi5mZWUpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBhc3NldF9pbmRleCsrO1xuXG4gICAgICAgICAgaWYgKG9wZXJhdGlvbi5wcm9wb3NlZF9vcHMpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgICAgICAgICAgZm9yICh2YXIgeSA9IDA7IHkgPCBvcGVyYXRpb24ucHJvcG9zZWRfb3BzLmxlbmd0aDsgeSsrKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHNldF9mZWUob3BlcmF0aW9uLnByb3Bvc2VkX29wc1t5XS5vcFsxXSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBmb3IgKHZhciBfaTIgPSAwOyBfaTIgPCBfdGhpczQub3BlcmF0aW9ucy5sZW5ndGg7IF9pMisrKSB7XG4gICAgICAgICAgc2V0X2ZlZShfdGhpczQub3BlcmF0aW9uc1tfaTJdWzFdKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBERUJVRyBjb25zb2xlLmxvZygnLi4uIGdldF9yZXF1aXJlZF9mZWVzJyxvcGVyYXRpb25zLGFzc2V0X2lkLGZsYXRfYXNzZXRzKVxuICAgIH0pO1xuICB9O1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuZ2V0X3BvdGVudGlhbF9zaWduYXR1cmVzID0gZnVuY3Rpb24gZ2V0X3BvdGVudGlhbF9zaWduYXR1cmVzKCkge1xuICAgIHZhciB0cl9vYmplY3QgPSBfc2VyaWFsaXplci5vcHMuc2lnbmVkX3RyYW5zYWN0aW9uLnRvT2JqZWN0KHRoaXMpO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChbX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoJ2dldF9wb3RlbnRpYWxfc2lnbmF0dXJlcycsIFt0cl9vYmplY3RdKSwgX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoJ2dldF9wb3RlbnRpYWxfYWRkcmVzc19zaWduYXR1cmVzJywgW3RyX29iamVjdF0pXSkudGhlbihmdW5jdGlvbiAocmVzdWx0cykge1xuICAgICAgcmV0dXJuIHsgcHVia2V5czogcmVzdWx0c1swXSwgYWRkeXM6IHJlc3VsdHNbMV0gfTtcbiAgICB9KTtcbiAgfTtcblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLmdldF9yZXF1aXJlZF9zaWduYXR1cmVzID0gZnVuY3Rpb24gZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMoYXZhaWxhYmxlX2tleXMpIHtcbiAgICBpZiAoIWF2YWlsYWJsZV9rZXlzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbXSk7XG4gICAgfVxuXG4gICAgdmFyIHRyX29iamVjdCA9IF9zZXJpYWxpemVyLm9wcy5zaWduZWRfdHJhbnNhY3Rpb24udG9PYmplY3QodGhpcyk7XG4gICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiB0cl9vYmplY3QnLHRyX29iamVjdClcbiAgICByZXR1cm4gX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoJ2dldF9yZXF1aXJlZF9zaWduYXR1cmVzJywgW3RyX29iamVjdCwgYXZhaWxhYmxlX2tleXNdKS50aGVuKGZ1bmN0aW9uIChyZXF1aXJlZF9wdWJsaWNfa2V5cykge1xuICAgICAgcmV0dXJuIHJlcXVpcmVkX3B1YmxpY19rZXlzO1xuICAgIH0pO1xuICB9O1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuYWRkX3NpZ25lciA9IGZ1bmN0aW9uIGFkZF9zaWduZXIocHJpdmF0ZV9rZXkpIHtcbiAgICB2YXIgcHVibGljX2tleSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKTtcblxuICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShwcml2YXRlX2tleS5kLCAncmVxdWlyZWQgUHJpdmF0ZUtleSBvYmplY3QnKTtcblxuICAgIGlmICh0aGlzLnNpZ25lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhbHJlYWR5IHNpZ25lZCcpO1xuICAgIH1cblxuICAgIGlmICghcHVibGljX2tleS5RKSB7XG4gICAgICBwdWJsaWNfa2V5ID0gX2VjYy5QdWJsaWNLZXkuZnJvbVB1YmxpY0tleVN0cmluZyhwdWJsaWNfa2V5KTtcbiAgICB9XG5cbiAgICAvLyBwcmV2ZW50IGR1cGxpY2F0ZXNcbiAgICB2YXIgc3BIZXggPSBwcml2YXRlX2tleS50b0hleCgpO1xuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLnNpZ25lcl9wcml2YXRlX2tleXMpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGtleXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBzcCA9IHRoaXMuc2lnbmVyX3ByaXZhdGVfa2V5c1trZXlzW2ldXTtcblxuICAgICAgaWYgKHNwWzBdLnRvSGV4KCkgPT09IHNwSGV4KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnNpZ25lcl9wcml2YXRlX2tleXMucHVzaChbcHJpdmF0ZV9rZXksIHB1YmxpY19rZXldKTtcbiAgfTtcblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbiBzaWduKCkge1xuICAgIHZhciBjaGFpbl9pZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmNoYWluX2lkO1xuXG4gICAgaWYgKCF0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgZmluYWxpemVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2lnbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FscmVhZHkgc2lnbmVkJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnNpZ25lcl9wcml2YXRlX2tleXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zYWN0aW9uIHdhcyBub3Qgc2lnbmVkLiBEbyB5b3UgaGF2ZSBhIHByaXZhdGUga2V5PyBbbm9fc2lnbmVyc10nKTtcbiAgICB9XG5cbiAgICB2YXIgZW5kID0gdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzLmxlbmd0aDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBlbmQgPiAwID8gaSA8IGVuZCA6IGkgPiBlbmQ7IGVuZCA+IDAgPyBpKysgOiBpKyspIHtcbiAgICAgIHZhciBfc2lnbmVyX3ByaXZhdGVfa2V5cyQgPSB0aGlzLnNpZ25lcl9wcml2YXRlX2tleXNbaV0sXG4gICAgICAgICAgcHJpdmF0ZV9rZXkgPSBfc2lnbmVyX3ByaXZhdGVfa2V5cyRbMF0sXG4gICAgICAgICAgcHVibGljX2tleSA9IF9zaWduZXJfcHJpdmF0ZV9rZXlzJFsxXTtcblxuICAgICAgdmFyIHNpZyA9IF9lY2MuU2lnbmF0dXJlLnNpZ25CdWZmZXIoQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oY2hhaW5faWQsICdoZXgnKSwgdGhpcy50cl9idWZmZXJdKSwgcHJpdmF0ZV9rZXksIHB1YmxpY19rZXkpO1xuICAgICAgdGhpcy5zaWduYXR1cmVzLnB1c2goc2lnLnRvQnVmZmVyKCkpO1xuICAgIH1cblxuICAgIHRoaXMuc2lnbmVyX3ByaXZhdGVfa2V5cyA9IFtdO1xuICAgIHRoaXMuc2lnbmVkID0gdHJ1ZTtcbiAgfTtcblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLnNlcmlhbGl6ZSA9IGZ1bmN0aW9uIHNlcmlhbGl6ZSgpIHtcbiAgICByZXR1cm4gX3NlcmlhbGl6ZXIub3BzLnNpZ25lZF90cmFuc2FjdGlvbi50b09iamVjdCh0aGlzKTtcbiAgfTtcblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QoKSB7XG4gICAgcmV0dXJuIF9zZXJpYWxpemVyLm9wcy5zaWduZWRfdHJhbnNhY3Rpb24udG9PYmplY3QodGhpcyk7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5icm9hZGNhc3QgPSBmdW5jdGlvbiBicm9hZGNhc3Qod2FzX2Jyb2FkY2FzdF9jYWxsYmFjaykge1xuICAgIHZhciBfdGhpczUgPSB0aGlzO1xuXG4gICAgaWYgKHRoaXMudHJfYnVmZmVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYnJvYWRjYXN0KHdhc19icm9hZGNhc3RfY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZpbmFsaXplKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gX3RoaXM1Ll9icm9hZGNhc3Qod2FzX2Jyb2FkY2FzdF9jYWxsYmFjayk7XG4gICAgfSk7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5fYnJvYWRjYXN0ID0gZnVuY3Rpb24gX2Jyb2FkY2FzdCh3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKSB7XG4gICAgdmFyIF90aGlzNiA9IHRoaXM7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgaWYgKCFfdGhpczYuc2lnbmVkKSB7XG4gICAgICAgIF90aGlzNi5zaWduKCk7XG4gICAgICB9XG5cbiAgICAgIGlmICghX3RoaXM2LnRyX2J1ZmZlcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vdCBmaW5hbGl6ZWQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFfdGhpczYuc2lnbmF0dXJlcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3Qgc2lnbmVkJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghX3RoaXM2Lm9wZXJhdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm8gb3BlcmF0aW9ucycpO1xuICAgICAgfVxuXG4gICAgICB2YXIgdHJfb2JqZWN0ID0gX3NlcmlhbGl6ZXIub3BzLnNpZ25lZF90cmFuc2FjdGlvbi50b09iamVjdChfdGhpczYpO1xuICAgICAgLy8gY29uc29sZS5sb2coJy4uLiBicm9hZGNhc3RfdHJhbnNhY3Rpb25fd2l0aF9jYWxsYmFjayAhISEnKVxuICAgICAgX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLm5ldHdvcmtfYXBpKCkuZXhlYygnYnJvYWRjYXN0X3RyYW5zYWN0aW9uX3dpdGhfY2FsbGJhY2snLCBbZnVuY3Rpb24gKHJlcykge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXMpO1xuICAgICAgfSwgdHJfb2JqZWN0XSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCcuLi4gYnJvYWRjYXN0IHN1Y2Nlc3MsIHdhaXRpbmcgZm9yIGNhbGxiYWNrJylcbiAgICAgICAgaWYgKHdhc19icm9hZGNhc3RfY2FsbGJhY2spIHtcbiAgICAgICAgICB3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAvLyBjb25zb2xlLmxvZyBtYXkgYmUgcmVkdW5kYW50IGZvciBuZXR3b3JrIGVycm9ycywgb3RoZXIgZXJyb3JzIGNvdWxkIG9jY3VyXG4gICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuXG5cbiAgICAgICAgaWYgKCFtZXNzYWdlKSB7XG4gICAgICAgICAgbWVzc2FnZSA9ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihtZXNzYWdlICsgJ1xcbicgKyAncGVlcnBsYXlzLWNyeXB0byAnICsgKCcgZGlnZXN0ICcgKyBfZWNjLmhhc2guc2hhMjU2KF90aGlzNi50cl9idWZmZXIpLnRvU3RyaW5nKCdoZXgnKSArICcgdHJhbnNhY3Rpb24gJyArIF90aGlzNi50cl9idWZmZXIudG9TdHJpbmcoJ2hleCcpICsgJyAnICsgSlNPTi5zdHJpbmdpZnkodHJfb2JqZWN0KSkpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci50aW1lU3RyaW5nVG9EYXRlID0gZnVuY3Rpb24gdGltZVN0cmluZ1RvRGF0ZSh0aW1lX3N0cmluZykge1xuICAgIGlmICghdGltZV9zdHJpbmcpIHtcbiAgICAgIHRpbWVfc3RyaW5nID0gJzE5NzAtMDEtMDFUMDA6MDA6MDAuMDAwWic7XG4gICAgfVxuXG4gICAgaWYgKCEvWiQvLnRlc3QodGltZV9zdHJpbmcpKSB7XG4gICAgICAvLyBkb2VzIG5vdCBlbmQgaW4gWlxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NyeXB0b25vbWV4L2dyYXBoZW5lL2lzc3Vlcy8zNjhcbiAgICAgIHRpbWVfc3RyaW5nICs9ICdaJztcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IERhdGUodGltZV9zdHJpbmcpO1xuICB9O1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuZ2V0SGVhZEJsb2NrRGF0ZSA9IGZ1bmN0aW9uIGdldEhlYWRCbG9ja0RhdGUoKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uQnVpbGRlci50aW1lU3RyaW5nVG9EYXRlKHRoaXMuaGVhZF9ibG9ja190aW1lX3N0cmluZyk7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5iYXNlX2V4cGlyYXRpb25fc2VjID0gZnVuY3Rpb24gYmFzZV9leHBpcmF0aW9uX3NlYygpIHtcbiAgICB2YXIgaGVhZF9ibG9ja19zZWMgPSBNYXRoLmNlaWwodGhpcy5nZXRIZWFkQmxvY2tEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7XG4gICAgdmFyIG5vd19zZWMgPSBNYXRoLmNlaWwoRGF0ZS5ub3coKSAvIDEwMDApO1xuXG4gICAgLy8gVGhlIGhlYWQgYmxvY2sgdGltZSBzaG91bGQgYmUgdXBkYXRlZCBldmVyeSAzIHNlY29uZHMuICBJZiBpdCBpc24ndFxuICAgIC8vIHRoZW4gaGVscCB0aGUgdHJhbnNhY3Rpb24gdG8gZXhwaXJlICh1c2UgaGVhZF9ibG9ja19zZWMpXG4gICAgaWYgKG5vd19zZWMgLSBoZWFkX2Jsb2NrX3NlYyA+IDMwKSB7XG4gICAgICByZXR1cm4gaGVhZF9ibG9ja19zZWM7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHVzZXIncyBjbG9jayBpcyB2ZXJ5IGZhciBiZWhpbmQsIHVzZSB0aGUgaGVhZCBibG9jayB0aW1lLlxuICAgIHJldHVybiBNYXRoLm1heChub3dfc2VjLCBoZWFkX2Jsb2NrX3NlYyk7XG4gIH07XG5cbiAgcmV0dXJuIFRyYW5zYWN0aW9uQnVpbGRlcjtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gVHJhbnNhY3Rpb25CdWlsZGVyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZnVuY3Rpb24gZ2V0KHN0YXRlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHN0YXRlW2tleV0gfHwgJyc7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHNldChzdGF0ZSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHJldHVybiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIHN0YXRlW2tleV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH07XG59XG5cbmV4cG9ydHMuZ2V0ID0gZ2V0O1xuZXhwb3J0cy5zZXQgPSBzZXQ7IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5rZXkgPSBleHBvcnRzLmhhc2ggPSBleHBvcnRzLmJyYWluS2V5ID0gZXhwb3J0cy5TaWduYXR1cmUgPSBleHBvcnRzLlB1YmxpY0tleSA9IGV4cG9ydHMuUHJpdmF0ZUtleSA9IGV4cG9ydHMuQWVzID0gZXhwb3J0cy5BZGRyZXNzID0gdW5kZWZpbmVkO1xuXG52YXIgX2FkZHJlc3MgPSByZXF1aXJlKDEyKTtcblxudmFyIF9hZGRyZXNzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2FkZHJlc3MpO1xuXG52YXIgX2FlcyA9IHJlcXVpcmUoMTMpO1xuXG52YXIgX2FlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hZXMpO1xuXG52YXIgX1ByaXZhdGVLZXkgPSByZXF1aXJlKDEwKTtcblxudmFyIF9Qcml2YXRlS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1ByaXZhdGVLZXkpO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoMTEpO1xuXG52YXIgX1B1YmxpY0tleTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9QdWJsaWNLZXkpO1xuXG52YXIgX3NpZ25hdHVyZSA9IHJlcXVpcmUoMTgpO1xuXG52YXIgX3NpZ25hdHVyZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zaWduYXR1cmUpO1xuXG52YXIgX0JyYWluS2V5ID0gcmVxdWlyZSg4KTtcblxudmFyIF9CcmFpbktleTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9CcmFpbktleSk7XG5cbnZhciBfaGFzaCA9IHJlcXVpcmUoMTcpO1xuXG52YXIgaGFzaCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9oYXNoKTtcblxudmFyIF9LZXlVdGlscyA9IHJlcXVpcmUoOSk7XG5cbnZhciBfS2V5VXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfS2V5VXRpbHMpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqLmRlZmF1bHQgPSBvYmo7IHJldHVybiBuZXdPYmo7IH0gfVxuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5leHBvcnRzLkFkZHJlc3MgPSBfYWRkcmVzczIuZGVmYXVsdDtcbmV4cG9ydHMuQWVzID0gX2FlczIuZGVmYXVsdDtcbmV4cG9ydHMuUHJpdmF0ZUtleSA9IF9Qcml2YXRlS2V5Mi5kZWZhdWx0O1xuZXhwb3J0cy5QdWJsaWNLZXkgPSBfUHVibGljS2V5Mi5kZWZhdWx0O1xuZXhwb3J0cy5TaWduYXR1cmUgPSBfc2lnbmF0dXJlMi5kZWZhdWx0O1xuZXhwb3J0cy5icmFpbktleSA9IF9CcmFpbktleTIuZGVmYXVsdDtcbmV4cG9ydHMuaGFzaCA9IGhhc2g7XG5leHBvcnRzLmtleSA9IF9LZXlVdGlsczIuZGVmYXVsdDsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLmRlZmF1bHQgPSBub3JtYWxpemU7XG5mdW5jdGlvbiBub3JtYWxpemUoYnJhaW5LZXkpIHtcbiAgaWYgKHR5cGVvZiBicmFpbktleSAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmluZyByZXF1aXJlZCBmb3IgYnJhaW5LZXknKTtcbiAgfVxuXG4gIGJyYWluS2V5ID0gYnJhaW5LZXkudHJpbSgpO1xuICByZXR1cm4gYnJhaW5LZXkuc3BsaXQoL1tcXHRcXG5cXHZcXGZcXHIgXSsvKS5qb2luKCcgJyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfc2VjdXJlUmFuZG9tID0gcmVxdWlyZSgnc2VjdXJlLXJhbmRvbScpO1xuXG52YXIgX3NlY3VyZVJhbmRvbTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zZWN1cmVSYW5kb20pO1xuXG52YXIgX3BlZXJwbGF5c2pzV3MgPSByZXF1aXJlKCdwZWVycGxheXNqcy13cycpO1xuXG52YXIgX1ByaXZhdGVLZXkgPSByZXF1aXJlKCcuL1ByaXZhdGVLZXknKTtcblxudmFyIF9Qcml2YXRlS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1ByaXZhdGVLZXkpO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoJy4vUHVibGljS2V5Jyk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbnZhciBfYWRkcmVzcyA9IHJlcXVpcmUoJy4vYWRkcmVzcycpO1xuXG52YXIgX2FkZHJlc3MyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWRkcmVzcyk7XG5cbnZhciBfYWVzID0gcmVxdWlyZSgnLi9hZXMnKTtcblxudmFyIF9hZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWVzKTtcblxudmFyIF9oYXNoID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8vIGltcG9ydCBkaWN0aW9uYXJ5IGZyb20gJy4vZGljdGlvbmFyeV9lbic7XG5cbi8vIGhhc2ggZm9yIC4yNSBzZWNvbmRcbnZhciBIQVNIX1BPV0VSX01JTExTID0gMjUwO1xuXG52YXIga2V5ID0ge1xuICAvKiogVXNlcyAxIHNlY29uZCBvZiBoYXNoaW5nIHBvd2VyIHRvIGNyZWF0ZSBhIGtleS9wYXNzd29yZCBjaGVja3N1bS4gIEFuXG4gICAgaW1wbGVtZW50YXRpb24gY2FuIHJlLWNhbGwgdGhpcyBtZXRob2Qgd2l0aCB0aGUgc2FtZSBwYXNzd29yZCB0byByZS1tYXRjaFxuICAgIHRoZSBzdHJlbmd0aCBvZiB0aGUgQ1BVIChlaXRoZXIgYWZ0ZXIgbW92aW5nIGZyb20gYSBkZXNrdG9wIHRvIGEgbW9iaWxlLFxuICAgIG1vYmlsZSB0byBkZXNrdG9wLCBvciBOIHllYXJzIGZyb20gbm93IHdoZW4gQ1BVcyBhcmUgcHJlc3VtYWJseSBzdHJvbmdlcikuXG4gICAgIEEgc2FsdCBpcyB1c2VkIGZvciBhbGwgdGhlIG5vcm1hbCByZWFzb25zLi4uXG4gICAgIEByZXR1cm4gb2JqZWN0IHtcbiAgICAgICAgYWVzX3ByaXZhdGU6IEFlcyxcbiAgICAgICAgY2hlY2tzdW06IFwie2hhc2hfaXRlcmF0aW9uX2NvdW50fSx7c2FsdH0se2NoZWNrc3VtfVwiXG4gICAgfVxuICAgICovXG4gIGFlc19jaGVja3N1bTogZnVuY3Rpb24gYWVzX2NoZWNrc3VtKHBhc3N3b3JkKSB7XG4gICAgaWYgKCEodHlwZW9mIHBhc3N3b3JkID09PSAnc3RyaW5nJykpIHtcbiAgICAgIHRocm93IG5ldyAncGFzc3dvcmQgc3RyaW5nIHJlcXVpcmVkJygpO1xuICAgIH1cblxuICAgIHZhciBzYWx0ID0gX3NlY3VyZVJhbmRvbTIuZGVmYXVsdC5yYW5kb21CdWZmZXIoNCkudG9TdHJpbmcoJ2hleCcpO1xuICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICB2YXIgc2VjcmV0ID0gc2FsdCArIHBhc3N3b3JkO1xuICAgIC8vIGhhc2ggZm9yIC4xIHNlY29uZFxuICAgIHZhciBzdGFydF90ID0gRGF0ZS5ub3coKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIC0gc3RhcnRfdCA8IEhBU0hfUE9XRVJfTUlMTFMpIHtcbiAgICAgIHNlY3JldCA9ICgwLCBfaGFzaC5zaGEyNTYpKHNlY3JldCk7XG4gICAgICBpdGVyYXRpb25zICs9IDE7XG4gICAgfVxuXG4gICAgdmFyIGNoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1Nikoc2VjcmV0KTtcbiAgICB2YXIgY2hlY2tzdW1fc3RyaW5nID0gW2l0ZXJhdGlvbnMsIHNhbHQudG9TdHJpbmcoJ2hleCcpLCBjaGVja3N1bS5zbGljZSgwLCA0KS50b1N0cmluZygnaGV4JyldLmpvaW4oJywnKTtcblxuICAgIHJldHVybiB7XG4gICAgICBhZXNfcHJpdmF0ZTogX2FlczIuZGVmYXVsdC5mcm9tU2VlZChzZWNyZXQpLFxuICAgICAgY2hlY2tzdW06IGNoZWNrc3VtX3N0cmluZ1xuICAgIH07XG4gIH0sXG5cblxuICAvKiogUHJvdmlkZSBhIG1hdGNoaW5nIHBhc3N3b3JkIGFuZCBrZXlfY2hlY2tzdW0uICBBIFwid3JvbmcgcGFzc3dvcmRcIlxuICAgIGVycm9yIGlzIHRocm93biBpZiB0aGUgcGFzc3dvcmQgZG9lcyBub3QgbWF0Y2guICBJZiB0aGlzIG1ldGhvZCB0YWtlc1xuICAgIG11Y2ggbW9yZSBvciBsZXNzIHRoYW4gMSBzZWNvbmQgdG8gcmV0dXJuLCBvbmUgc2hvdWxkIGNvbnNpZGVyIHVwZGF0aW5nXG4gICAgYWxsIGVuY3lycHRlZCBmaWVsZHMgdXNpbmcgYSBuZXcga2V5LmtleV9jaGVja3N1bS5cbiAgICAqL1xuICBhZXNfcHJpdmF0ZTogZnVuY3Rpb24gYWVzX3ByaXZhdGUocGFzc3dvcmQsIGtleV9jaGVja3N1bSkge1xuICAgIHZhciBfa2V5X2NoZWNrc3VtJHNwbGl0ID0ga2V5X2NoZWNrc3VtLnNwbGl0KCcsJyksXG4gICAgICAgIGl0ZXJhdGlvbnMgPSBfa2V5X2NoZWNrc3VtJHNwbGl0WzBdLFxuICAgICAgICBzYWx0ID0gX2tleV9jaGVja3N1bSRzcGxpdFsxXSxcbiAgICAgICAgY2hlY2tzdW0gPSBfa2V5X2NoZWNrc3VtJHNwbGl0WzJdO1xuXG4gICAgdmFyIHNlY3JldCA9IHNhbHQgKyBwYXNzd29yZDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpdGVyYXRpb25zID4gMCA/IGkgPCBpdGVyYXRpb25zIDogaSA+IGl0ZXJhdGlvbnM7IGl0ZXJhdGlvbnMgPiAwID8gaSsrIDogaSsrKSB7XG4gICAgICBzZWNyZXQgPSAoMCwgX2hhc2guc2hhMjU2KShzZWNyZXQpO1xuICAgIH1cblxuICAgIHZhciBuZXdfY2hlY2tzdW0gPSAoMCwgX2hhc2guc2hhMjU2KShzZWNyZXQpO1xuXG4gICAgaWYgKCEobmV3X2NoZWNrc3VtLnNsaWNlKDAsIDQpLnRvU3RyaW5nKCdoZXgnKSA9PT0gY2hlY2tzdW0pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHBhc3N3b3JkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9hZXMyLmRlZmF1bHQuZnJvbVNlZWQoc2VjcmV0KTtcbiAgfSxcblxuXG4gIC8qKlxuICAgICAgICBBIHdlZWsgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgY2FuIHJ1biBvdXQgb2YgZW50cm9weS5cbiAgICAgICAgVGhpcyBzaG91bGQgZW5zdXJlIGV2ZW4gdGhlIHdvcnN0IHJhbmRvbSBudW1iZXIgaW1wbGVtZW50YXRpb24gd2lsbCBiZSByZWFzb25hYmx5IHNhZmUuXG4gICAgICAgICBAcGFyYW0xIHN0cmluZyBlbnRyb3B5IG9mIGF0IGxlYXN0IDMyIGJ5dGVzXG4gICAgKi9cbiAgcmFuZG9tMzJCeXRlQnVmZmVyOiBmdW5jdGlvbiByYW5kb20zMkJ5dGVCdWZmZXIoKSB7XG4gICAgdmFyIGVudHJvcHkgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRoaXMuYnJvd3NlckVudHJvcHkoKTtcblxuICAgIGlmICghKHR5cGVvZiBlbnRyb3B5ID09PSAnc3RyaW5nJykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc3RyaW5nIHJlcXVpcmVkIGZvciBlbnRyb3B5Jyk7XG4gICAgfVxuXG4gICAgaWYgKGVudHJvcHkubGVuZ3RoIDwgMzIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0aW5nIGF0IGxlYXN0IDMyIGJ5dGVzIG9mIGVudHJvcHknKTtcbiAgICB9XG5cbiAgICB2YXIgc3RhcnRfdCA9IERhdGUubm93KCk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0X3QgPCBIQVNIX1BPV0VSX01JTExTKSB7XG4gICAgICBlbnRyb3B5ID0gKDAsIF9oYXNoLnNoYTI1NikoZW50cm9weSk7XG4gICAgfVxuXG4gICAgdmFyIGhhc2hfYXJyYXkgPSBbXTtcbiAgICBoYXNoX2FycmF5LnB1c2goZW50cm9weSk7XG5cbiAgICAvLyBIYXNoaW5nIGZvciAxIHNlY29uZCBtYXkgaGVscHMgdGhlIGNvbXB1dGVyIGlzIG5vdCBsb3cgb24gZW50cm9weVxuICAgIC8vICh0aGlzIG1ldGhvZCBtYXkgYmUgY2FsbGVkIGJhY2stdG8tYmFjaykuXG4gICAgaGFzaF9hcnJheS5wdXNoKF9zZWN1cmVSYW5kb20yLmRlZmF1bHQucmFuZG9tQnVmZmVyKDMyKSk7XG5cbiAgICByZXR1cm4gKDAsIF9oYXNoLnNoYTI1NikoQnVmZmVyLmNvbmNhdChoYXNoX2FycmF5KSk7XG4gIH0sXG4gIHN1Z2dlc3RfYnJhaW5fa2V5OiBmdW5jdGlvbiBzdWdnZXN0X2JyYWluX2tleSgpIHtcbiAgICB2YXIgZGljdGlvbmFyeSA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJywnO1xuICAgIHZhciBlbnRyb3B5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB0aGlzLmJyb3dzZXJFbnRyb3B5KCk7XG5cbiAgICB2YXIgcmFuZG9tQnVmZmVyID0gdGhpcy5yYW5kb20zMkJ5dGVCdWZmZXIoZW50cm9weSk7XG5cbiAgICB2YXIgd29yZF9jb3VudCA9IDE2O1xuICAgIHZhciBkaWN0aW9uYXJ5X2xpbmVzID0gZGljdGlvbmFyeS5zcGxpdCgnLCcpO1xuXG4gICAgaWYgKCEoZGljdGlvbmFyeV9saW5lcy5sZW5ndGggPT09IDQ5NzQ0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdleHBlY3RpbmcgJyArIDQ5NzQ0ICsgJyBidXQgZ290ICcgKyBkaWN0aW9uYXJ5X2xpbmVzLmxlbmd0aCArICcgZGljdGlvbmFyeSB3b3JkcycpO1xuICAgIH1cblxuICAgIHZhciBicmFpbmtleSA9IFtdO1xuICAgIHZhciBlbmQgPSB3b3JkX2NvdW50ICogMjtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5kOyBpICs9IDIpIHtcbiAgICAgIC8vIHJhbmRvbUJ1ZmZlciBoYXMgMjU2IGJpdHMgLyAxNiBiaXRzIHBlciB3b3JkID09IDE2IHdvcmRzXG4gICAgICB2YXIgbnVtID0gKHJhbmRvbUJ1ZmZlcltpXSA8PCA4KSArIHJhbmRvbUJ1ZmZlcltpICsgMV07IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgICAgLy8gY29udmVydCBpbnRvIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMSAoaW5jbHVzaXZlKVxuICAgICAgdmFyIHJuZE11bHRpcGxpZXIgPSBudW0gLyBNYXRoLnBvdygyLCAxNik7XG4gICAgICB2YXIgd29yZEluZGV4ID0gTWF0aC5yb3VuZChkaWN0aW9uYXJ5X2xpbmVzLmxlbmd0aCAqIHJuZE11bHRpcGxpZXIpO1xuXG4gICAgICBicmFpbmtleS5wdXNoKGRpY3Rpb25hcnlfbGluZXNbd29yZEluZGV4XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubm9ybWFsaXplX2JyYWluS2V5KGJyYWlua2V5LmpvaW4oJyAnKSk7XG4gIH0sXG4gIGdldF9yYW5kb21fa2V5OiBmdW5jdGlvbiBnZXRfcmFuZG9tX2tleShlbnRyb3B5KSB7XG4gICAgcmV0dXJuIF9Qcml2YXRlS2V5Mi5kZWZhdWx0LmZyb21CdWZmZXIodGhpcy5yYW5kb20zMkJ5dGVCdWZmZXIoZW50cm9weSkpO1xuICB9LFxuICBnZXRfYnJhaW5Qcml2YXRlS2V5OiBmdW5jdGlvbiBnZXRfYnJhaW5Qcml2YXRlS2V5KGJyYWluS2V5KSB7XG4gICAgdmFyIHNlcXVlbmNlID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAwO1xuXG4gICAgaWYgKHNlcXVlbmNlIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNlcXVlbmNlJyk7XG4gICAgfVxuXG4gICAgYnJhaW5LZXkgPSBrZXkubm9ybWFsaXplX2JyYWluS2V5KGJyYWluS2V5KTtcbiAgICByZXR1cm4gX1ByaXZhdGVLZXkyLmRlZmF1bHQuZnJvbUJ1ZmZlcigoMCwgX2hhc2guc2hhMjU2KSgoMCwgX2hhc2guc2hhNTEyKShicmFpbktleSArICcgJyArIHNlcXVlbmNlKSkpO1xuICB9LFxuXG5cbiAgLy8gVHVybiBpbnZpc2libGUgc3BhY2UgbGlrZSBjaGFyYWN0ZXJzIGludG8gYSBzaW5nbGUgc3BhY2VcbiAgbm9ybWFsaXplX2JyYWluS2V5OiBmdW5jdGlvbiBub3JtYWxpemVfYnJhaW5LZXkoYnJhaW5LZXkpIHtcbiAgICBpZiAoISh0eXBlb2YgYnJhaW5LZXkgPT09ICdzdHJpbmcnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpbmcgcmVxdWlyZWQgZm9yIGJyYWluS2V5Jyk7XG4gICAgfVxuXG4gICAgYnJhaW5LZXkgPSBicmFpbktleS50cmltKCk7XG4gICAgcmV0dXJuIGJyYWluS2V5LnNwbGl0KC9bXFx0XFxuXFx2XFxmXFxyIF0rLykuam9pbignICcpO1xuICB9LFxuICBicm93c2VyRW50cm9weTogZnVuY3Rpb24gYnJvd3NlckVudHJvcHkoKSB7XG4gICAgdmFyIGVudHJvcHlTdHIgPSAnJztcblxuICAgIHRyeSB7XG4gICAgICBlbnRyb3B5U3RyID0gbmV3IERhdGUoKS50b1N0cmluZygpICsgJyAnICsgd2luZG93LnNjcmVlbi5oZWlnaHQgKyAnICcgKyB3aW5kb3cuc2NyZWVuLndpZHRoO1xuICAgICAgZW50cm9weVN0ciA9IGVudHJvcHlTdHIgKyAnICcgKyB3aW5kb3cuc2NyZWVuLmNvbG9yRGVwdGggKyAnICcgKyB3aW5kb3cuc2NyZWVuLmF2YWlsSGVpZ2h0O1xuICAgICAgZW50cm9weVN0ciA9IGVudHJvcHlTdHIgKyAnICcgKyB3aW5kb3cuc2NyZWVuLmF2YWlsV2lkdGggKyAnICcgKyB3aW5kb3cuc2NyZWVuLnBpeGVsRGVwdGg7XG4gICAgICBlbnRyb3B5U3RyID0gZW50cm9weVN0ciArICcgJyArIG5hdmlnYXRvci5sYW5ndWFnZSArICcgJyArIHdpbmRvdy5sb2NhdGlvbjtcbiAgICAgIGVudHJvcHlTdHIgPSBlbnRyb3B5U3RyICsgJyAnICsgd2luZG93Lmhpc3RvcnkubGVuZ3RoO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbmF2aWdhdG9yLm1pbWVUeXBlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgbWltZVR5cGUgPSBuYXZpZ2F0b3IubWltZVR5cGVzW2ldO1xuICAgICAgICBlbnRyb3B5U3RyICs9IG1pbWVUeXBlLmRlc2NyaXB0aW9uICsgJyAnICsgbWltZVR5cGUudHlwZSArICcgJyArIG1pbWVUeXBlLnN1ZmZpeGVzICsgJyAnO1xuICAgICAgfVxuXG4gICAgICBjb25zb2xlLmxvZygnSU5GT1xcdGJyb3dzZXJFbnRyb3B5IGdhdGhlcmVkJyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIG5vZGVqczpSZWZlcmVuY2VFcnJvcjogd2luZG93IGlzIG5vdCBkZWZpbmVkXG4gICAgICBlbnRyb3B5U3RyID0gKDAsIF9oYXNoLnNoYTI1NikobmV3IERhdGUoKS50b1N0cmluZygpKTtcbiAgICB9XG5cbiAgICB2YXIgYiA9IEJ1ZmZlci5mcm9tKGVudHJvcHlTdHIpO1xuICAgIGVudHJvcHlTdHIgKz0gYi50b1N0cmluZygnYmluYXJ5JykgKyAnICcgKyBuZXcgRGF0ZSgpLnRvU3RyaW5nKCk7XG4gICAgcmV0dXJuIGVudHJvcHlTdHI7XG4gIH0sXG5cblxuICAvLyBAcmV0dXJuIGFycmF5IG9mIDUgbGVnYWN5IGFkZHJlc3NlcyBmb3IgYSBwdWJrZXkgc3RyaW5nIHBhcmFtZXRlci5cbiAgYWRkcmVzc2VzOiBmdW5jdGlvbiBhZGRyZXNzZXMocHVia2V5KSB7XG4gICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgIHZhciBwdWJsaWNfa2V5ID0gX1B1YmxpY0tleTIuZGVmYXVsdC5mcm9tUHVibGljS2V5U3RyaW5nKHB1YmtleSwgYWRkcmVzc19wcmVmaXgpO1xuICAgIC8vIFMgTCBPIFdcbiAgICB2YXIgYWRkcmVzc19zdHJpbmcgPSBbX2FkZHJlc3MyLmRlZmF1bHQuZnJvbVB1YmxpYyhwdWJsaWNfa2V5LCBmYWxzZSwgMCkudG9TdHJpbmcoYWRkcmVzc19wcmVmaXgpLCAvLyBidGNfdW5jb21wcmVzc2VkXG4gICAgX2FkZHJlc3MyLmRlZmF1bHQuZnJvbVB1YmxpYyhwdWJsaWNfa2V5LCB0cnVlLCAwKS50b1N0cmluZyhhZGRyZXNzX3ByZWZpeCksIC8vIGJ0Y19jb21wcmVzc2VkXG4gICAgX2FkZHJlc3MyLmRlZmF1bHQuZnJvbVB1YmxpYyhwdWJsaWNfa2V5LCBmYWxzZSwgNTYpLnRvU3RyaW5nKGFkZHJlc3NfcHJlZml4KSwgLy8gcHRzX3VuY29tcHJlc3NlZFxuICAgIF9hZGRyZXNzMi5kZWZhdWx0LmZyb21QdWJsaWMocHVibGljX2tleSwgdHJ1ZSwgNTYpLnRvU3RyaW5nKGFkZHJlc3NfcHJlZml4KSwgLy8gcHRzX2NvbXByZXNzZWRcbiAgICBwdWJsaWNfa2V5LnRvQWRkcmVzc1N0cmluZyhhZGRyZXNzX3ByZWZpeCkgLy8gYnRzX3Nob3J0LCBtb3N0IHJlY2VudCBmb3JtYXRcbiAgICBdO1xuICAgIHJldHVybiBhZGRyZXNzX3N0cmluZztcbiAgfVxufTtcblxuZXhwb3J0cy5kZWZhdWx0ID0ga2V5O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2VjdXJ2ZSA9IHJlcXVpcmUoJ2VjdXJ2ZScpO1xuXG52YXIgX2JpZ2kgPSByZXF1aXJlKCdiaWdpJyk7XG5cbnZhciBfYmlnaTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9iaWdpKTtcblxudmFyIF9icyA9IHJlcXVpcmUoJ2JzNTgnKTtcblxudmFyIF9kZWVwRXF1YWwgPSByZXF1aXJlKCdkZWVwLWVxdWFsJyk7XG5cbnZhciBfZGVlcEVxdWFsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2RlZXBFcXVhbCk7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfaGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoJy4vUHVibGljS2V5Jyk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9IC8qIGdsb2JhbCBCeXRlQnVmZmVyICovXG5cblxudmFyIHNlY3AyNTZrMSA9ICgwLCBfZWN1cnZlLmdldEN1cnZlQnlOYW1lKSgnc2VjcDI1NmsxJyk7XG52YXIgbiA9IHNlY3AyNTZrMS5uO1xuXG5cbmZ1bmN0aW9uIHRvUHVibGljKGRhdGEpIHtcbiAgaWYgKCFkYXRhIHx8IGRhdGEuUSkge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgcmV0dXJuIF9QdWJsaWNLZXkyLmRlZmF1bHQuZnJvbVN0cmluZ09yVGhyb3coZGF0YSk7XG59XG5cbnZhciBQcml2YXRlS2V5ID0gZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICAgICAgQHByaXZhdGUgc2VlIHN0YXRpYyBmdW5jdGlvbnNcbiAgICAgICAgQHBhcmFtIHtCaWdJbnRlZ2VyfVxuICAgICovXG4gIGZ1bmN0aW9uIFByaXZhdGVLZXkoZCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQcml2YXRlS2V5KTtcblxuICAgIHRoaXMuZCA9IGQ7XG4gIH1cblxuICBQcml2YXRlS2V5LmZyb21CdWZmZXIgPSBmdW5jdGlvbiBmcm9tQnVmZmVyKGJ1Zikge1xuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0aW5nIHBhcmFtdGVyIHRvIGJlIGEgQnVmZmVyIHR5cGUnKTtcbiAgICB9XG5cbiAgICBpZiAoYnVmLmxlbmd0aCAhPT0gMzIpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdXQVJOOiBFeHBlY3RpbmcgMzIgYnl0ZXMsIGluc3RlYWQgZ290ICcgKyBidWYubGVuZ3RoICsgJywgc3RhY2sgdHJhY2U6JywgbmV3IEVycm9yKCkuc3RhY2spO1xuICAgIH1cblxuICAgIGlmIChidWYubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VtcHR5IGJ1ZmZlcicpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJpdmF0ZUtleShfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1ZikpO1xuICB9O1xuXG4gIC8qKiBAYXJnIHtzdHJpbmd9IHNlZWQgLSBhbnkgbGVuZ3RoIHN0cmluZy4gIFRoaXMgaXMgcHJpdmF0ZSxcbiAgICogdGhlIHNhbWUgc2VlZCBwcm9kdWNlcyB0aGUgc2FtZSBwcml2YXRlIGtleSBldmVyeSB0aW1lLiAgKi9cblxuXG4gIFByaXZhdGVLZXkuZnJvbVNlZWQgPSBmdW5jdGlvbiBmcm9tU2VlZChzZWVkKSB7XG4gICAgLy8gZ2VuZXJhdGVfcHJpdmF0ZV9rZXlcbiAgICBpZiAoISh0eXBlb2Ygc2VlZCA9PT0gJ3N0cmluZycpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NlZWQgbXVzdCBiZSBvZiB0eXBlIHN0cmluZycpO1xuICAgIH1cblxuICAgIHJldHVybiBQcml2YXRlS2V5LmZyb21CdWZmZXIoKDAsIF9oYXNoLnNoYTI1Nikoc2VlZCkpO1xuICB9O1xuXG4gIC8qKiBAcmV0dXJuIHtzdHJpbmd9IFdhbGxldCBJbXBvcnQgRm9ybWF0IChzdGlsbCBhIHNlY3JldCwgTm90IGVuY3J5cHRlZCkgKi9cblxuXG4gIFByaXZhdGVLZXkuZnJvbVdpZiA9IGZ1bmN0aW9uIGZyb21XaWYoX3ByaXZhdGVfd2lmKSB7XG4gICAgdmFyIHByaXZhdGVfd2lmID0gQnVmZmVyLmZyb20oKDAsIF9icy5kZWNvZGUpKF9wcml2YXRlX3dpZikpO1xuICAgIHZhciB2ZXJzaW9uID0gcHJpdmF0ZV93aWYucmVhZFVJbnQ4KDApO1xuICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoMHg4MCwgdmVyc2lvbiwgJ0V4cGVjdGVkIHZlcnNpb24gJyArIDB4ODAgKyAnLCBpbnN0ZWFkIGdvdCAnICsgdmVyc2lvbik7XG4gICAgLy8gY2hlY2tzdW0gaW5jbHVkZXMgdGhlIHZlcnNpb25cbiAgICB2YXIgcHJpdmF0ZV9rZXkgPSBwcml2YXRlX3dpZi5zbGljZSgwLCAtNCk7XG4gICAgdmFyIGNoZWNrc3VtID0gcHJpdmF0ZV93aWYuc2xpY2UoLTQpO1xuICAgIHZhciBuZXdfY2hlY2tzdW0gPSAoMCwgX2hhc2guc2hhMjU2KShwcml2YXRlX2tleSk7XG4gICAgbmV3X2NoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1NikobmV3X2NoZWNrc3VtKTtcbiAgICBuZXdfY2hlY2tzdW0gPSBuZXdfY2hlY2tzdW0uc2xpY2UoMCwgNCk7XG4gICAgdmFyIGlzRXF1YWwgPSAoMCwgX2RlZXBFcXVhbDIuZGVmYXVsdCkoY2hlY2tzdW0sIG5ld19jaGVja3N1bSk7IC8vICwgJ0ludmFsaWQgY2hlY2tzdW0nXG5cbiAgICBpZiAoIWlzRXF1YWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2hlY2tzdW0gZGlkIG5vdCBtYXRjaCcpO1xuICAgIH1cblxuICAgIHByaXZhdGVfa2V5ID0gcHJpdmF0ZV9rZXkuc2xpY2UoMSk7XG4gICAgcHJpdmF0ZV9rZXkgPSBwcml2YXRlX2tleS5zbGljZSgwLCAzMik7XG4gICAgcmV0dXJuIFByaXZhdGVLZXkuZnJvbUJ1ZmZlcihwcml2YXRlX2tleSk7XG4gIH07XG5cbiAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9XaWYgPSBmdW5jdGlvbiB0b1dpZigpIHtcbiAgICB2YXIgcHJpdmF0ZV9rZXkgPSB0aGlzLnRvQnVmZmVyKCk7XG4gICAgLy8gY2hlY2tzdW0gaW5jbHVkZXMgdGhlIHZlcnNpb25cbiAgICBwcml2YXRlX2tleSA9IEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKFsweDgwXSksIHByaXZhdGVfa2V5XSk7XG4gICAgdmFyIGNoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1NikocHJpdmF0ZV9rZXkpO1xuICAgIGNoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1NikoY2hlY2tzdW0pO1xuICAgIGNoZWNrc3VtID0gY2hlY2tzdW0uc2xpY2UoMCwgNCk7XG4gICAgdmFyIHByaXZhdGVfd2lmID0gQnVmZmVyLmNvbmNhdChbcHJpdmF0ZV9rZXksIGNoZWNrc3VtXSk7XG4gICAgcmV0dXJuICgwLCBfYnMuZW5jb2RlKShwcml2YXRlX3dpZik7XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEByZXR1cm4ge1BvaW50fVxuICAgICovXG5cblxuICBQcml2YXRlS2V5LnByb3RvdHlwZS50b1B1YmxpY0tleVBvaW50ID0gZnVuY3Rpb24gdG9QdWJsaWNLZXlQb2ludCgpIHtcbiAgICB2YXIgUSA9IHNlY3AyNTZrMS5HLm11bHRpcGx5KHRoaXMuZCk7XG4gICAgcmV0dXJuIFE7XG4gIH07XG5cbiAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9QdWJsaWNLZXkgPSBmdW5jdGlvbiB0b1B1YmxpY0tleSgpIHtcbiAgICBpZiAodGhpcy5wdWJsaWNfa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5wdWJsaWNfa2V5O1xuICAgIH1cblxuICAgIHRoaXMucHVibGljX2tleSA9IF9QdWJsaWNLZXkyLmRlZmF1bHQuZnJvbVBvaW50KHRoaXMudG9QdWJsaWNLZXlQb2ludCgpKTtcblxuICAgIHJldHVybiB0aGlzLnB1YmxpY19rZXk7XG4gIH07XG5cbiAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiB0b0J1ZmZlcigpIHtcbiAgICByZXR1cm4gdGhpcy5kLnRvQnVmZmVyKDMyKTtcbiAgfTtcblxuICAvKiogRUNJRVMgKi9cblxuXG4gIFByaXZhdGVLZXkucHJvdG90eXBlLmdldF9zaGFyZWRfc2VjcmV0ID0gZnVuY3Rpb24gZ2V0X3NoYXJlZF9zZWNyZXQocHVibGljX2tleSkge1xuICAgIHZhciBsZWdhY3kgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZhbHNlO1xuXG4gICAgcHVibGljX2tleSA9IHRvUHVibGljKHB1YmxpY19rZXkpO1xuICAgIHZhciBLQiA9IHB1YmxpY19rZXkudG9VbmNvbXByZXNzZWQoKS50b0J1ZmZlcigpO1xuICAgIHZhciBLQlAgPSBfZWN1cnZlLlBvaW50LmZyb21BZmZpbmUoc2VjcDI1NmsxLCBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKEtCLnNsaWNlKDEsIDMzKSksIC8vIHhcbiAgICBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKEtCLnNsaWNlKDMzLCA2NSkpIC8vIHlcbiAgICApO1xuICAgIHZhciByID0gdGhpcy50b0J1ZmZlcigpO1xuICAgIHZhciBQID0gS0JQLm11bHRpcGx5KF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIocikpO1xuICAgIHZhciBTID0gUC5hZmZpbmVYLnRvQnVmZmVyKHsgc2l6ZTogMzIgfSk7XG5cbiAgICAvKlxuICAgICAgICB0aGUgaW5wdXQgdG8gc2hhNTEyIG11c3QgYmUgZXhhY3RseSAzMi1ieXRlcywgdG8gbWF0Y2ggdGhlIGMrKyBpbXBsZW1lbnRhdGlvblxuICAgICAgICBvZiBnZXRfc2hhcmVkX3NlY3JldC4gIFJpZ2h0IG5vdyBTIHdpbGwgYmUgc2hvcnRlciBpZiB0aGUgbW9zdCBzaWduaWZpY2FudFxuICAgICAgICBieXRlKHMpIGlzIHplcm8uICBQYWQgaXQgYmFjayB0byB0aGUgZnVsbCAzMi1ieXRlc1xuICAgICAgICAqL1xuICAgIGlmICghbGVnYWN5ICYmIFMubGVuZ3RoIDwgMzIpIHtcbiAgICAgIHZhciBwYWQgPSBCdWZmZXIuYWxsb2MoMzIgLSBTLmxlbmd0aCwgMCk7XG4gICAgICBTID0gQnVmZmVyLmNvbmNhdChbcGFkLCBTXSk7XG4gICAgfVxuXG4gICAgLy8gU0hBNTEyIHVzZWQgaW4gRUNJRVNcbiAgICByZXR1cm4gKDAsIF9oYXNoLnNoYTUxMikoUyk7XG4gIH07XG5cbiAgLy8gLyoqIEVDSUVTIChkb2VzIG5vdCBhbHdheXMgbWF0Y2ggdGhlIFBvaW50LmZyb21BZmZpbmUgdmVyc2lvbiBhYm92ZSkgKi9cbiAgLy8gZ2V0X3NoYXJlZF9zZWNyZXQocHVibGljX2tleSl7XG4gIC8vICAgICBwdWJsaWNfa2V5ID0gdG9QdWJsaWMocHVibGljX2tleSlcbiAgLy8gICAgIHZhciBQID0gcHVibGljX2tleS5RLm11bHRpcGx5KCB0aGlzLmQgKTtcbiAgLy8gICAgIHZhciBTID0gUC5hZmZpbmVYLnRvQnVmZmVyKHtzaXplOiAzMn0pO1xuICAvLyAgICAgLy8gRUNJRVMsIGFkZHMgYW4gZXh0cmEgc2hhNTEyXG4gIC8vICAgICByZXR1cm4gc2hhNTEyKFMpO1xuICAvLyB9XG5cbiAgLyoqIEB0aHJvd3Mge0Vycm9yfSAtIG92ZXJmbG93IG9mIHRoZSBrZXkgY291bGQgbm90IGJlIGRlcml2ZWQgKi9cblxuXG4gIFByaXZhdGVLZXkucHJvdG90eXBlLmNoaWxkID0gZnVuY3Rpb24gY2hpbGQob2Zmc2V0KSB7XG4gICAgb2Zmc2V0ID0gQnVmZmVyLmNvbmNhdChbdGhpcy50b1B1YmxpY0tleSgpLnRvQnVmZmVyKCksIG9mZnNldF0pO1xuICAgIG9mZnNldCA9ICgwLCBfaGFzaC5zaGEyNTYpKG9mZnNldCk7XG4gICAgdmFyIGMgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKG9mZnNldCk7XG5cbiAgICBpZiAoYy5jb21wYXJlVG8obikgPj0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCBvZmZzZXQgd2VudCBvdXQgb2YgYm91bmRzLCB0cnkgYWdhaW4nKTtcbiAgICB9XG5cbiAgICB2YXIgZGVyaXZlZCA9IHRoaXMuZC5hZGQoYyk7IC8vIC5tb2QobilcblxuICAgIGlmIChkZXJpdmVkLnNpZ251bSgpID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NoaWxkIG9mZnNldCBkZXJpdmVkIHRvIGFuIGludmFsaWQga2V5LCB0cnkgYWdhaW4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByaXZhdGVLZXkoZGVyaXZlZCk7XG4gIH07XG5cbiAgLyogPGhlbHBlcl9mdW5jdGlvbnM+ICovXG5cbiAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9CeXRlQnVmZmVyID0gZnVuY3Rpb24gdG9CeXRlQnVmZmVyKCkge1xuICAgIHZhciBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiKTtcbiAgICByZXR1cm4gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgfTtcblxuICBQcml2YXRlS2V5LmZyb21IZXggPSBmdW5jdGlvbiBmcm9tSGV4KGhleCkge1xuICAgIHJldHVybiBQcml2YXRlS2V5LmZyb21CdWZmZXIoQnVmZmVyLmZyb20oaGV4LCAnaGV4JykpO1xuICB9O1xuXG4gIFByaXZhdGVLZXkucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24gdG9IZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9CdWZmZXIoKS50b1N0cmluZygnaGV4Jyk7XG4gIH07XG5cbiAgLyogPC9oZWxwZXJfZnVuY3Rpb25zPiAqL1xuXG5cbiAgcmV0dXJuIFByaXZhdGVLZXk7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IFByaXZhdGVLZXk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYmlnaSA9IHJlcXVpcmUoJ2JpZ2knKTtcblxudmFyIF9iaWdpMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2JpZ2kpO1xuXG52YXIgX2VjdXJ2ZSA9IHJlcXVpcmUoJ2VjdXJ2ZScpO1xuXG52YXIgX2JzID0gcmVxdWlyZSgnYnM1OCcpO1xuXG52YXIgX3BlZXJwbGF5c2pzV3MgPSByZXF1aXJlKCdwZWVycGxheXNqcy13cycpO1xuXG52YXIgX2Fzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xuXG52YXIgX2Fzc2VydDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnQpO1xuXG52YXIgX2RlZXBFcXVhbCA9IHJlcXVpcmUoJ2RlZXAtZXF1YWwnKTtcblxudmFyIF9kZWVwRXF1YWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZGVlcEVxdWFsKTtcblxudmFyIF9oYXNoID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9IC8qIGdsb2JhbCBCeXRlQnVmZmVyICovXG5cblxudmFyIHNlY3AyNTZrMSA9ICgwLCBfZWN1cnZlLmdldEN1cnZlQnlOYW1lKSgnc2VjcDI1NmsxJyk7XG5cbnZhciBHID0gc2VjcDI1NmsxLkcsXG4gICAgbiA9IHNlY3AyNTZrMS5uO1xuXG52YXIgUHVibGljS2V5ID0gZnVuY3Rpb24gKCkge1xuICAvKiogQHBhcmFtIHtQb2ludH0gcHVibGljIGtleSAqL1xuICBmdW5jdGlvbiBQdWJsaWNLZXkoUSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQdWJsaWNLZXkpO1xuXG4gICAgdGhpcy5RID0gUTtcbiAgfVxuXG4gIFB1YmxpY0tleS5mcm9tQmluYXJ5ID0gZnVuY3Rpb24gZnJvbUJpbmFyeShiaW4pIHtcbiAgICByZXR1cm4gUHVibGljS2V5LmZyb21CdWZmZXIoQnVmZmVyLmZyb20oYmluLCAnYmluYXJ5JykpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICBpZiAoYnVmZmVyLnRvU3RyaW5nKCdoZXgnKSA9PT0gJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcpIHtcbiAgICAgIHJldHVybiBuZXcgUHVibGljS2V5KG51bGwpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHVibGljS2V5KF9lY3VydmUuUG9pbnQuZGVjb2RlRnJvbShzZWNwMjU2azEsIGJ1ZmZlcikpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiB0b0J1ZmZlcigpIHtcbiAgICB2YXIgY29tcHJlc3NlZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogdGhpcy5RID8gdGhpcy5RLmNvbXByZXNzZWQgOiBudWxsO1xuXG4gICAgaWYgKHRoaXMuUSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKCcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLCAnaGV4Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuUS5nZXRFbmNvZGVkKGNvbXByZXNzZWQpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5mcm9tUG9pbnQgPSBmdW5jdGlvbiBmcm9tUG9pbnQocG9pbnQpIHtcbiAgICByZXR1cm4gbmV3IFB1YmxpY0tleShwb2ludCk7XG4gIH07XG5cbiAgUHVibGljS2V5LnByb3RvdHlwZS50b1VuY29tcHJlc3NlZCA9IGZ1bmN0aW9uIHRvVW5jb21wcmVzc2VkKCkge1xuICAgIHZhciBidWYgPSB0aGlzLlEuZ2V0RW5jb2RlZChmYWxzZSk7XG4gICAgdmFyIHBvaW50ID0gX2VjdXJ2ZS5Qb2ludC5kZWNvZGVGcm9tKHNlY3AyNTZrMSwgYnVmKTtcbiAgICByZXR1cm4gUHVibGljS2V5LmZyb21Qb2ludChwb2ludCk7XG4gIH07XG5cbiAgLyoqIGJ0czo6YmxvY2tjaGFpbjo6YWRkcmVzcyAodW5pcXVlIGJ1dCBub3QgYSBmdWxsIHB1YmxpYyBrZXkpICovXG5cblxuICBQdWJsaWNLZXkucHJvdG90eXBlLnRvQmxvY2tjaGFpbkFkZHJlc3MgPSBmdW5jdGlvbiB0b0Jsb2NrY2hhaW5BZGRyZXNzKCkge1xuICAgIHZhciBwdWJfYnVmID0gdGhpcy50b0J1ZmZlcigpO1xuICAgIHZhciBwdWJfc2hhID0gKDAsIF9oYXNoLnNoYTUxMikocHViX2J1Zik7XG4gICAgcmV0dXJuICgwLCBfaGFzaC5yaXBlbWQxNjApKHB1Yl9zaGEpO1xuICB9O1xuXG4gIC8qKiBBbGlhcyBmb3Ige0BsaW5rIHRvUHVibGljS2V5U3RyaW5nfSAqL1xuXG5cbiAgUHVibGljS2V5LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICByZXR1cm4gdGhpcy50b1B1YmxpY0tleVN0cmluZyhhZGRyZXNzX3ByZWZpeCk7XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEZ1bGwgcHVibGljIGtleVxuICAgICAgICB7cmV0dXJufSBzdHJpbmdcbiAgICAqL1xuXG5cbiAgUHVibGljS2V5LnByb3RvdHlwZS50b1B1YmxpY0tleVN0cmluZyA9IGZ1bmN0aW9uIHRvUHVibGljS2V5U3RyaW5nKCkge1xuICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICB2YXIgcHViX2J1ZiA9IHRoaXMudG9CdWZmZXIoKTtcbiAgICB2YXIgY2hlY2tzdW0gPSAoMCwgX2hhc2gucmlwZW1kMTYwKShwdWJfYnVmKTtcbiAgICAvLyBTbGljZSBmcm9tIHRoZSBidWZmZXIgZGlyZWN0bHksIHNsaWNpbmcgZnJvbSB0aGUgY2hlY2tzdW1cbiAgICAvLyBVaW50OGFycmF5IHdpbGwgcmV0dXJuIHRoZSBlbnRpcmUgYXJyYXkgZWFjaCB0aW1lLlxuICAgIHZhciBzbGljZWQgPSBuZXcgVWludDhBcnJheShjaGVja3N1bS5idWZmZXIuc2xpY2UoMCwgNCkpO1xuXG4gICAgLy8gY29uY2F0IG9ubHkgYWNjZXB0cyBidWZmZXJzIHNvIGluaXRpYWxpemUgdGhlIHNsaWNlZCBVaW50OGFycmF5IGFzIGEgQnVmZmVyLlxuICAgIHZhciBhZGR5ID0gQnVmZmVyLmNvbmNhdChbcHViX2J1ZiwgQnVmZmVyLmZyb20oc2xpY2VkKV0pO1xuICAgIHJldHVybiBhZGRyZXNzX3ByZWZpeCArICgwLCBfYnMuZW5jb2RlKShhZGR5KTtcbiAgfTtcblxuICAvKipcbiAgICAgICAgQGFyZyB7c3RyaW5nfSBwdWJsaWNfa2V5IC0gbGlrZSBHUEhYeXouLi5cbiAgICAgICAgQGFyZyB7c3RyaW5nfSBhZGRyZXNzX3ByZWZpeCAtIGxpa2UgR1BIXG4gICAgICAgIEByZXR1cm4gUHVibGljS2V5IG9yIGBudWxsYCAoaWYgdGhlIHB1YmxpY19rZXkgc3RyaW5nIGlzIGludmFsaWQpXG4gICAgKi9cblxuXG4gIFB1YmxpY0tleS5mcm9tUHVibGljS2V5U3RyaW5nID0gZnVuY3Rpb24gZnJvbVB1YmxpY0tleVN0cmluZyhwdWJsaWNfa2V5KSB7XG4gICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gUHVibGljS2V5LmZyb21TdHJpbmdPclRocm93KHB1YmxpY19rZXksIGFkZHJlc3NfcHJlZml4KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEBhcmcge3N0cmluZ30gcHVibGljX2tleSAtIGxpa2UgR1BIWHl6Li4uXG4gICAgICAgIEBhcmcge3N0cmluZ30gYWRkcmVzc19wcmVmaXggLSBsaWtlIEdQSFxuICAgICAgICBAdGhyb3dzIHtFcnJvcn0gaWYgcHVibGljIGtleSBpcyBpbnZhbGlkXG4gICAgICAgIEByZXR1cm4gUHVibGljS2V5XG4gICAgKi9cblxuXG4gIFB1YmxpY0tleS5mcm9tU3RyaW5nT3JUaHJvdyA9IGZ1bmN0aW9uIGZyb21TdHJpbmdPclRocm93KHB1YmxpY19rZXkpIHtcbiAgICB2YXIgYWRkcmVzc19wcmVmaXggPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IF9wZWVycGxheXNqc1dzLkNoYWluQ29uZmlnLmFkZHJlc3NfcHJlZml4O1xuXG4gICAgdmFyIHByZWZpeCA9IHB1YmxpY19rZXkuc2xpY2UoMCwgYWRkcmVzc19wcmVmaXgubGVuZ3RoKTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGFkZHJlc3NfcHJlZml4LCBwcmVmaXgsICdFeHBlY3Rpbmcga2V5IHRvIGJlZ2luIHdpdGggJyArIGFkZHJlc3NfcHJlZml4ICsgJywgaW5zdGVhZCBnb3QgJyArIHByZWZpeCk7XG4gICAgcHVibGljX2tleSA9IHB1YmxpY19rZXkuc2xpY2UoYWRkcmVzc19wcmVmaXgubGVuZ3RoKTtcblxuICAgIHB1YmxpY19rZXkgPSBCdWZmZXIuZnJvbSgoMCwgX2JzLmRlY29kZSkocHVibGljX2tleSksICdiaW5hcnknKTtcbiAgICB2YXIgY2hlY2tzdW0gPSBwdWJsaWNfa2V5LnNsaWNlKC00KTtcbiAgICBwdWJsaWNfa2V5ID0gcHVibGljX2tleS5zbGljZSgwLCAtNCk7XG4gICAgdmFyIG5ld19jaGVja3N1bSA9ICgwLCBfaGFzaC5yaXBlbWQxNjApKHB1YmxpY19rZXkpO1xuICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS5zbGljZSgwLCA0KTtcbiAgICB2YXIgaXNFcXVhbCA9ICgwLCBfZGVlcEVxdWFsMi5kZWZhdWx0KShjaGVja3N1bSwgbmV3X2NoZWNrc3VtKTsgLy8gLCAnSW52YWxpZCBjaGVja3N1bSdcblxuICAgIGlmICghaXNFcXVhbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGVja3N1bSBkaWQgbm90IG1hdGNoJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tQnVmZmVyKHB1YmxpY19rZXkpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5wcm90b3R5cGUudG9BZGRyZXNzU3RyaW5nID0gZnVuY3Rpb24gdG9BZGRyZXNzU3RyaW5nKCkge1xuICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICB2YXIgcHViX2J1ZiA9IHRoaXMudG9CdWZmZXIoKTtcbiAgICB2YXIgcHViX3NoYSA9ICgwLCBfaGFzaC5zaGE1MTIpKHB1Yl9idWYpO1xuICAgIHZhciBhZGR5ID0gKDAsIF9oYXNoLnJpcGVtZDE2MCkocHViX3NoYSk7XG4gICAgdmFyIGNoZWNrc3VtID0gKDAsIF9oYXNoLnJpcGVtZDE2MCkoYWRkeSk7XG4gICAgYWRkeSA9IEJ1ZmZlci5jb25jYXQoW2FkZHksIGNoZWNrc3VtLnNsaWNlKDAsIDQpXSk7XG4gICAgcmV0dXJuIGFkZHJlc3NfcHJlZml4ICsgKDAsIF9icy5lbmNvZGUpKGFkZHkpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5wcm90b3R5cGUudG9QdHNBZGR5ID0gZnVuY3Rpb24gdG9QdHNBZGR5KCkge1xuICAgIHZhciBwdWJfYnVmID0gdGhpcy50b0J1ZmZlcigpO1xuICAgIHZhciBwdWJfc2hhID0gKDAsIF9oYXNoLnNoYTI1NikocHViX2J1Zik7XG4gICAgdmFyIGFkZHkgPSAoMCwgX2hhc2gucmlwZW1kMTYwKShwdWJfc2hhKTtcbiAgICBhZGR5ID0gQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oWzB4MzhdKSwgYWRkeV0pOyAvLyB2ZXJzaW9uIDU2KGRlY2ltYWwpXG5cbiAgICB2YXIgY2hlY2tzdW0gPSAoMCwgX2hhc2guc2hhMjU2KShhZGR5KTtcbiAgICBjaGVja3N1bSA9ICgwLCBfaGFzaC5zaGEyNTYpKGNoZWNrc3VtKTtcblxuICAgIGFkZHkgPSBCdWZmZXIuY29uY2F0KFthZGR5LCBjaGVja3N1bS5zbGljZSgwLCA0KV0pO1xuICAgIHJldHVybiAoMCwgX2JzLmVuY29kZSkoYWRkeSk7XG4gIH07XG5cbiAgUHVibGljS2V5LnByb3RvdHlwZS5jaGlsZCA9IGZ1bmN0aW9uIGNoaWxkKG9mZnNldCkge1xuICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShCdWZmZXIuaXNCdWZmZXIob2Zmc2V0KSwgJ0J1ZmZlciByZXF1aXJlZDogb2Zmc2V0Jyk7XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChvZmZzZXQubGVuZ3RoLCAzMiwgJ29mZnNldCBsZW5ndGgnKTtcblxuICAgIG9mZnNldCA9IEJ1ZmZlci5jb25jYXQoW3RoaXMudG9CdWZmZXIoKSwgb2Zmc2V0XSk7XG4gICAgb2Zmc2V0ID0gKDAsIF9oYXNoLnNoYTI1Nikob2Zmc2V0KTtcblxuICAgIHZhciBjID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcihvZmZzZXQpO1xuXG4gICAgaWYgKGMuY29tcGFyZVRvKG4pID49IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2hpbGQgb2Zmc2V0IHdlbnQgb3V0IG9mIGJvdW5kcywgdHJ5IGFnYWluJyk7XG4gICAgfVxuXG4gICAgdmFyIGNHID0gRy5tdWx0aXBseShjKTtcbiAgICB2YXIgUXByaW1lID0gdGhpcy5RLmFkZChjRyk7XG5cbiAgICBpZiAoc2VjcDI1NmsxLmlzSW5maW5pdHkoUXByaW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCBvZmZzZXQgZGVyaXZlZCB0byBhbiBpbnZhbGlkIGtleSwgdHJ5IGFnYWluJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tUG9pbnQoUXByaW1lKTtcbiAgfTtcblxuICAvKiA8SEVYPiAqL1xuXG4gIFB1YmxpY0tleS5wcm90b3R5cGUudG9CeXRlQnVmZmVyID0gZnVuY3Rpb24gdG9CeXRlQnVmZmVyKCkge1xuICAgIHZhciBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiKTtcbiAgICByZXR1cm4gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgfTtcblxuICBQdWJsaWNLZXkuZnJvbUhleCA9IGZ1bmN0aW9uIGZyb21IZXgoaGV4KSB7XG4gICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tQnVmZmVyKEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpKTtcbiAgfTtcblxuICBQdWJsaWNLZXkucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24gdG9IZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9CdWZmZXIoKS50b1N0cmluZygnaGV4Jyk7XG4gIH07XG5cbiAgUHVibGljS2V5LmZyb21QdWJsaWNLZXlTdHJpbmdIZXggPSBmdW5jdGlvbiBmcm9tUHVibGljS2V5U3RyaW5nSGV4KGhleCkge1xuICAgIHJldHVybiBQdWJsaWNLZXkuZnJvbVB1YmxpY0tleVN0cmluZyhCdWZmZXIuZnJvbShoZXgsICdoZXgnKSk7XG4gIH07XG5cbiAgLyogPC9IRVg+ICovXG5cblxuICByZXR1cm4gUHVibGljS2V5O1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBQdWJsaWNLZXk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfcGVlcnBsYXlzanNXcyA9IHJlcXVpcmUoJ3BlZXJwbGF5c2pzLXdzJyk7XG5cbnZhciBfYnMgPSByZXF1aXJlKCdiczU4Jyk7XG5cbnZhciBfZGVlcEVxdWFsID0gcmVxdWlyZSgnZGVlcC1lcXVhbCcpO1xuXG52YXIgX2RlZXBFcXVhbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9kZWVwRXF1YWwpO1xuXG52YXIgX2hhc2gyID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbi8qKiBBZGRyZXNzZXMgYXJlIHNob3J0ZW5lZCBub24tcmV2ZXJzYWJsZSBoYXNoZXMgb2YgYSBwdWJsaWMga2V5LiAgVGhlIGZ1bGwgUHVibGljS2V5IGlzIHByZWZlcnJlZC5cbiAgICBAZGVwcmVjYXRlZFxuKi9cbnZhciBBZGRyZXNzID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBBZGRyZXNzKGFkZHkpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWRkcmVzcyk7XG5cbiAgICB0aGlzLmFkZHkgPSBhZGR5O1xuICB9XG5cbiAgQWRkcmVzcy5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICB2YXIgX2hhc2ggPSAoMCwgX2hhc2gyLnNoYTUxMikoYnVmZmVyKTtcbiAgICB2YXIgYWRkeSA9ICgwLCBfaGFzaDIucmlwZW1kMTYwKShfaGFzaCk7XG4gICAgcmV0dXJuIG5ldyBBZGRyZXNzKGFkZHkpO1xuICB9O1xuXG4gIEFkZHJlc3MuZnJvbVN0cmluZyA9IGZ1bmN0aW9uIGZyb21TdHJpbmcoc3RyaW5nKSB7XG4gICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgIHZhciBwcmVmaXggPSBzdHJpbmcuc2xpY2UoMCwgYWRkcmVzc19wcmVmaXgubGVuZ3RoKTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGFkZHJlc3NfcHJlZml4LCBwcmVmaXgsICdFeHBlY3Rpbmcga2V5IHRvIGJlZ2luIHdpdGggJyArIGFkZHJlc3NfcHJlZml4ICsgJywgaW5zdGVhZCBnb3QgJyArIHByZWZpeCk7XG4gICAgdmFyIGFkZHkgPSBzdHJpbmcuc2xpY2UoYWRkcmVzc19wcmVmaXgubGVuZ3RoKTtcbiAgICBhZGR5ID0gQnVmZmVyLmZyb20oKDAsIF9icy5kZWNvZGUpKGFkZHkpLCAnYmluYXJ5Jyk7XG4gICAgdmFyIGNoZWNrc3VtID0gYWRkeS5zbGljZSgtNCk7XG4gICAgYWRkeSA9IGFkZHkuc2xpY2UoMCwgLTQpO1xuICAgIHZhciBuZXdfY2hlY2tzdW0gPSAoMCwgX2hhc2gyLnJpcGVtZDE2MCkoYWRkeSk7XG4gICAgbmV3X2NoZWNrc3VtID0gbmV3X2NoZWNrc3VtLnNsaWNlKDAsIDQpO1xuICAgIHZhciBpc0VxdWFsID0gKDAsIF9kZWVwRXF1YWwyLmRlZmF1bHQpKGNoZWNrc3VtLCBuZXdfY2hlY2tzdW0pOyAvLyAsICdJbnZhbGlkIGNoZWNrc3VtJ1xuXG4gICAgaWYgKCFpc0VxdWFsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NoZWNrc3VtIGRpZCBub3QgbWF0Y2gnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEFkZHJlc3MoYWRkeSk7XG4gIH07XG5cbiAgLyoqIEByZXR1cm4gQWRkcmVzcyAtIENvbXByZXNzZWQgUFRTIGZvcm1hdCAoYnkgZGVmYXVsdCkgKi9cblxuXG4gIEFkZHJlc3MuZnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGZyb21QdWJsaWMocHVibGljX2tleSkge1xuICAgIHZhciBjb21wcmVzc2VkID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB0cnVlO1xuICAgIHZhciB2ZXJzaW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiA1NjtcblxuICAgIHZhciBzaGEyID0gKDAsIF9oYXNoMi5zaGEyNTYpKHB1YmxpY19rZXkudG9CdWZmZXIoY29tcHJlc3NlZCkpO1xuICAgIHZhciByZXAgPSAoMCwgX2hhc2gyLnJpcGVtZDE2MCkoc2hhMik7XG4gICAgdmFyIHZlcnNpb25CdWZmZXIgPSBCdWZmZXIuYWxsb2MoMSk7XG4gICAgdmVyc2lvbkJ1ZmZlci53cml0ZVVJbnQ4KDB4ZmYgJiB2ZXJzaW9uLCAwKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIHZhciBhZGRyID0gQnVmZmVyLmNvbmNhdChbdmVyc2lvbkJ1ZmZlciwgcmVwXSk7XG4gICAgdmFyIGNoZWNrID0gKDAsIF9oYXNoMi5zaGEyNTYpKGFkZHIpO1xuICAgIGNoZWNrID0gKDAsIF9oYXNoMi5zaGEyNTYpKGNoZWNrKTtcbiAgICB2YXIgYnVmZmVyID0gQnVmZmVyLmNvbmNhdChbYWRkciwgY2hlY2suc2xpY2UoMCwgNCldKTtcbiAgICByZXR1cm4gbmV3IEFkZHJlc3MoKDAsIF9oYXNoMi5yaXBlbWQxNjApKGJ1ZmZlcikpO1xuICB9O1xuXG4gIEFkZHJlc3MucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gdG9CdWZmZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkeTtcbiAgfTtcblxuICBBZGRyZXNzLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICB2YXIgY2hlY2tzdW0gPSAoMCwgX2hhc2gyLnJpcGVtZDE2MCkodGhpcy5hZGR5KTtcbiAgICB2YXIgYWRkeSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuYWRkeSwgY2hlY2tzdW0uc2xpY2UoMCwgNCldKTtcbiAgICByZXR1cm4gYWRkcmVzc19wcmVmaXggKyAoMCwgX2JzLmVuY29kZSkoYWRkeSk7XG4gIH07XG5cbiAgcmV0dXJuIEFkZHJlc3M7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEFkZHJlc3M7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYWVzID0gcmVxdWlyZSgnY3J5cHRvLWpzL2FlcycpO1xuXG52YXIgX2FlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hZXMpO1xuXG52YXIgX2VuY0hleCA9IHJlcXVpcmUoJ2NyeXB0by1qcy9lbmMtaGV4Jyk7XG5cbnZhciBfZW5jSGV4MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2VuY0hleCk7XG5cbnZhciBfZW5jQmFzZSA9IHJlcXVpcmUoJ2NyeXB0by1qcy9lbmMtYmFzZTY0Jyk7XG5cbnZhciBfZW5jQmFzZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lbmNCYXNlKTtcblxudmFyIF9hc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTtcblxudmFyIF9hc3NlcnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0KTtcblxudmFyIF9oYXNoMiA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfSAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qc1xuXG5cbi8qKiBQcm92aWRlcyBzeW1ldHJpYyBlbmNyeXB0IGFuZCBkZWNyeXB0IHZpYSBBRVMuICovXG52YXIgQWVzID0gZnVuY3Rpb24gKCkge1xuICAvKiogQHByaXZhdGUgKi9cbiAgZnVuY3Rpb24gQWVzKGl2LCBrZXkpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWVzKTtcblxuICAgIHRoaXMuaXYgPSBpdjtcbiAgICB0aGlzLmtleSA9IGtleTtcbiAgfVxuXG4gIC8qKiBUaGlzIGlzIGFuIGV4Y2VsbGVudCB3YXkgdG8gZW5zdXJlIHRoYXQgYWxsIHJlZmVyZW5jZXMgdG8gQWVzIGNhbiBub3Qgb3BlcmF0ZSBhbnltb3JlXG4gICAqIChleGFtcGxlOiBhIHdhbGxldCBiZWNvbWVzIGxvY2tlZCkuICBBbiBhcHBsaWNhdGlvbiBzaG91bGQgZW5zdXJlIHRoZXJlIGlzIG9ubHkgb25lXG4gICAqIEFlcyBvYmplY3QgaW5zdGFuY2UgZm9yIGEgZ2l2ZW4gc2VjcmV0IGBzZWVkYC4gKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICB0aGlzLml2ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMua2V5ID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG5cbiAgLyoqIEBhcmcge3N0cmluZ30gc2VlZCAtIHNlY3JldCBzZWVkIG1heSBiZSB1c2VkIHRvIGVuY3J5cHQgb3IgZGVjcnlwdC4gKi9cblxuXG4gIEFlcy5mcm9tU2VlZCA9IGZ1bmN0aW9uIGZyb21TZWVkKHNlZWQpIHtcbiAgICBpZiAoc2VlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NlZWQgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICB2YXIgX2hhc2ggPSAoMCwgX2hhc2gyLnNoYTUxMikoc2VlZCk7XG4gICAgX2hhc2ggPSBfaGFzaC50b1N0cmluZygnaGV4Jyk7XG4gICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiBmcm9tU2VlZCBfaGFzaCcsX2hhc2gpXG4gICAgcmV0dXJuIEFlcy5mcm9tU2hhNTEyKF9oYXNoKTtcbiAgfTtcblxuICAvKiogQGFyZyB7c3RyaW5nfSBoYXNoIC0gQSAxMjggYnl0ZSBoZXggc3RyaW5nLCB0eXBpY2FsbHkgb25lXG4gICAqIHdvdWxkIGNhbGwge0BsaW5rIGZyb21TZWVkfSBpbnN0ZWFkLiAqL1xuXG5cbiAgQWVzLmZyb21TaGE1MTIgPSBmdW5jdGlvbiBmcm9tU2hhNTEyKGhhc2gpIHtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGhhc2gubGVuZ3RoLCAxMjgsICdBIFNoYTUxMiBpbiBIRVggc2hvdWxkIGJlIDEyOCBjaGFyYWN0ZXJzIGxvbmcsIGluc3RlYWQgZ290ICcgKyBoYXNoLmxlbmd0aCk7XG4gICAgdmFyIGl2ID0gX2VuY0hleDIuZGVmYXVsdC5wYXJzZShoYXNoLnN1YnN0cmluZyg2NCwgOTYpKTtcbiAgICB2YXIga2V5ID0gX2VuY0hleDIuZGVmYXVsdC5wYXJzZShoYXNoLnN1YnN0cmluZygwLCA2NCkpO1xuICAgIHJldHVybiBuZXcgQWVzKGl2LCBrZXkpO1xuICB9O1xuXG4gIEFlcy5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWYpIHtcbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoQnVmZmVyLmlzQnVmZmVyKGJ1ZiksICdFeHBlY3RpbmcgQnVmZmVyJyk7XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChidWYubGVuZ3RoLCA2NCwgJ0EgU2hhNTEyIEJ1ZmZlciBzaG91bGQgYmUgNjQgY2hhcmFjdGVycyBsb25nLCBpbnN0ZWFkIGdvdCAnICsgYnVmLmxlbmd0aCk7XG4gICAgcmV0dXJuIEFlcy5mcm9tU2hhNTEyKGJ1Zi50b1N0cmluZygnaGV4JykpO1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBAdGhyb3dzIHtFcnJvcn0gLSBcIkludmFsaWQgS2V5LCAuLi5cIlxuICAgICAgICBAYXJnIHtQcml2YXRlS2V5fSBwcml2YXRlX2tleSAtIHJlcXVpcmVkIGFuZCB1c2VkIGZvciBkZWNyeXB0aW9uXG4gICAgICAgIEBhcmcge1B1YmxpY0tleX0gcHVibGljX2tleSAtIHJlcXVpcmVkIGFuZCB1c2VkIHRvIGNhbGN1YWx0ZSB0aGUgc2hhcmVkIHNlY3JldFxuICAgICAgICBAYXJnIHtzdHJpbmd9IFtub25jZSA9IFwiXCJdIG9wdGlvbmFsIGJ1dCBzaG91bGQgYWx3YXlzIGJlIHByb3ZpZGVkIGFuZCBiZSB1bmlxdWVcbiAgICAgICAgd2hlbiByZS11c2luZyB0aGUgc2FtZSBwcml2YXRlL3B1YmxpYyBrZXlzIG1vcmUgdGhhbiBvbmNlLiAgVGhpcyBub25jZSBpcyBub3QgYSBzZWNyZXQuXG4gICAgICAgIEBhcmcge3N0cmluZ3xCdWZmZXJ9IG1lc3NhZ2UgLSBFbmNyeXB0ZWQgbWVzc2FnZSBjb250YWluaW5nIGEgY2hlY2tzdW1cbiAgICAgICAgQHJldHVybiB7QnVmZmVyfVxuICAgICovXG5cblxuICBBZXMuZGVjcnlwdF93aXRoX2NoZWNrc3VtID0gZnVuY3Rpb24gZGVjcnlwdF93aXRoX2NoZWNrc3VtKHByaXZhdGVfa2V5LCBwdWJsaWNfa2V5LCBub25jZSwgbWVzc2FnZSkge1xuICAgIHZhciBsZWdhY3kgPSBhcmd1bWVudHMubGVuZ3RoID4gNCAmJiBhcmd1bWVudHNbNF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1s0XSA6IGZhbHNlO1xuXG4gICAgLy8gV2FybmluZzogRG8gbm90IHB1dCBgbm9uY2UgPSBcIlwiYCBpbiB0aGUgYXJndW1lbnRzLCBpbiBlczYgdGhpcyB3aWxsXG4gICAgLy8gbm90IGNvbnZlcnQgXCJudWxsXCIgaW50byBhbiBlbXRweSBzdHJpbmdcbiAgICBpZiAobm9uY2UgPT0gbnVsbCkge1xuICAgICAgbm9uY2UgPSAnJztcbiAgICB9XG5cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihtZXNzYWdlKSkge1xuICAgICAgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKG1lc3NhZ2UsICdoZXgnKTtcbiAgICB9XG5cbiAgICB2YXIgUyA9IHByaXZhdGVfa2V5LmdldF9zaGFyZWRfc2VjcmV0KHB1YmxpY19rZXksIGxlZ2FjeSk7XG4gICAgLy8gRCBFIEIgVSBHXG4gICAgLy8gY29uc29sZS5sb2coJ2RlY3J5cHRfd2l0aF9jaGVja3N1bScsIHtcbiAgICAvLyAgICAgcHJpdl90b19wdWI6IHByaXZhdGVfa2V5LnRvUHVibGljS2V5KCkudG9TdHJpbmcoKSxcbiAgICAvLyAgICAgcHViOiBwdWJsaWNfa2V5LnRvUHVibGljS2V5U3RyaW5nKCksXG4gICAgLy8gICAgIG5vbmNlOiBub25jZSxcbiAgICAvLyAgICAgbWVzc2FnZTogbWVzc2FnZS5sZW5ndGgsXG4gICAgLy8gICAgIFM6IFMudG9TdHJpbmcoJ2hleCcpXG4gICAgLy8gfSlcblxuICAgIHZhciBhZXMgPSBBZXMuZnJvbVNlZWQoQnVmZmVyLmNvbmNhdChbXG4gICAgLy8gQSBudWxsIG9yIGVtcHR5IHN0cmluZyBub25jZSB3aWxsIG5vdCBlZmZlY3QgdGhlIGhhc2hcbiAgICBCdWZmZXIuZnJvbSgnJyArIG5vbmNlKSwgQnVmZmVyLmZyb20oUy50b1N0cmluZygnaGV4JykpXSkpO1xuXG4gICAgdmFyIHBsYW5lYnVmZmVyID0gYWVzLmRlY3J5cHQobWVzc2FnZSk7XG5cbiAgICBpZiAoIShwbGFuZWJ1ZmZlci5sZW5ndGggPj0gNCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBrZXksIGNvdWxkIG5vdCBkZWNyeXB0IG1lc3NhZ2UoMSknKTtcbiAgICB9XG5cbiAgICAvLyBERUJVRyBjb25zb2xlLmxvZygnLi4uIHBsYW5lYnVmZmVyJyxwbGFuZWJ1ZmZlcilcbiAgICB2YXIgY2hlY2tzdW0gPSBwbGFuZWJ1ZmZlci5zbGljZSgwLCA0KTtcbiAgICB2YXIgcGxhaW50ZXh0ID0gcGxhbmVidWZmZXIuc2xpY2UoNCk7XG5cbiAgICAvLyBjb25zb2xlLmxvZygnLi4uIGNoZWNrc3VtJyxjaGVja3N1bS50b1N0cmluZygnaGV4JykpXG4gICAgLy8gY29uc29sZS5sb2coJy4uLiBwbGFpbnRleHQnLHBsYWludGV4dC50b1N0cmluZygpKVxuXG4gICAgdmFyIG5ld19jaGVja3N1bSA9ICgwLCBfaGFzaDIuc2hhMjU2KShwbGFpbnRleHQpO1xuICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS5zbGljZSgwLCA0KTtcbiAgICBuZXdfY2hlY2tzdW0gPSBuZXdfY2hlY2tzdW0udG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgaWYgKCEoY2hlY2tzdW0udG9TdHJpbmcoJ2hleCcpID09PSBuZXdfY2hlY2tzdW0pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5LCBjb3VsZCBub3QgZGVjcnlwdCBtZXNzYWdlKDIpJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBsYWludGV4dDtcbiAgfTtcblxuICAvKiogSWRlbnRpY2FsIHRvIHtAbGluayBkZWNyeXB0X3dpdGhfY2hlY2tzdW19IGJ1dCB1c2VkIHRvIGVuY3J5cHQuICBTaG91bGQgbm90IHRocm93IGFuIGVycm9yLlxuICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9IG1lc3NhZ2UgLSBFbmNyeXB0ZWQgbWVzc2FnZSB3aGljaCBpbmNsdWRlcyBhIGNoZWNrc3VtXG4gICAgKi9cblxuXG4gIEFlcy5lbmNyeXB0X3dpdGhfY2hlY2tzdW0gPSBmdW5jdGlvbiBlbmNyeXB0X3dpdGhfY2hlY2tzdW0ocHJpdmF0ZV9rZXksIHB1YmxpY19rZXksIG5vbmNlLCBtZXNzYWdlKSB7XG4gICAgLy8gV2FybmluZzogRG8gbm90IHB1dCBgbm9uY2UgPSBcIlwiYCBpbiB0aGUgYXJndW1lbnRzLCBpbiBlczYgdGhpcyB3aWxsXG4gICAgLy8gbm90IGNvbnZlcnQgXCJudWxsXCIgaW50byBhbiBlbXRweSBzdHJpbmdcblxuICAgIGlmIChub25jZSA9PSBudWxsKSB7XG4gICAgICBub25jZSA9ICcnO1xuICAgIH1cblxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKG1lc3NhZ2UpKSB7XG4gICAgICBtZXNzYWdlID0gQnVmZmVyLmZyb20obWVzc2FnZSwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIHZhciBTID0gcHJpdmF0ZV9rZXkuZ2V0X3NoYXJlZF9zZWNyZXQocHVibGljX2tleSk7XG5cbiAgICAvLyBEIEUgQiBVIEdcbiAgICAvLyBjb25zb2xlLmxvZygnZW5jcnlwdF93aXRoX2NoZWNrc3VtJywge1xuICAgIC8vICAgICBwcml2X3RvX3B1YjogcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKS50b1N0cmluZygpXG4gICAgLy8gICAgIHB1YjogcHVibGljX2tleS50b1B1YmxpY0tleVN0cmluZygpXG4gICAgLy8gICAgIG5vbmNlOiBub25jZVxuICAgIC8vICAgICBtZXNzYWdlOiBtZXNzYWdlLmxlbmd0aFxuICAgIC8vICAgICBTOiBTLnRvU3RyaW5nKCdoZXgnKVxuICAgIC8vIH0pXG5cbiAgICB2YXIgYWVzID0gQWVzLmZyb21TZWVkKEJ1ZmZlci5jb25jYXQoW1xuICAgIC8vIEEgbnVsbCBvciBlbXB0eSBzdHJpbmcgbm9uY2Ugd2lsbCBub3QgZWZmZWN0IHRoZSBoYXNoXG4gICAgQnVmZmVyLmZyb20oJycgKyBub25jZSksIEJ1ZmZlci5mcm9tKFMudG9TdHJpbmcoJ2hleCcpKV0pKTtcbiAgICAvLyBERUJVRyBjb25zb2xlLmxvZygnLi4uIFMnLFMudG9TdHJpbmcoJ2hleCcpKVxuICAgIHZhciBjaGVja3N1bSA9ICgwLCBfaGFzaDIuc2hhMjU2KShtZXNzYWdlKS5zbGljZSgwLCA0KTtcbiAgICB2YXIgcGF5bG9hZCA9IEJ1ZmZlci5jb25jYXQoW2NoZWNrc3VtLCBtZXNzYWdlXSk7XG4gICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiBwYXlsb2FkJyxwYXlsb2FkLnRvU3RyaW5nKCkpXG4gICAgcmV0dXJuIGFlcy5lbmNyeXB0KHBheWxvYWQpO1xuICB9O1xuXG4gIC8qKiBAcHJpdmF0ZSAqL1xuXG5cbiAgQWVzLnByb3RvdHlwZS5fZGVjcnlwdF93b3JkX2FycmF5ID0gZnVuY3Rpb24gX2RlY3J5cHRfd29yZF9hcnJheShjaXBoZXIpIHtcbiAgICAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy8jQ3VzdG9tX0tleV9hbmRfSVZcbiAgICAvLyBzZWUgd2FsbGV0X3JlY29yZHMuY3BwIG1hc3Rlcl9rZXk6OmRlY3J5cHRfa2V5XG4gICAgcmV0dXJuIF9hZXMyLmRlZmF1bHQuZGVjcnlwdCh7IGNpcGhlcnRleHQ6IGNpcGhlciwgc2FsdDogbnVsbCB9LCB0aGlzLmtleSwgeyBpdjogdGhpcy5pdiB9KTtcbiAgfTtcblxuICAvKiogQHByaXZhdGUgKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuX2VuY3J5cHRfd29yZF9hcnJheSA9IGZ1bmN0aW9uIF9lbmNyeXB0X3dvcmRfYXJyYXkocGxhaW50ZXh0KSB7XG4gICAgLy8gaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvaXNzdWVzL2RldGFpbD9pZD04NVxuICAgIHZhciBjaXBoZXIgPSBfYWVzMi5kZWZhdWx0LmVuY3J5cHQocGxhaW50ZXh0LCB0aGlzLmtleSwgeyBpdjogdGhpcy5pdiB9KTtcbiAgICByZXR1cm4gX2VuY0Jhc2UyLmRlZmF1bHQucGFyc2UoY2lwaGVyLnRvU3RyaW5nKCkpO1xuICB9O1xuXG4gIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ30gY2lwaGVydGV4dFxuICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9IGJpbmFyeVxuICAgICovXG5cblxuICBBZXMucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbiBkZWNyeXB0KGNpcGhlcnRleHQpIHtcbiAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjaXBoZXJ0ZXh0ID0gQnVmZmVyLmZyb20oY2lwaGVydGV4dCwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGNpcGhlcnRleHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1ZmZlciByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShjaXBoZXJ0ZXh0LCAnTWlzc2luZyBjaXBoZXIgdGV4dCcpO1xuICAgIC8vIGhleCBpcyB0aGUgb25seSBjb21tb24gZm9ybWF0XG4gICAgdmFyIGhleCA9IHRoaXMuZGVjcnlwdEhleChjaXBoZXJ0ZXh0LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpO1xuICB9O1xuXG4gIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ30gcGxhaW50ZXh0XG4gICAgICAgIEByZXR1cm4ge0J1ZmZlcn0gYmluYXJ5XG4gICAgKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuZW5jcnlwdCA9IGZ1bmN0aW9uIGVuY3J5cHQocGxhaW50ZXh0KSB7XG4gICAgaWYgKHR5cGVvZiBwbGFpbnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBwbGFpbnRleHQgPSBCdWZmZXIuZnJvbShwbGFpbnRleHQsICdiaW5hcnknKTtcbiAgICB9XG5cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwbGFpbnRleHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1ZmZlciByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8vIGFzc2VydCBwbGFpbnRleHQsIFwiTWlzc2luZyBwbGFpbiB0ZXh0XCJcbiAgICAvLyBoZXggaXMgdGhlIG9ubHkgY29tbW9uIGZvcm1hdFxuICAgIHZhciBoZXggPSB0aGlzLmVuY3J5cHRIZXgocGxhaW50ZXh0LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpO1xuICB9O1xuXG4gIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ3xCdWZmZXJ9IHBsYWludGV4dFxuICAgICAgICBAcmV0dXJuIHtzdHJpbmd9IGhleFxuICAgICovXG5cblxuICBBZXMucHJvdG90eXBlLmVuY3J5cHRUb0hleCA9IGZ1bmN0aW9uIGVuY3J5cHRUb0hleChwbGFpbnRleHQpIHtcbiAgICBpZiAodHlwZW9mIHBsYWludGV4dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHBsYWludGV4dCA9IEJ1ZmZlci5mcm9tKHBsYWludGV4dCwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKHBsYWludGV4dCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYnVmZmVyIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgLy8gYXNzZXJ0IHBsYWludGV4dCwgXCJNaXNzaW5nIHBsYWluIHRleHRcIlxuICAgIC8vIGhleCBpcyB0aGUgb25seSBjb21tb24gZm9ybWF0XG4gICAgcmV0dXJuIHRoaXMuZW5jcnlwdEhleChwbGFpbnRleHQudG9TdHJpbmcoJ2hleCcpKTtcbiAgfTtcblxuICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICBAYXJnIHtzdHJpbmd9IGNpcGhlciAtIGhleFxuICAgICAgICBAcmV0dXJuIHtzdHJpbmd9IGJpbmFyeSAoY291bGQgZWFzaWx5IGJlIHJlYWRhYmxlIHRleHQpXG4gICAgKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuZGVjcnlwdEhleCA9IGZ1bmN0aW9uIGRlY3J5cHRIZXgoY2lwaGVyKSB7XG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKGNpcGhlciwgJ01pc3NpbmcgY2lwaGVyIHRleHQnKTtcbiAgICAvLyBDb252ZXJ0IGRhdGEgaW50byB3b3JkIGFycmF5cyAodXNlZCBieSBDcnlwdG8pXG4gICAgdmFyIGNpcGhlcl9hcnJheSA9IF9lbmNIZXgyLmRlZmF1bHQucGFyc2UoY2lwaGVyKTtcbiAgICB2YXIgcGxhaW53b3JkcyA9IHRoaXMuX2RlY3J5cHRfd29yZF9hcnJheShjaXBoZXJfYXJyYXkpO1xuICAgIHJldHVybiBfZW5jSGV4Mi5kZWZhdWx0LnN0cmluZ2lmeShwbGFpbndvcmRzKTtcbiAgfTtcblxuICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICBAYXJnIHtzdHJpbmd9IGNpcGhlciAtIGhleFxuICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9IGVuY29kZWQgYXMgc3BlY2lmaWVkIGJ5IHRoZSBwYXJhbWV0ZXJcbiAgICAqL1xuXG5cbiAgQWVzLnByb3RvdHlwZS5kZWNyeXB0SGV4VG9CdWZmZXIgPSBmdW5jdGlvbiBkZWNyeXB0SGV4VG9CdWZmZXIoY2lwaGVyKSB7XG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKGNpcGhlciwgJ01pc3NpbmcgY2lwaGVyIHRleHQnKTtcbiAgICAvLyBDb252ZXJ0IGRhdGEgaW50byB3b3JkIGFycmF5cyAodXNlZCBieSBDcnlwdG8pXG4gICAgdmFyIGNpcGhlcl9hcnJheSA9IF9lbmNIZXgyLmRlZmF1bHQucGFyc2UoY2lwaGVyKTtcbiAgICB2YXIgcGxhaW53b3JkcyA9IHRoaXMuX2RlY3J5cHRfd29yZF9hcnJheShjaXBoZXJfYXJyYXkpO1xuICAgIHZhciBwbGFpbmhleCA9IF9lbmNIZXgyLmRlZmF1bHQuc3RyaW5naWZ5KHBsYWlud29yZHMpO1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShwbGFpbmhleCwgJ2hleCcpO1xuICB9O1xuXG4gIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ30gY2lwaGVyIC0gaGV4XG4gICAgICAgIEBhcmcge3N0cmluZ30gW2VuY29kaW5nID0gJ2JpbmFyeSddIC0gYSB2YWxpZCBCdWZmZXIgZW5jb2RpbmdcbiAgICAgICAgQHJldHVybiB7U3RyaW5nfSBlbmNvZGVkIGFzIHNwZWNpZmllZCBieSB0aGUgcGFyYW1ldGVyXG4gICAgKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuZGVjcnlwdEhleFRvVGV4dCA9IGZ1bmN0aW9uIGRlY3J5cHRIZXhUb1RleHQoY2lwaGVyKSB7XG4gICAgdmFyIGVuY29kaW5nID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnYmluYXJ5JztcblxuICAgIHJldHVybiB0aGlzLmRlY3J5cHRIZXhUb0J1ZmZlcihjaXBoZXIpLnRvU3RyaW5nKGVuY29kaW5nKTtcbiAgfTtcblxuICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICBAYXJnIHtzdHJpbmd9IHBsYWluaGV4IC0gaGV4IGZvcm1hdFxuICAgICAgICBAcmV0dXJuIHtTdHJpbmd9IGhleFxuICAgICovXG5cblxuICBBZXMucHJvdG90eXBlLmVuY3J5cHRIZXggPSBmdW5jdGlvbiBlbmNyeXB0SGV4KHBsYWluaGV4KSB7XG4gICAgdmFyIHBsYWluX2FycmF5ID0gX2VuY0hleDIuZGVmYXVsdC5wYXJzZShwbGFpbmhleCk7XG4gICAgdmFyIGNpcGhlcl9hcnJheSA9IHRoaXMuX2VuY3J5cHRfd29yZF9hcnJheShwbGFpbl9hcnJheSk7XG4gICAgcmV0dXJuIF9lbmNIZXgyLmRlZmF1bHQuc3RyaW5naWZ5KGNpcGhlcl9hcnJheSk7XG4gIH07XG5cbiAgcmV0dXJuIEFlcztcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gQWVzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy52ZXJpZnlSYXcgPSBleHBvcnRzLnZlcmlmeSA9IGV4cG9ydHMuc2lnbiA9IGV4cG9ydHMucmVjb3ZlclB1YktleSA9IGV4cG9ydHMuZGV0ZXJtaW5pc3RpY0dlbmVyYXRlSyA9IGV4cG9ydHMuY2FsY1B1YktleVJlY292ZXJ5UGFyYW0gPSB1bmRlZmluZWQ7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfYmlnaSA9IHJlcXVpcmUoJ2JpZ2knKTtcblxudmFyIF9iaWdpMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2JpZ2kpO1xuXG52YXIgX2hhc2ggPSByZXF1aXJlKCcuL2hhc2gnKTtcblxudmFyIF9lbmZvcmNlX3R5cGVzID0gcmVxdWlyZSgnLi9lbmZvcmNlX3R5cGVzJyk7XG5cbnZhciBfZW5mb3JjZV90eXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lbmZvcmNlX3R5cGVzKTtcblxudmFyIF9lY3NpZ25hdHVyZSA9IHJlcXVpcmUoJy4vZWNzaWduYXR1cmUnKTtcblxudmFyIF9lY3NpZ25hdHVyZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lY3NpZ25hdHVyZSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8vIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM2OTc5I3NlY3Rpb24tMy4yXG5cbi8vIGZyb20gZ2l0aHViLmNvbS9iaXRjb2luanMvYml0Y29pbmpzLWxpYiBmcm9tIGdpdGh1Yi5jb20vY3J5cHRvY29pbmpzL2VjZHNhXG5mdW5jdGlvbiBkZXRlcm1pbmlzdGljR2VuZXJhdGVLKGN1cnZlLCBoYXNoLCBkLCBjaGVja1NpZywgbm9uY2UpIHtcbiAgKDAsIF9lbmZvcmNlX3R5cGVzMi5kZWZhdWx0KSgnQnVmZmVyJywgaGFzaCk7XG4gICgwLCBfZW5mb3JjZV90eXBlczIuZGVmYXVsdCkoX2JpZ2kyLmRlZmF1bHQsIGQpO1xuXG4gIGlmIChub25jZSkge1xuICAgIGhhc2ggPSAoMCwgX2hhc2guc2hhMjU2KShCdWZmZXIuY29uY2F0KFtoYXNoLCBCdWZmZXIuYWxsb2Mobm9uY2UpXSkpO1xuICB9XG5cbiAgLy8gc2FuaXR5IGNoZWNrXG4gIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoaGFzaC5sZW5ndGgsIDMyLCAnSGFzaCBtdXN0IGJlIDI1NiBiaXQnKTtcblxuICB2YXIgeCA9IGQudG9CdWZmZXIoMzIpO1xuICB2YXIgayA9IEJ1ZmZlci5hbGxvYygzMik7XG4gIHZhciB2ID0gQnVmZmVyLmFsbG9jKDMyKTtcblxuICAvLyBTdGVwIEJcbiAgdi5maWxsKDEpO1xuXG4gIC8vIFN0ZXAgQ1xuICBrLmZpbGwoMCk7XG5cbiAgLy8gU3RlcCBEXG4gIGsgPSAoMCwgX2hhc2guSG1hY1NIQTI1NikoQnVmZmVyLmNvbmNhdChbdiwgQnVmZmVyLmZyb20oWzBdKSwgeCwgaGFzaF0pLCBrKTtcblxuICAvLyBTdGVwIEVcbiAgdiA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KSh2LCBrKTtcblxuICAvLyBTdGVwIEZcbiAgayA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KShCdWZmZXIuY29uY2F0KFt2LCBCdWZmZXIuZnJvbShbMV0pLCB4LCBoYXNoXSksIGspO1xuXG4gIC8vIFN0ZXAgR1xuICB2ID0gKDAsIF9oYXNoLkhtYWNTSEEyNTYpKHYsIGspO1xuXG4gIC8vIFN0ZXAgSDEvSDJhLCBpZ25vcmVkIGFzIHRsZW4gPT09IHFsZW4gKDI1NiBiaXQpXG4gIC8vIFN0ZXAgSDJiXG4gIHYgPSAoMCwgX2hhc2guSG1hY1NIQTI1Nikodiwgayk7XG5cbiAgdmFyIFQgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKHYpO1xuXG4gIC8vIFN0ZXAgSDMsIHJlcGVhdCB1bnRpbCBUIGlzIHdpdGhpbiB0aGUgaW50ZXJ2YWwgWzEsIG4gLSAxXVxuICB3aGlsZSAoVC5zaWdudW0oKSA8PSAwIHx8IFQuY29tcGFyZVRvKGN1cnZlLm4pID49IDAgfHwgIWNoZWNrU2lnKFQpKSB7XG4gICAgayA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KShCdWZmZXIuY29uY2F0KFt2LCBCdWZmZXIuZnJvbShbMF0pXSksIGspO1xuICAgIHYgPSAoMCwgX2hhc2guSG1hY1NIQTI1Nikodiwgayk7XG5cbiAgICAvLyBTdGVwIEgxL0gyYSwgYWdhaW4sIGlnbm9yZWQgYXMgdGxlbiA9PT0gcWxlbiAoMjU2IGJpdClcbiAgICAvLyBTdGVwIEgyYiBhZ2FpblxuICAgIHYgPSAoMCwgX2hhc2guSG1hY1NIQTI1Nikodiwgayk7XG5cbiAgICBUID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcih2KTtcbiAgfVxuXG4gIHJldHVybiBUO1xufVxuXG5mdW5jdGlvbiBzaWduKGN1cnZlLCBoYXNoLCBkLCBub25jZSkge1xuICB2YXIgZSA9IF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoaGFzaCk7XG4gIHZhciBuID0gY3VydmUubjtcbiAgdmFyIEcgPSBjdXJ2ZS5HO1xuXG4gIHZhciByID0gdm9pZCAwO1xuICB2YXIgcyA9IHZvaWQgMDtcblxuICBkZXRlcm1pbmlzdGljR2VuZXJhdGVLKGN1cnZlLCBoYXNoLCBkLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgLy8gZmluZCBjYW5vbmljYWxseSB2YWxpZCBzaWduYXR1cmVcbiAgICB2YXIgUSA9IEcubXVsdGlwbHkoa2V5KTtcblxuICAgIGlmIChjdXJ2ZS5pc0luZmluaXR5KFEpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgciA9IFEuYWZmaW5lWC5tb2Qobik7XG5cbiAgICBpZiAoci5zaWdudW0oKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHMgPSBrZXkubW9kSW52ZXJzZShuKS5tdWx0aXBseShlLmFkZChkLm11bHRpcGx5KHIpKSkubW9kKG4pO1xuXG4gICAgaWYgKHMuc2lnbnVtKCkgPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgbm9uY2UpO1xuXG4gIHZhciBOX09WRVJfVFdPID0gbi5zaGlmdFJpZ2h0KDEpO1xuXG4gIC8vIGVuZm9yY2UgbG93IFMgdmFsdWVzLCBzZWUgYmlwNjI6ICdsb3cgcyB2YWx1ZXMgaW4gc2lnbmF0dXJlcydcbiAgaWYgKHMuY29tcGFyZVRvKE5fT1ZFUl9UV08pID4gMCkge1xuICAgIHMgPSBuLnN1YnRyYWN0KHMpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBfZWNzaWduYXR1cmUyLmRlZmF1bHQociwgcyk7XG59XG5cbmZ1bmN0aW9uIHZlcmlmeVJhdyhjdXJ2ZSwgZSwgc2lnbmF0dXJlLCBRKSB7XG4gIHZhciBuID0gY3VydmUubjtcbiAgdmFyIEcgPSBjdXJ2ZS5HO1xuXG4gIHZhciByID0gc2lnbmF0dXJlLnI7XG4gIHZhciBzID0gc2lnbmF0dXJlLnM7XG5cbiAgLy8gMS40LjEgRW5mb3JjZSByIGFuZCBzIGFyZSBib3RoIGludGVnZXJzIGluIHRoZSBpbnRlcnZhbCBbMSwgbiDiiJIgMV1cbiAgaWYgKHIuc2lnbnVtKCkgPD0gMCB8fCByLmNvbXBhcmVUbyhuKSA+PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHMuc2lnbnVtKCkgPD0gMCB8fCBzLmNvbXBhcmVUbyhuKSA+PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gYyA9IHNeLTEgbW9kIG5cbiAgdmFyIGMgPSBzLm1vZEludmVyc2Uobik7XG5cbiAgLy8gMS40LjQgQ29tcHV0ZSB1MSA9IGVzXuKIkjEgbW9kIG5cbiAgLy8gICAgICAgICAgICAgICB1MiA9IHJzXuKIkjEgbW9kIG5cbiAgdmFyIHUxID0gZS5tdWx0aXBseShjKS5tb2Qobik7XG4gIHZhciB1MiA9IHIubXVsdGlwbHkoYykubW9kKG4pO1xuXG4gIC8vIDEuNC41IENvbXB1dGUgUiA9ICh4UiwgeVIpID0gdTFHICsgdTJRXG4gIHZhciBSID0gRy5tdWx0aXBseVR3byh1MSwgUSwgdTIpO1xuXG4gIC8vIDEuNC41IChjb250LikgRW5mb3JjZSBSIGlzIG5vdCBhdCBpbmZpbml0eVxuICBpZiAoY3VydmUuaXNJbmZpbml0eShSKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIDEuNC42IENvbnZlcnQgdGhlIGZpZWxkIGVsZW1lbnQgUi54IHRvIGFuIGludGVnZXJcbiAgdmFyIHhSID0gUi5hZmZpbmVYO1xuXG4gIC8vIDEuNC43IFNldCB2ID0geFIgbW9kIG5cbiAgdmFyIHYgPSB4Ui5tb2Qobik7XG5cbiAgLy8gMS40LjggSWYgdiA9IHIsIG91dHB1dCBcInZhbGlkXCIsIGFuZCBpZiB2ICE9IHIsIG91dHB1dCBcImludmFsaWRcIlxuICByZXR1cm4gdi5lcXVhbHMocik7XG59XG5cbmZ1bmN0aW9uIHZlcmlmeShjdXJ2ZSwgaGFzaCwgc2lnbmF0dXJlLCBRKSB7XG4gIC8vIDEuNC4yIEggPSBIYXNoKE0pLCBhbHJlYWR5IGRvbmUgYnkgdGhlIHVzZXJcbiAgLy8gMS40LjMgZSA9IEhcbiAgdmFyIGUgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGhhc2gpO1xuICByZXR1cm4gdmVyaWZ5UmF3KGN1cnZlLCBlLCBzaWduYXR1cmUsIFEpO1xufVxuXG4vKipcbiAqIFJlY292ZXIgYSBwdWJsaWMga2V5IGZyb20gYSBzaWduYXR1cmUuXG4gKlxuICogU2VlIFNFQyAxOiBFbGxpcHRpYyBDdXJ2ZSBDcnlwdG9ncmFwaHksIHNlY3Rpb24gNC4xLjYsIFwiUHVibGljXG4gKiBLZXkgUmVjb3ZlcnkgT3BlcmF0aW9uXCIuXG4gKlxuICogaHR0cDovL3d3dy5zZWNnLm9yZy9kb3dubG9hZC9haWQtNzgwL3NlYzEtdjIucGRmXG4gKi9cbmZ1bmN0aW9uIHJlY292ZXJQdWJLZXkoY3VydmUsIGUsIHNpZ25hdHVyZSwgaSkge1xuICBfYXNzZXJ0Mi5kZWZhdWx0LnN0cmljdEVxdWFsKGkgJiAzLCBpLCAnUmVjb3ZlcnkgcGFyYW0gaXMgbW9yZSB0aGFuIHR3byBiaXRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICB2YXIgbiA9IGN1cnZlLm47XG4gIHZhciBHID0gY3VydmUuRztcblxuICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICB2YXIgcyA9IHNpZ25hdHVyZS5zO1xuXG4gICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShyLnNpZ251bSgpID4gMCAmJiByLmNvbXBhcmVUbyhuKSA8IDAsICdJbnZhbGlkIHIgdmFsdWUnKTtcbiAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKHMuc2lnbnVtKCkgPiAwICYmIHMuY29tcGFyZVRvKG4pIDwgMCwgJ0ludmFsaWQgcyB2YWx1ZScpO1xuXG4gIC8vIEEgc2V0IExTQiBzaWduaWZpZXMgdGhhdCB0aGUgeS1jb29yZGluYXRlIGlzIG9kZFxuICB2YXIgaXNZT2RkID0gaSAmIDE7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAvLyBUaGUgbW9yZSBzaWduaWZpY2FudCBiaXQgc3BlY2lmaWVzIHdoZXRoZXIgd2Ugc2hvdWxkIHVzZSB0aGVcbiAgLy8gZmlyc3Qgb3Igc2Vjb25kIGNhbmRpZGF0ZSBrZXkuXG4gIHZhciBpc1NlY29uZEtleSA9IGkgPj4gMTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gIC8vIDEuMSBMZXQgeCA9IHIgKyBqblxuICB2YXIgeCA9IGlzU2Vjb25kS2V5ID8gci5hZGQobikgOiByO1xuICB2YXIgUiA9IGN1cnZlLnBvaW50RnJvbVgoaXNZT2RkLCB4KTtcblxuICAvLyAxLjQgQ2hlY2sgdGhhdCBuUiBpcyBhdCBpbmZpbml0eVxuICB2YXIgblIgPSBSLm11bHRpcGx5KG4pO1xuICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoY3VydmUuaXNJbmZpbml0eShuUiksICduUiBpcyBub3QgYSB2YWxpZCBjdXJ2ZSBwb2ludCcpO1xuXG4gIC8vIENvbXB1dGUgLWUgZnJvbSBlXG4gIHZhciBlTmVnID0gZS5uZWdhdGUoKS5tb2Qobik7XG5cbiAgLy8gMS42LjEgQ29tcHV0ZSBRID0gcl4tMSAoc1IgLSAgZUcpXG4gIC8vICAgICAgICAgICAgICAgUSA9IHJeLTEgKHNSICsgLWVHKVxuICB2YXIgckludiA9IHIubW9kSW52ZXJzZShuKTtcblxuICB2YXIgUSA9IFIubXVsdGlwbHlUd28ocywgRywgZU5lZykubXVsdGlwbHkockludik7XG4gIGN1cnZlLnZhbGlkYXRlKFEpO1xuXG4gIHJldHVybiBRO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBwdWJrZXkgZXh0cmFjdGlvbiBwYXJhbWV0ZXIuXG4gKlxuICogV2hlbiBleHRyYWN0aW5nIGEgcHVia2V5IGZyb20gYSBzaWduYXR1cmUsIHdlIGhhdmUgdG9cbiAqIGRpc3Rpbmd1aXNoIGZvdXIgZGlmZmVyZW50IGNhc2VzLiBSYXRoZXIgdGhhbiBwdXR0aW5nIHRoaXNcbiAqIGJ1cmRlbiBvbiB0aGUgdmVyaWZpZXIsIEJpdGNvaW4gaW5jbHVkZXMgYSAyLWJpdCB2YWx1ZSB3aXRoIHRoZVxuICogc2lnbmF0dXJlLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gc2ltcGx5IHRyaWVzIGFsbCBmb3VyIGNhc2VzIGFuZCByZXR1cm5zIHRoZSB2YWx1ZVxuICogdGhhdCByZXN1bHRlZCBpbiBhIHN1Y2Nlc3NmdWwgcHVia2V5IHJlY292ZXJ5LlxuICovXG5mdW5jdGlvbiBjYWxjUHViS2V5UmVjb3ZlcnlQYXJhbShjdXJ2ZSwgZSwgc2lnbmF0dXJlLCBRKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgdmFyIFFwcmltZSA9IHJlY292ZXJQdWJLZXkoY3VydmUsIGUsIHNpZ25hdHVyZSwgaSk7XG5cbiAgICAvLyAxLjYuMiBWZXJpZnkgUVxuICAgIGlmIChRcHJpbWUuZXF1YWxzKFEpKSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIHZhbGlkIHJlY292ZXJ5IGZhY3RvcicpO1xufVxuXG5leHBvcnRzLmNhbGNQdWJLZXlSZWNvdmVyeVBhcmFtID0gY2FsY1B1YktleVJlY292ZXJ5UGFyYW07XG5leHBvcnRzLmRldGVybWluaXN0aWNHZW5lcmF0ZUsgPSBkZXRlcm1pbmlzdGljR2VuZXJhdGVLO1xuZXhwb3J0cy5yZWNvdmVyUHViS2V5ID0gcmVjb3ZlclB1YktleTtcbmV4cG9ydHMuc2lnbiA9IHNpZ247XG5leHBvcnRzLnZlcmlmeSA9IHZlcmlmeTtcbmV4cG9ydHMudmVyaWZ5UmF3ID0gdmVyaWZ5UmF3OyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9hc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTtcblxudmFyIF9hc3NlcnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0KTtcblxudmFyIF9iaWdpID0gcmVxdWlyZSgnYmlnaScpO1xuXG52YXIgX2JpZ2kyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYmlnaSk7XG5cbnZhciBfZW5mb3JjZV90eXBlcyA9IHJlcXVpcmUoJy4vZW5mb3JjZV90eXBlcycpO1xuXG52YXIgX2VuZm9yY2VfdHlwZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZW5mb3JjZV90eXBlcyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8vIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2JpdGNvaW5qcy9iaXRjb2luanMtbGliXG5mdW5jdGlvbiBFQ1NpZ25hdHVyZShyLCBzKSB7XG4gICgwLCBfZW5mb3JjZV90eXBlczIuZGVmYXVsdCkoX2JpZ2kyLmRlZmF1bHQsIHIpO1xuICAoMCwgX2VuZm9yY2VfdHlwZXMyLmRlZmF1bHQpKF9iaWdpMi5kZWZhdWx0LCBzKTtcblxuICB0aGlzLnIgPSByO1xuICB0aGlzLnMgPSBzO1xufVxuXG4vLyBJbXBvcnQgb3BlcmF0aW9uc1xuLyogZXNsaW50IG5vLWJpdHdpc2U6IFwib2ZmXCIgKi9cbkVDU2lnbmF0dXJlLnBhcnNlQ29tcGFjdCA9IGZ1bmN0aW9uIChidWZmZXIpIHtcbiAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChidWZmZXIubGVuZ3RoLCA2NSwgJ0ludmFsaWQgc2lnbmF0dXJlIGxlbmd0aCcpO1xuICB2YXIgaSA9IGJ1ZmZlci5yZWFkVUludDgoMCkgLSAyNztcblxuICAvLyBBdCBtb3N0IDMgYml0c1xuICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGksIGkgJiA3LCAnSW52YWxpZCBzaWduYXR1cmUgcGFyYW1ldGVyJyk7XG4gIHZhciBjb21wcmVzc2VkID0gISEoaSAmIDQpO1xuXG4gIC8vIFJlY292ZXJ5IHBhcmFtIG9ubHlcbiAgaSAmPSAzO1xuXG4gIHZhciByID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcihidWZmZXIuc2xpY2UoMSwgMzMpKTtcbiAgdmFyIHMgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1ZmZlci5zbGljZSgzMykpO1xuXG4gIHJldHVybiB7XG4gICAgY29tcHJlc3NlZDogY29tcHJlc3NlZCxcbiAgICBpOiBpLFxuICAgIHNpZ25hdHVyZTogbmV3IEVDU2lnbmF0dXJlKHIsIHMpXG4gIH07XG59O1xuXG5FQ1NpZ25hdHVyZS5mcm9tREVSID0gZnVuY3Rpb24gKGJ1ZmZlcikge1xuICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGJ1ZmZlci5yZWFkVUludDgoMCksIDB4MzAsICdOb3QgYSBERVIgc2VxdWVuY2UnKTtcbiAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChidWZmZXIucmVhZFVJbnQ4KDEpLCBidWZmZXIubGVuZ3RoIC0gMiwgJ0ludmFsaWQgc2VxdWVuY2UgbGVuZ3RoJyk7XG4gIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoYnVmZmVyLnJlYWRVSW50OCgyKSwgMHgwMiwgJ0V4cGVjdGVkIGEgREVSIGludGVnZXInKTtcblxuICB2YXIgckxlbiA9IGJ1ZmZlci5yZWFkVUludDgoMyk7XG4gICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShyTGVuID4gMCwgJ1IgbGVuZ3RoIGlzIHplcm8nKTtcblxuICB2YXIgb2Zmc2V0ID0gNCArIHJMZW47XG4gIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoYnVmZmVyLnJlYWRVSW50OChvZmZzZXQpLCAweDAyLCAnRXhwZWN0ZWQgYSBERVIgaW50ZWdlciAoMiknKTtcblxuICB2YXIgc0xlbiA9IGJ1ZmZlci5yZWFkVUludDgob2Zmc2V0ICsgMSk7XG4gICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShzTGVuID4gMCwgJ1MgbGVuZ3RoIGlzIHplcm8nKTtcblxuICB2YXIgckIgPSBidWZmZXIuc2xpY2UoNCwgb2Zmc2V0KTtcbiAgdmFyIHNCID0gYnVmZmVyLnNsaWNlKG9mZnNldCArIDIpO1xuICBvZmZzZXQgKz0gMiArIHNMZW47XG5cbiAgaWYgKHJMZW4gPiAxICYmIHJCLnJlYWRVSW50OCgwKSA9PT0gMHgwMCkge1xuICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShyQi5yZWFkVUludDgoMSkgJiAweDgwLCAnUiB2YWx1ZSBleGNlc3NpdmVseSBwYWRkZWQnKTtcbiAgfVxuXG4gIGlmIChzTGVuID4gMSAmJiBzQi5yZWFkVUludDgoMCkgPT09IDB4MDApIHtcbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoc0IucmVhZFVJbnQ4KDEpICYgMHg4MCwgJ1MgdmFsdWUgZXhjZXNzaXZlbHkgcGFkZGVkJyk7XG4gIH1cblxuICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKG9mZnNldCwgYnVmZmVyLmxlbmd0aCwgJ0ludmFsaWQgREVSIGVuY29kaW5nJyk7XG4gIHZhciByID0gX2JpZ2kyLmRlZmF1bHQuZnJvbURFUkludGVnZXIockIpO1xuICB2YXIgcyA9IF9iaWdpMi5kZWZhdWx0LmZyb21ERVJJbnRlZ2VyKHNCKTtcblxuICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoci5zaWdudW0oKSA+PSAwLCAnUiB2YWx1ZSBpcyBuZWdhdGl2ZScpO1xuICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkocy5zaWdudW0oKSA+PSAwLCAnUyB2YWx1ZSBpcyBuZWdhdGl2ZScpO1xuXG4gIHJldHVybiBuZXcgRUNTaWduYXR1cmUociwgcyk7XG59O1xuXG4vLyBGSVhNRTogMHgwMCwgMHgwNCwgMHg4MCBhcmUgU0lHSEFTSF8qIGJvdW5kYXJ5IGNvbnN0YW50cyxcbi8vIGltcG9ydGluZyBUcmFuc2FjdGlvbiBjYXVzZXMgYSBjaXJjdWxhciBkZXBlbmRlbmN5XG5FQ1NpZ25hdHVyZS5wYXJzZVNjcmlwdFNpZ25hdHVyZSA9IGZ1bmN0aW9uIChidWZmZXIpIHtcbiAgdmFyIGhhc2hUeXBlID0gYnVmZmVyLnJlYWRVSW50OChidWZmZXIubGVuZ3RoIC0gMSk7XG4gIHZhciBoYXNoVHlwZU1vZCA9IGhhc2hUeXBlICYgfjB4ODA7XG5cbiAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKGhhc2hUeXBlTW9kID4gMHgwMCAmJiBoYXNoVHlwZU1vZCA8IDB4MDQsICdJbnZhbGlkIGhhc2hUeXBlJyk7XG5cbiAgcmV0dXJuIHtcbiAgICBzaWduYXR1cmU6IEVDU2lnbmF0dXJlLmZyb21ERVIoYnVmZmVyLnNsaWNlKDAsIC0xKSksXG4gICAgaGFzaFR5cGU6IGhhc2hUeXBlXG4gIH07XG59O1xuXG4vLyBFeHBvcnQgb3BlcmF0aW9uc1xuRUNTaWduYXR1cmUucHJvdG90eXBlLnRvQ29tcGFjdCA9IGZ1bmN0aW9uIHRvQ29tcGFjdChpLCBjb21wcmVzc2VkKSB7XG4gIGlmIChjb21wcmVzc2VkKSB7XG4gICAgaSArPSA0O1xuICB9XG5cbiAgaSArPSAyNztcblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDY1KTtcbiAgYnVmZmVyLndyaXRlVUludDgoaSwgMCk7XG5cbiAgdGhpcy5yLnRvQnVmZmVyKDMyKS5jb3B5KGJ1ZmZlciwgMSk7XG4gIHRoaXMucy50b0J1ZmZlcigzMikuY29weShidWZmZXIsIDMzKTtcblxuICByZXR1cm4gYnVmZmVyO1xufTtcblxuRUNTaWduYXR1cmUucHJvdG90eXBlLnRvREVSID0gZnVuY3Rpb24gdG9ERVIoKSB7XG4gIHZhciByQmEgPSB0aGlzLnIudG9ERVJJbnRlZ2VyKCk7XG4gIHZhciBzQmEgPSB0aGlzLnMudG9ERVJJbnRlZ2VyKCk7XG5cbiAgdmFyIHNlcXVlbmNlID0gW107XG5cbiAgLy8gSU5URUdFUlxuICBzZXF1ZW5jZS5wdXNoKDB4MDIsIHJCYS5sZW5ndGgpO1xuICBzZXF1ZW5jZSA9IHNlcXVlbmNlLmNvbmNhdChyQmEpO1xuXG4gIC8vIElOVEVHRVJcbiAgc2VxdWVuY2UucHVzaCgweDAyLCBzQmEubGVuZ3RoKTtcbiAgc2VxdWVuY2UgPSBzZXF1ZW5jZS5jb25jYXQoc0JhKTtcblxuICAvLyBTRVFVRU5DRVxuICBzZXF1ZW5jZS51bnNoaWZ0KDB4MzAsIHNlcXVlbmNlLmxlbmd0aCk7XG5cbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNlcXVlbmNlKTtcbn07XG5cbkVDU2lnbmF0dXJlLnByb3RvdHlwZS50b1NjcmlwdFNpZ25hdHVyZSA9IGZ1bmN0aW9uIHRvU2NyaXB0U2lnbmF0dXJlKGhhc2hUeXBlKSB7XG4gIHZhciBoYXNoVHlwZUJ1ZmZlciA9IEJ1ZmZlci5hbGxvYygxKTtcbiAgaGFzaFR5cGVCdWZmZXIud3JpdGVVSW50OChoYXNoVHlwZSwgMCk7XG5cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW3RoaXMudG9ERVIoKSwgaGFzaFR5cGVCdWZmZXJdKTtcbn07XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEVDU2lnbmF0dXJlO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5kZWZhdWx0ID0gZW5mb3JjZTtcblxuZnVuY3Rpb24gZ2V0TmFtZShmbikge1xuICAvLyBXaHkgbm90IGZuLm5hbWU6IGh0dHBzOi8va2FuZ2F4LmdpdGh1Yi5pby9jb21wYXQtdGFibGUvZXM2LyNmdW5jdGlvbl9uYW1lX3Byb3BlcnR5XG4gIHZhciBtYXRjaCA9IGZuLnRvU3RyaW5nKCkubWF0Y2goL2Z1bmN0aW9uICguKj8pXFwoLyk7XG4gIHJldHVybiBtYXRjaCA/IG1hdGNoWzFdIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gZW5mb3JjZSh0eXBlLCB2YWx1ZSkge1xuICAvLyBDb3BpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vYml0Y29pbmpzL2JpdGNvaW5qcy1saWJcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgJ0J1ZmZlcic6XG4gICAgICB7XG4gICAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlICdOdW1iZXInOlxuICAgICAge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIGlmIChnZXROYW1lKHZhbHVlLmNvbnN0cnVjdG9yKSA9PT0gZ2V0TmFtZSh0eXBlKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgJyArIChnZXROYW1lKHR5cGUpIHx8IHR5cGUpICsgJywgZ290ICcgKyB2YWx1ZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLnJpcGVtZDE2MCA9IGV4cG9ydHMuSG1hY1NIQTI1NiA9IGV4cG9ydHMuc2hhNTEyID0gZXhwb3J0cy5zaGEyNTYgPSBleHBvcnRzLnNoYTEgPSB1bmRlZmluZWQ7XG5cbnZhciBfY3JlYXRlSGFzaCA9IHJlcXVpcmUoNDEpO1xuXG52YXIgX2NyZWF0ZUhhc2gyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfY3JlYXRlSGFzaCk7XG5cbnZhciBfY3JlYXRlSG1hYyA9IHJlcXVpcmUoNDMpO1xuXG52YXIgX2NyZWF0ZUhtYWMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfY3JlYXRlSG1hYyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8qKiBAYXJnIHtzdHJpbmd8QnVmZmVyfSBkYXRhXG4gICAgQGFyZyB7c3RyaW5nfSBbZGlnZXN0ID0gbnVsbF0gLSAnaGV4JywgJ2JpbmFyeScgb3IgJ2Jhc2U2NCdcbiAgICBAcmV0dXJuIHtzdHJpbmd8QnVmZmVyfSAtIEJ1ZmZlciB3aGVuIGRpZ2VzdCBpcyBudWxsLCBvciBzdHJpbmdcbiovXG5mdW5jdGlvbiBzaGExKGRhdGEsIGVuY29kaW5nKSB7XG4gIHJldHVybiAoMCwgX2NyZWF0ZUhhc2gyLmRlZmF1bHQpKCdzaGExJykudXBkYXRlKGRhdGEpLmRpZ2VzdChlbmNvZGluZyk7XG59XG5cbi8qKiBAYXJnIHtzdHJpbmd8QnVmZmVyfSBkYXRhXG4gICAgQGFyZyB7c3RyaW5nfSBbZGlnZXN0ID0gbnVsbF0gLSAnaGV4JywgJ2JpbmFyeScgb3IgJ2Jhc2U2NCdcbiAgICBAcmV0dXJuIHtzdHJpbmd8QnVmZmVyfSAtIEJ1ZmZlciB3aGVuIGRpZ2VzdCBpcyBudWxsLCBvciBzdHJpbmdcbiovXG5mdW5jdGlvbiBzaGEyNTYoZGF0YSwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuICgwLCBfY3JlYXRlSGFzaDIuZGVmYXVsdCkoJ3NoYTI1NicpLnVwZGF0ZShkYXRhKS5kaWdlc3QoZW5jb2RpbmcpO1xufVxuXG4vKiogQGFyZyB7c3RyaW5nfEJ1ZmZlcn0gZGF0YVxuICAgIEBhcmcge3N0cmluZ30gW2RpZ2VzdCA9IG51bGxdIC0gJ2hleCcsICdiaW5hcnknIG9yICdiYXNlNjQnXG4gICAgQHJldHVybiB7c3RyaW5nfEJ1ZmZlcn0gLSBCdWZmZXIgd2hlbiBkaWdlc3QgaXMgbnVsbCwgb3Igc3RyaW5nXG4qL1xuZnVuY3Rpb24gc2hhNTEyKGRhdGEsIGVuY29kaW5nKSB7XG4gIHJldHVybiAoMCwgX2NyZWF0ZUhhc2gyLmRlZmF1bHQpKCdzaGE1MTInKS51cGRhdGUoZGF0YSkuZGlnZXN0KGVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gSG1hY1NIQTI1NihidWZmZXIsIHNlY3JldCkge1xuICByZXR1cm4gKDAsIF9jcmVhdGVIbWFjMi5kZWZhdWx0KSgnc2hhMjU2Jywgc2VjcmV0KS51cGRhdGUoYnVmZmVyKS5kaWdlc3QoKTtcbn1cblxuZnVuY3Rpb24gcmlwZW1kMTYwKGRhdGEpIHtcbiAgcmV0dXJuICgwLCBfY3JlYXRlSGFzaDIuZGVmYXVsdCkoJ3JtZDE2MCcpLnVwZGF0ZShkYXRhKS5kaWdlc3QoKTtcbn1cblxuLy8gZnVuY3Rpb24gaGFzaDE2MChidWZmZXIpIHtcbi8vICAgcmV0dXJuIHJpcGVtZDE2MChzaGEyNTYoYnVmZmVyKSlcbi8vIH1cbi8vXG4vLyBmdW5jdGlvbiBoYXNoMjU2KGJ1ZmZlcikge1xuLy8gICByZXR1cm4gc2hhMjU2KHNoYTI1NihidWZmZXIpKVxuLy8gfVxuXG4vL1xuLy8gZnVuY3Rpb24gSG1hY1NIQTUxMihidWZmZXIsIHNlY3JldCkge1xuLy8gICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTUxMicsIHNlY3JldCkudXBkYXRlKGJ1ZmZlcikuZGlnZXN0KClcbi8vIH1cblxuZXhwb3J0cy5zaGExID0gc2hhMTtcbmV4cG9ydHMuc2hhMjU2ID0gc2hhMjU2O1xuZXhwb3J0cy5zaGE1MTIgPSBzaGE1MTI7XG5leHBvcnRzLkhtYWNTSEEyNTYgPSBIbWFjU0hBMjU2O1xuZXhwb3J0cy5yaXBlbWQxNjAgPSByaXBlbWQxNjA7IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2VjdXJ2ZSA9IHJlcXVpcmUoJ2VjdXJ2ZScpO1xuXG52YXIgX2Fzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xuXG52YXIgX2Fzc2VydDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnQpO1xuXG52YXIgX2JpZ2kgPSByZXF1aXJlKCdiaWdpJyk7XG5cbnZhciBfYmlnaTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9iaWdpKTtcblxudmFyIF9oYXNoMiA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG52YXIgX2VjZHNhID0gcmVxdWlyZSgnLi9lY2RzYScpO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoJy4vUHVibGljS2V5Jyk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9IC8qIGdsb2JhbCBCeXRlQnVmZmVyICovXG5cblxudmFyIHNlY3AyNTZrMSA9ICgwLCBfZWN1cnZlLmdldEN1cnZlQnlOYW1lKSgnc2VjcDI1NmsxJyk7XG5cbnZhciBTaWduYXR1cmUgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFNpZ25hdHVyZShyMSwgczEsIGkxKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNpZ25hdHVyZSk7XG5cbiAgICB0aGlzLnIgPSByMTtcbiAgICB0aGlzLnMgPSBzMTtcbiAgICB0aGlzLmkgPSBpMTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKHRoaXMuciAhPSBudWxsLCB0cnVlLCAnTWlzc2luZyBwYXJhbWV0ZXInKTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKHRoaXMucyAhPSBudWxsLCB0cnVlLCAnTWlzc2luZyBwYXJhbWV0ZXInKTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKHRoaXMuaSAhPSBudWxsLCB0cnVlLCAnTWlzc2luZyBwYXJhbWV0ZXInKTtcbiAgfVxuXG4gIFNpZ25hdHVyZS5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWYpIHtcbiAgICB2YXIgaSA9IHZvaWQgMDtcbiAgICB2YXIgciA9IHZvaWQgMDtcbiAgICB2YXIgcyA9IHZvaWQgMDtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGJ1Zi5sZW5ndGgsIDY1LCAnSW52YWxpZCBzaWduYXR1cmUgbGVuZ3RoJyk7XG4gICAgaSA9IGJ1Zi5yZWFkVUludDgoMCk7XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChpIC0gMjcsIGkgLSAyNyAmIDcsICdJbnZhbGlkIHNpZ25hdHVyZSBwYXJhbWV0ZXInKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIHIgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1Zi5zbGljZSgxLCAzMykpO1xuICAgIHMgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1Zi5zbGljZSgzMykpO1xuICAgIHJldHVybiBuZXcgU2lnbmF0dXJlKHIsIHMsIGkpO1xuICB9O1xuXG4gIFNpZ25hdHVyZS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiB0b0J1ZmZlcigpIHtcbiAgICB2YXIgYnVmID0gdm9pZCAwO1xuICAgIGJ1ZiA9IEJ1ZmZlci5hbGxvYyg2NSk7XG4gICAgYnVmLndyaXRlVUludDgodGhpcy5pLCAwKTtcbiAgICB0aGlzLnIudG9CdWZmZXIoMzIpLmNvcHkoYnVmLCAxKTtcbiAgICB0aGlzLnMudG9CdWZmZXIoMzIpLmNvcHkoYnVmLCAzMyk7XG4gICAgcmV0dXJuIGJ1ZjtcbiAgfTtcblxuICBTaWduYXR1cmUucHJvdG90eXBlLnJlY292ZXJQdWJsaWNLZXlGcm9tQnVmZmVyID0gZnVuY3Rpb24gcmVjb3ZlclB1YmxpY0tleUZyb21CdWZmZXIoYnVmZmVyKSB7XG4gICAgcmV0dXJuIHRoaXMucmVjb3ZlclB1YmxpY0tleSgoMCwgX2hhc2gyLnNoYTI1NikoYnVmZmVyKSk7XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEByZXR1cm4ge1B1YmxpY0tleX1cbiAgICAqL1xuXG5cbiAgU2lnbmF0dXJlLnByb3RvdHlwZS5yZWNvdmVyUHVibGljS2V5ID0gZnVuY3Rpb24gcmVjb3ZlclB1YmxpY0tleShzaGEyNTZfYnVmZmVyKSB7XG4gICAgdmFyIFEgPSB2b2lkIDA7XG4gICAgdmFyIGUgPSB2b2lkIDA7XG4gICAgdmFyIGkgPSB2b2lkIDA7XG4gICAgZSA9IF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoc2hhMjU2X2J1ZmZlcik7XG4gICAgaSA9IHRoaXMuaTtcbiAgICBpIC09IDI3O1xuICAgIGkgJj0gMzsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIFEgPSAoMCwgX2VjZHNhLnJlY292ZXJQdWJLZXkpKHNlY3AyNTZrMSwgZSwgdGhpcywgaSk7XG4gICAgcmV0dXJuIF9QdWJsaWNLZXkyLmRlZmF1bHQuZnJvbVBvaW50KFEpO1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBAcGFyYW0ge0J1ZmZlcn0gYnVmXG4gICAgICAgIEBwYXJhbSB7UHJpdmF0ZUtleX0gcHJpdmF0ZV9rZXlcbiAgICAgICAgQHJldHVybiB7U2lnbmF0dXJlfVxuICAgICovXG5cblxuICBTaWduYXR1cmUuc2lnbkJ1ZmZlciA9IGZ1bmN0aW9uIHNpZ25CdWZmZXIoYnVmLCBwcml2YXRlX2tleSkge1xuICAgIHZhciBfaGFzaCA9ICgwLCBfaGFzaDIuc2hhMjU2KShidWYpO1xuICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlclNoYTI1NihfaGFzaCwgcHJpdmF0ZV9rZXkpO1xuICB9O1xuXG4gIC8qKiBTaWduIGEgYnVmZmVyIG9mIGV4YWN0YWxseSAzMiBieXRlcyBpbiBzaXplIChzaGEyNTYodGV4dCkpXG4gICAgICAgIEBwYXJhbSB7QnVmZmVyfSBidWYgLSAzMiBieXRlcyBiaW5hcnlcbiAgICAgICAgQHBhcmFtIHtQcml2YXRlS2V5fSBwcml2YXRlX2tleVxuICAgICAgICBAcmV0dXJuIHtTaWduYXR1cmV9XG4gICAgKi9cblxuXG4gIFNpZ25hdHVyZS5zaWduQnVmZmVyU2hhMjU2ID0gZnVuY3Rpb24gc2lnbkJ1ZmZlclNoYTI1NihidWZfc2hhMjU2LCBwcml2YXRlX2tleSkge1xuICAgIGlmIChidWZfc2hhMjU2Lmxlbmd0aCAhPT0gMzIgfHwgIUJ1ZmZlci5pc0J1ZmZlcihidWZfc2hhMjU2KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdidWZfc2hhMjU2OiAzMiBieXRlIGJ1ZmZlciByZXF1cmVkJyk7XG4gICAgfVxuXG4gICAgdmFyIGRlciA9IHZvaWQgMDtcbiAgICB2YXIgZSA9IHZvaWQgMDtcbiAgICB2YXIgZWNzaWduYXR1cmUgPSB2b2lkIDA7XG4gICAgdmFyIGkgPSB2b2lkIDA7XG4gICAgdmFyIGxlblIgPSB2b2lkIDA7XG4gICAgdmFyIGxlblMgPSB2b2lkIDA7XG4gICAgdmFyIG5vbmNlID0gdm9pZCAwO1xuICAgIGkgPSBudWxsO1xuICAgIG5vbmNlID0gMDtcbiAgICBlID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcihidWZfc2hhMjU2KTtcblxuICAgIHZhciBsb29wID0gdHJ1ZTtcblxuICAgIHdoaWxlIChsb29wKSB7XG4gICAgICBlY3NpZ25hdHVyZSA9ICgwLCBfZWNkc2Euc2lnbikoc2VjcDI1NmsxLCBidWZfc2hhMjU2LCBwcml2YXRlX2tleS5kLCBub25jZSsrKTtcbiAgICAgIGRlciA9IGVjc2lnbmF0dXJlLnRvREVSKCk7XG4gICAgICBsZW5SID0gZGVyWzNdO1xuICAgICAgbGVuUyA9IGRlcls1ICsgbGVuUl07XG5cbiAgICAgIGlmIChsZW5SID09PSAzMiAmJiBsZW5TID09PSAzMikge1xuICAgICAgICBpID0gKDAsIF9lY2RzYS5jYWxjUHViS2V5UmVjb3ZlcnlQYXJhbSkoc2VjcDI1NmsxLCBlLCBlY3NpZ25hdHVyZSwgcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKS5RKTtcbiAgICAgICAgaSArPSA0OyAvLyBjb21wcmVzc2VkXG4gICAgICAgIGkgKz0gMjc7IC8vIGNvbXBhY3QgIC8vICAyNCBvciAyNyA6KCBmb3JjaW5nIG9kZC15IDJuZCBrZXkgY2FuZGlkYXRlKVxuICAgICAgICBsb29wID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAobm9uY2UgJSAxMCA9PT0gMCkge1xuICAgICAgICBjb25zb2xlLmxvZygnV0FSTjogJyArIG5vbmNlICsgJyBhdHRlbXB0cyB0byBmaW5kIGNhbm9uaWNhbCBzaWduYXR1cmUnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFNpZ25hdHVyZShlY3NpZ25hdHVyZS5yLCBlY3NpZ25hdHVyZS5zLCBpKTtcbiAgfTtcblxuICBTaWduYXR1cmUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24oc3RyaW5nLCBwcml2YXRlX2tleSkge1xuICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlcihCdWZmZXIuZnJvbShzdHJpbmcpLCBwcml2YXRlX2tleSk7XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEBwYXJhbSB7QnVmZmVyfSB1bi1oYXNoZWRcbiAgICAgICAgQHBhcmFtIHsuL1B1YmxpY0tleX1cbiAgICAgICAgQHJldHVybiB7Ym9vbGVhbn1cbiAgICAqL1xuXG5cbiAgU2lnbmF0dXJlLnByb3RvdHlwZS52ZXJpZnlCdWZmZXIgPSBmdW5jdGlvbiB2ZXJpZnlCdWZmZXIoYnVmLCBwdWJsaWNfa2V5KSB7XG4gICAgdmFyIF9oYXNoID0gKDAsIF9oYXNoMi5zaGEyNTYpKGJ1Zik7XG4gICAgcmV0dXJuIHRoaXMudmVyaWZ5SGFzaChfaGFzaCwgcHVibGljX2tleSk7XG4gIH07XG5cbiAgU2lnbmF0dXJlLnByb3RvdHlwZS52ZXJpZnlIYXNoID0gZnVuY3Rpb24gdmVyaWZ5SGFzaChoYXNoLCBwdWJsaWNfa2V5KSB7XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChoYXNoLmxlbmd0aCwgMzIsICdBIFNIQSAyNTYgc2hvdWxkIGJlIDMyIGJ5dGVzIGxvbmcsIGluc3RlYWQgZ290ICcgKyBoYXNoLmxlbmd0aCk7XG4gICAgcmV0dXJuICgwLCBfZWNkc2EudmVyaWZ5KShzZWNwMjU2azEsIGhhc2gsIHtcbiAgICAgIHI6IHRoaXMucixcbiAgICAgIHM6IHRoaXMuc1xuICAgIH0sIHB1YmxpY19rZXkuUSk7XG4gIH07XG5cbiAgLyogPEhFWD4gKi9cblxuICBTaWduYXR1cmUucHJvdG90eXBlLnRvQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uIHRvQnl0ZUJ1ZmZlcigpIHtcbiAgICB2YXIgYiA9IHZvaWQgMDtcbiAgICBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiKTtcbiAgICByZXR1cm4gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgfTtcblxuICBTaWduYXR1cmUuZnJvbUhleCA9IGZ1bmN0aW9uIGZyb21IZXgoaGV4KSB7XG4gICAgcmV0dXJuIFNpZ25hdHVyZS5mcm9tQnVmZmVyKEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpKTtcbiAgfTtcblxuICBTaWduYXR1cmUucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24gdG9IZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9CdWZmZXIoKS50b1N0cmluZygnaGV4Jyk7XG4gIH07XG5cbiAgU2lnbmF0dXJlLnNpZ25IZXggPSBmdW5jdGlvbiBzaWduSGV4KGhleCwgcHJpdmF0ZV9rZXkpIHtcbiAgICB2YXIgYnVmID0gdm9pZCAwO1xuICAgIGJ1ZiA9IEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpO1xuICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlcihidWYsIHByaXZhdGVfa2V5KTtcbiAgfTtcblxuICBTaWduYXR1cmUucHJvdG90eXBlLnZlcmlmeUhleCA9IGZ1bmN0aW9uIHZlcmlmeUhleChoZXgsIHB1YmxpY19rZXkpIHtcbiAgICB2YXIgYnVmID0gdm9pZCAwO1xuICAgIGJ1ZiA9IEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpO1xuICAgIHJldHVybiB0aGlzLnZlcmlmeUJ1ZmZlcihidWYsIHB1YmxpY19rZXkpO1xuICB9O1xuXG4gIHJldHVybiBTaWduYXR1cmU7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IFNpZ25hdHVyZTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHMuU2VyaWFsaXplclZhbGlkYXRpb24gPSBleHBvcnRzLnRlbXBsYXRlID0gZXhwb3J0cy5vcHMgPSBleHBvcnRzLnR5cGVzID0gZXhwb3J0cy5mcCA9IGV4cG9ydHMuU2VyaWFsaXplciA9IHVuZGVmaW5lZDtcblxudmFyIF9zZXJpYWxpemVyID0gcmVxdWlyZSgyNCk7XG5cbnZhciBfc2VyaWFsaXplcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zZXJpYWxpemVyKTtcblxudmFyIF9GYXN0UGFyc2VyID0gcmVxdWlyZSgyMCk7XG5cbnZhciBfRmFzdFBhcnNlcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9GYXN0UGFyc2VyKTtcblxudmFyIF90eXBlcyA9IHJlcXVpcmUoMjYpO1xuXG52YXIgX3R5cGVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3R5cGVzKTtcblxudmFyIF9vcGVyYXRpb25zID0gcmVxdWlyZSgyMyk7XG5cbnZhciBvcHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfb3BlcmF0aW9ucyk7XG5cbnZhciBfdGVtcGxhdGUgPSByZXF1aXJlKDI1KTtcblxudmFyIF90ZW1wbGF0ZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90ZW1wbGF0ZSk7XG5cbnZhciBfU2VyaWFsaXplclZhbGlkYXRpb24gPSByZXF1aXJlKDIxKTtcblxudmFyIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TZXJpYWxpemVyVmFsaWRhdGlvbik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gZWxzZSB7IHZhciBuZXdPYmogPSB7fTsgaWYgKG9iaiAhPSBudWxsKSB7IGZvciAodmFyIGtleSBpbiBvYmopIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIG5ld09ialtrZXldID0gb2JqW2tleV07IH0gfSBuZXdPYmouZGVmYXVsdCA9IG9iajsgcmV0dXJuIG5ld09iajsgfSB9XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmV4cG9ydHMuU2VyaWFsaXplciA9IF9zZXJpYWxpemVyMi5kZWZhdWx0O1xuZXhwb3J0cy5mcCA9IF9GYXN0UGFyc2VyMi5kZWZhdWx0O1xuZXhwb3J0cy50eXBlcyA9IF90eXBlczIuZGVmYXVsdDtcbmV4cG9ydHMub3BzID0gb3BzO1xuZXhwb3J0cy50ZW1wbGF0ZSA9IF90ZW1wbGF0ZTIuZGVmYXVsdDtcbmV4cG9ydHMuU2VyaWFsaXplclZhbGlkYXRpb24gPSBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQ7IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoJy4uLy4uL2VjYy9zcmMvUHVibGljS2V5Jyk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBGYXN0UGFyc2VyID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBGYXN0UGFyc2VyKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBGYXN0UGFyc2VyKTtcbiAgfVxuXG4gIEZhc3RQYXJzZXIuZml4ZWRfZGF0YSA9IGZ1bmN0aW9uIGZpeGVkX2RhdGEoYiwgbGVuLCBidWZmZXIpIHtcbiAgICBpZiAoIWIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGJ1ZmZlcikge1xuICAgICAgdmFyIGRhdGEgPSBidWZmZXIuc2xpY2UoMCwgbGVuKS50b1N0cmluZygnYmluYXJ5Jyk7XG4gICAgICBiLmFwcGVuZChkYXRhLCAnYmluYXJ5Jyk7XG4gICAgICB3aGlsZSAobGVuLS0gPiBkYXRhLmxlbmd0aCkge1xuICAgICAgICBiLndyaXRlVWludDgoMCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgbGVuKTtcbiAgICAgIGIuc2tpcChsZW4pO1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJfY29weS50b0JpbmFyeSgpLCAnYmluYXJ5Jyk7XG4gICAgfVxuICB9O1xuXG4gIEZhc3RQYXJzZXIucHVibGljX2tleSA9IGZ1bmN0aW9uIHB1YmxpY19rZXkoYiwgX3B1YmxpY19rZXkpIHtcbiAgICB2YXIgYnVmZmVyID0gdm9pZCAwO1xuICAgIGlmICghYikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoX3B1YmxpY19rZXkpIHtcbiAgICAgIGJ1ZmZlciA9IF9wdWJsaWNfa2V5LnRvQnVmZmVyKCk7XG4gICAgICBiLmFwcGVuZChidWZmZXIudG9TdHJpbmcoJ2JpbmFyeScpLCAnYmluYXJ5Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1ZmZlciA9IEZhc3RQYXJzZXIuZml4ZWRfZGF0YShiLCAzMyk7XG4gICAgICByZXR1cm4gX1B1YmxpY0tleTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1ZmZlcik7XG4gICAgfVxuICB9O1xuXG4gIEZhc3RQYXJzZXIucmlwZW1kMTYwID0gZnVuY3Rpb24gcmlwZW1kMTYwKGIsIF9yaXBlbWQpIHtcbiAgICBpZiAoIWIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKF9yaXBlbWQpIHtcbiAgICAgIEZhc3RQYXJzZXIuZml4ZWRfZGF0YShiLCAyMCwgX3JpcGVtZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBGYXN0UGFyc2VyLmZpeGVkX2RhdGEoYiwgMjApO1xuICAgIH1cbiAgfTtcblxuICBGYXN0UGFyc2VyLnNoYTI1NiA9IGZ1bmN0aW9uIHNoYTI1NihiLCBfc2hhKSB7XG4gICAgaWYgKCFiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChfc2hhKSB7XG4gICAgICBGYXN0UGFyc2VyLmZpeGVkX2RhdGEoYiwgMzIsIF9zaGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gRmFzdFBhcnNlci5maXhlZF9kYXRhKGIsIDMyKTtcbiAgICB9XG4gIH07XG5cbiAgRmFzdFBhcnNlci50aW1lX3BvaW50X3NlYyA9IGZ1bmN0aW9uIHRpbWVfcG9pbnRfc2VjKGIsIGVwb2NoKSB7XG4gICAgaWYgKGVwb2NoKSB7XG4gICAgICBlcG9jaCA9IE1hdGguY2VpbChlcG9jaCAvIDEwMDApO1xuICAgICAgYi53cml0ZUludDMyKGVwb2NoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXBvY2ggPSBiLnJlYWRJbnQzMigpOyAvLyBmYzo6dGltZV9wb2ludF9zZWNcbiAgICAgIHJldHVybiBuZXcgRGF0ZShlcG9jaCAqIDEwMDApO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gRmFzdFBhcnNlcjtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gRmFzdFBhcnNlcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG52YXIgX2J5dGVidWZmZXIgPSByZXF1aXJlKDM4KTtcblxudmFyIF9DaGFpblR5cGVzID0gcmVxdWlyZSgzKTtcblxudmFyIF9DaGFpblR5cGVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0NoYWluVHlwZXMpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgTUFYX1NBRkVfSU5UID0gOTAwNzE5OTI1NDc0MDk5MTtcbnZhciBNSU5fU0FGRV9JTlQgPSAtOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gICAgTW9zdCB2YWxpZGF0aW9ucyBhcmUgc2tpcHBlZCBhbmQgdGhlIHZhbHVlIHJldHVybmVkIHVuY2hhbmdlZCB3aGVuIGFuIGVtcHR5IHN0cmluZyxcbiAgICBudWxsLCBvciB1bmRlZmluZWQgaXMgZW5jb3VudGVyZWQgKGV4Y2VwdCBcInJlcXVpcmVkXCIpLlxuICAgIFZhbGlkYXRpb25zIHN1cHBvcnQgYSBzdHJpbmcgZm9ybWF0IGZvciBkZWFsaW5nIHdpdGggbGFyZ2UgbnVtYmVycy5cbiovXG52YXIgX215ID0ge1xuICBpc19lbXB0eTogZnVuY3Rpb24gaXNfZW1wdHkodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZDtcbiAgfSxcbiAgcmVxdWlyZWQ6IGZ1bmN0aW9uIHJlcXVpcmVkKHZhbHVlKSB7XG4gICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6ICcnO1xuXG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbHVlIHJlcXVpcmVkICcgKyBmaWVsZF9uYW1lICsgJyB8ICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICByZXF1aXJlX2xvbmc6IGZ1bmN0aW9uIHJlcXVpcmVfbG9uZyh2YWx1ZSkge1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnJztcblxuICAgIGlmICghX2J5dGVidWZmZXIuTG9uZy5pc0xvbmcodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvbmcgdmFsdWUgcmVxdWlyZWQgJyArIGZpZWxkX25hbWUgKyAnIHwgJyArIHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIHN0cmluZzogZnVuY3Rpb24gc3RyaW5nKHZhbHVlKSB7XG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc3RyaW5nIHJlcXVpcmVkOiAnICsgdmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgbnVtYmVyOiBmdW5jdGlvbiBudW1iZXIodmFsdWUpIHtcbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdudW1iZXIgcmVxdWlyZWQ6ICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICB3aG9sZV9udW1iZXI6IGZ1bmN0aW9uIHdob2xlX251bWJlcih2YWx1ZSkge1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnJztcblxuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGlmICgvXFwuLy50ZXN0KHZhbHVlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd3aG9sZSBudW1iZXIgcmVxdWlyZWQgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICB1bnNpZ25lZDogZnVuY3Rpb24gdW5zaWduZWQodmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBpZiAoLy0vLnRlc3QodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc2lnbmVkIHJlcXVpcmVkICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgaXNfZGlnaXRzOiBmdW5jdGlvbiBpc19kaWdpdHModmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuICgvXlswLTldKyQvLnRlc3QodmFsdWUpXG4gICAgKTtcbiAgfSxcbiAgdG9fbnVtYmVyOiBmdW5jdGlvbiB0b19udW1iZXIodmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLm5vX292ZXJmbG93NTModmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHZhciBpbnRfdmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgIH0oKTtcbiAgICByZXR1cm4gaW50X3ZhbHVlO1xuICB9LFxuICB0b19sb25nOiBmdW5jdGlvbiB0b19sb25nKHZhbHVlKSB7XG4gICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6ICcnO1xuXG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKF9ieXRlYnVmZmVyLkxvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHRoaXMubm9fb3ZlcmZsb3c2NCh2YWx1ZSwgZmllbGRfbmFtZSk7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgdmFsdWUgPSAnJyArIHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBfYnl0ZWJ1ZmZlci5Mb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICB9LFxuICB0b191bG9uZzogZnVuY3Rpb24gdG9fdWxvbmcodmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBpZiAoX2J5dGVidWZmZXIuTG9uZy5pc0xvbmcodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhpcy5ub19vdmVyZmxvdzY0KHZhbHVlLCBmaWVsZF9uYW1lLCB0cnVlKTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICB2YWx1ZSA9ICcnICsgdmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9ieXRlYnVmZmVyLkxvbmcuZnJvbVN0cmluZyh2YWx1ZSwgdHJ1ZSk7XG4gIH0sXG4gIHRvX3N0cmluZzogZnVuY3Rpb24gdG9fc3RyaW5nKHZhbHVlKSB7XG4gICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6ICcnO1xuXG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy5ub19vdmVyZmxvdzUzKHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICAgIHJldHVybiAnJyArIHZhbHVlO1xuICAgIH1cblxuICAgIGlmIChfYnl0ZWJ1ZmZlci5Mb25nLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcigndW5zdXBwb3J0ZWQgdHlwZSAnICsgZmllbGRfbmFtZSArICc6ICgnICsgKHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YodmFsdWUpKSArICcpICcgKyB2YWx1ZSk7XG4gIH0sXG4gIHJlcXVpcmVfdGVzdDogZnVuY3Rpb24gcmVxdWlyZV90ZXN0KHJlZ2V4LCB2YWx1ZSkge1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAnJztcblxuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGlmICghcmVnZXgudGVzdCh2YWx1ZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5tYXRjaGVkICcgKyByZWdleCArICcgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICByZXF1aXJlX21hdGNoOiBmdW5jdGlvbiByZXF1aXJlX21hdGNoKHJlZ2V4LCB2YWx1ZSkge1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAnJztcblxuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHZhciBtYXRjaCA9IHZhbHVlLm1hdGNoKHJlZ2V4KTtcblxuICAgIGlmIChtYXRjaCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bm1hdGNoZWQgJyArIHJlZ2V4ICsgJyAnICsgZmllbGRfbmFtZSArICcgJyArIHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWF0Y2g7XG4gIH0sXG4gIHJlcXVpcmVfb2JqZWN0X2lkOiBmdW5jdGlvbiByZXF1aXJlX29iamVjdF9pZCh2YWx1ZSwgZmllbGRfbmFtZSkge1xuICAgIHJldHVybiB0aGlzLnJlcXVpcmVfbWF0Y2goL14oWzAtOV0rKVxcLihbMC05XSspXFwuKFswLTldKykkLywgdmFsdWUsIGZpZWxkX25hbWUpO1xuICB9LFxuXG5cbiAgLy8gRG9lcyBub3Qgc3VwcG9ydCBvdmVyIDUzIGJpdHNcbiAgcmVxdWlyZV9yYW5nZTogZnVuY3Rpb24gcmVxdWlyZV9yYW5nZShtaW4sIG1heCwgdmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogJyc7XG5cbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgbnVtID0gdGhpcy50b19udW1iZXIodmFsdWUpO1xuXG4gICAgaWYgKG51bSA8IG1pbiB8fCBudW0gPiBtYXgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb3V0IG9mIHJhbmdlICcgKyB2YWx1ZSArICcgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICByZXF1aXJlX29iamVjdF90eXBlOiBmdW5jdGlvbiByZXF1aXJlX29iamVjdF90eXBlKCkge1xuICAgIHZhciByZXNlcnZlZF9zcGFjZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IDE7XG4gICAgdmFyIHR5cGUgPSBhcmd1bWVudHNbMV07XG4gICAgdmFyIHZhbHVlID0gYXJndW1lbnRzWzJdO1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiAnJztcblxuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHZhciBvYmplY3RfdHlwZSA9IF9DaGFpblR5cGVzMi5kZWZhdWx0Lm9iamVjdF90eXBlW3R5cGVdO1xuXG4gICAgaWYgKCFvYmplY3RfdHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG9iamVjdCB0eXBlICcgKyB0eXBlICsgJyAnICsgZmllbGRfbmFtZSArICcgJyArIHZhbHVlKTtcbiAgICB9XG5cbiAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKHJlc2VydmVkX3NwYWNlcyArICcuJyArIG9iamVjdF90eXBlICsgJy5bMC05XSskJyk7XG5cbiAgICBpZiAoIXJlLnRlc3QodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGluZyAnICsgdHlwZSArICcgaW4gZm9ybWF0ICcgKyAocmVzZXJ2ZWRfc3BhY2VzICsgJy4nICsgb2JqZWN0X3R5cGUgKyAnLlswLTldKyAnKSArICgnaW5zdGVhZCBvZiAnICsgdmFsdWUgKyAnICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIGdldF9pbnN0YW5jZTogZnVuY3Rpb24gZ2V0X2luc3RhbmNlKHJlc2VydmVfc3BhY2VzLCB0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSkge1xuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHRoaXMucmVxdWlyZV9vYmplY3RfdHlwZShyZXNlcnZlX3NwYWNlcywgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdCgnLicpWzJdKTtcbiAgfSxcbiAgcmVxdWlyZV9yZWxhdGl2ZV90eXBlOiBmdW5jdGlvbiByZXF1aXJlX3JlbGF0aXZlX3R5cGUodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMCwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgZ2V0X3JlbGF0aXZlX2luc3RhbmNlOiBmdW5jdGlvbiBnZXRfcmVsYXRpdmVfaW5zdGFuY2UodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMCwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdCgnLicpWzJdKTtcbiAgfSxcbiAgcmVxdWlyZV9wcm90b2NvbF90eXBlOiBmdW5jdGlvbiByZXF1aXJlX3Byb3RvY29sX3R5cGUodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMSwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgZ2V0X3Byb3RvY29sX2luc3RhbmNlOiBmdW5jdGlvbiBnZXRfcHJvdG9jb2xfaW5zdGFuY2UodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMSwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdCgnLicpWzJdKTtcbiAgfSxcbiAgZ2V0X3Byb3RvY29sX3R5cGU6IGZ1bmN0aW9uIGdldF9wcm90b2NvbF90eXBlKHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhpcy5yZXF1aXJlX29iamVjdF9pZCh2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgdmFyIHZhbHVlcyA9IHZhbHVlLnNwbGl0KCcuJyk7XG4gICAgcmV0dXJuIHRoaXMudG9fbnVtYmVyKHZhbHVlc1sxXSk7XG4gIH0sXG4gIGdldF9wcm90b2NvbF90eXBlX25hbWU6IGZ1bmN0aW9uIGdldF9wcm90b2NvbF90eXBlX25hbWUodmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgdHlwZV9pZCA9IHRoaXMuZ2V0X3Byb3RvY29sX3R5cGUodmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhfQ2hhaW5UeXBlczIuZGVmYXVsdC5vYmplY3RfdHlwZSlbdHlwZV9pZF07XG4gIH0sXG4gIHJlcXVpcmVfaW1wbGVtZW50YXRpb25fdHlwZTogZnVuY3Rpb24gcmVxdWlyZV9pbXBsZW1lbnRhdGlvbl90eXBlKHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgdGhpcy5yZXF1aXJlX29iamVjdF90eXBlKDIsIHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIGdldF9pbXBsZW1lbnRhdGlvbl9pbnN0YW5jZTogZnVuY3Rpb24gZ2V0X2ltcGxlbWVudGF0aW9uX2luc3RhbmNlKHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhpcy5yZXF1aXJlX29iamVjdF90eXBlKDIsIHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICByZXR1cm4gdGhpcy50b19udW1iZXIodmFsdWUuc3BsaXQoJy4nKVsyXSk7XG4gIH0sXG5cblxuICAvLyBzaWduZWQgLyB1bnNpZ25lZCBkZWNpbWFsXG4gIG5vX292ZXJmbG93NTM6IGZ1bmN0aW9uIG5vX292ZXJmbG93NTModmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgaWYgKHZhbHVlID4gTUFYX1NBRkVfSU5UIHx8IHZhbHVlIDwgTUlOX1NBRkVfSU5UKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignb3ZlcmZsb3cgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgdmFyIGludCA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG5cbiAgICAgIGlmIChpbnQgPiBNQVhfU0FGRV9JTlQgfHwgaW50IDwgTUlOX1NBRkVfSU5UKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignb3ZlcmZsb3cgJyArIGZpZWxkX25hbWUgKyAnICcgKyBpbnQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKF9ieXRlYnVmZmVyLkxvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgLy8gdHlwZW9mIHZhbHVlLnRvSW50KCkgaXMgJ251bWJlcidcbiAgICAgIHRoaXMubm9fb3ZlcmZsb3c1Myh2YWx1ZS50b0ludCgpLCBmaWVsZF9uYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3VwcG9ydGVkIHR5cGUgJyArIGZpZWxkX25hbWUgKyAnOiAoJyArICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHZhbHVlKSkgKyAnKSAnICsgdmFsdWUpO1xuICB9LFxuXG5cbiAgLy8gc2lnbmVkIC8gdW5zaWduZWQgd2hvbGUgbnVtYmVycyBvbmx5XG4gIG5vX292ZXJmbG93NjQ6IGZ1bmN0aW9uIG5vX292ZXJmbG93NjQodmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG4gICAgdmFyIHVuc2lnbmVkID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBmYWxzZTtcblxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL0xvbmcuanMvaXNzdWVzLzIwXG4gICAgaWYgKF9ieXRlYnVmZmVyLkxvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEJpZ0ludGVnZXIjaXNCaWdJbnRlZ2VyIGh0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG9jb2luanMvYmlnaS9pc3N1ZXMvMjBcbiAgICBpZiAodmFsdWUudCAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5ub19vdmVyZmxvdzY0KHZhbHVlLnRvU3RyaW5nKCksIGZpZWxkX25hbWUsIHVuc2lnbmVkKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyByZW1vdmUgbGVhZGluZyB6ZXJvcywgd2lsbCBjYXVzZSBhIGZhbHNlIHBvc2l0aXZlXG4gICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoL14wKy8sICcnKTtcblxuICAgICAgLy8gcmVtb3ZlIHRyYWlsaW5nIHplcm9zXG4gICAgICB3aGlsZSAoLzAkLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZygwLCB2YWx1ZS5sZW5ndGggLSAxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKC9cXC4kLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgZG90XG4gICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKDAsIHZhbHVlLmxlbmd0aCAtIDEpO1xuICAgICAgfVxuXG4gICAgICBpZiAodmFsdWUgPT09ICcnKSB7XG4gICAgICAgIHZhbHVlID0gJzAnO1xuICAgICAgfVxuXG4gICAgICB2YXIgbG9uZ19zdHJpbmcgPSBfYnl0ZWJ1ZmZlci5Mb25nLmZyb21TdHJpbmcodmFsdWUsIHVuc2lnbmVkKS50b1N0cmluZygpO1xuXG4gICAgICBpZiAobG9uZ19zdHJpbmcgIT09IHZhbHVlLnRyaW0oKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ292ZXJmbG93ICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGlmICh2YWx1ZSA+IE1BWF9TQUZFX0lOVCB8fCB2YWx1ZSA8IE1JTl9TQUZFX0lOVCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ292ZXJmbG93ICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bnN1cHBvcnRlZCB0eXBlICcgKyBmaWVsZF9uYW1lICsgJzogKCcgKyAodHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZih2YWx1ZSkpICsgJykgJyArIHZhbHVlKTtcbiAgfVxufTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gX215O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG4vKiogRXhjZXB0aW9uIG5lc3RpbmcuICAqL1xudmFyIEVycm9yV2l0aENhdXNlID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBFcnJvcldpdGhDYXVzZShtZXNzYWdlLCBjYXVzZSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFcnJvcldpdGhDYXVzZSk7XG5cbiAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuXG4gICAgaWYgKHR5cGVvZiBjYXVzZSAhPT0gJ3VuZGVmaW5lZCcgJiYgY2F1c2UgIT09IG51bGwgPyBjYXVzZS5tZXNzYWdlIDogdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLm1lc3NhZ2UgPSAnY2F1c2VcXHQnICsgY2F1c2UubWVzc2FnZSArICdcXHQnICsgdGhpcy5tZXNzYWdlO1xuICAgIH1cblxuICAgIHZhciBzdGFjayA9ICcnOyAvLyAobmV3IEVycm9yKS5zdGFja1xuXG4gICAgaWYgKHR5cGVvZiBjYXVzZSAhPT0gJ3VuZGVmaW5lZCcgJiYgY2F1c2UgIT09IG51bGwgPyBjYXVzZS5zdGFjayA6IHVuZGVmaW5lZCkge1xuICAgICAgc3RhY2sgPSAnY2F1c2VkIGJ5XFxuXFx0JyArIGNhdXNlLnN0YWNrICsgJ1xcdCcgKyBzdGFjaztcbiAgICB9XG5cbiAgICB0aGlzLnN0YWNrID0gdGhpcy5tZXNzYWdlICsgJ1xcbicgKyBzdGFjaztcbiAgfVxuXG4gIEVycm9yV2l0aENhdXNlLnRocm93ID0gZnVuY3Rpb24gX3Rocm93KG1lc3NhZ2UsIGNhdXNlKSB7XG4gICAgdmFyIG1zZyA9IG1lc3NhZ2U7XG5cbiAgICBpZiAodHlwZW9mIGNhdXNlICE9PSAndW5kZWZpbmVkJyAmJiBjYXVzZSAhPT0gbnVsbCA/IGNhdXNlLm1lc3NhZ2UgOiB1bmRlZmluZWQpIHtcbiAgICAgIG1zZyArPSAnXFx0IGNhdXNlOiAnICsgY2F1c2UubWVzc2FnZSArICcgJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNhdXNlICE9PSAndW5kZWZpbmVkJyAmJiBjYXVzZSAhPT0gbnVsbCA/IGNhdXNlLnN0YWNrIDogdW5kZWZpbmVkKSB7XG4gICAgICBtc2cgKz0gJ1xcbiBzdGFjazogJyArIGNhdXNlLnN0YWNrICsgJyAnO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICB9O1xuXG4gIHJldHVybiBFcnJvcldpdGhDYXVzZTtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gRXJyb3JXaXRoQ2F1c2U7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLnN0ZWFsdGhfbWVtb19kYXRhID0gZXhwb3J0cy5nbG9iYWxfYmV0dGluZ19zdGF0aXN0aWNzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9wb3NpdGlvbiA9IGV4cG9ydHMuYmV0ID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldCA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXAgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X3J1bGVzID0gZXhwb3J0cy5ldmVudCA9IGV4cG9ydHMuZXZlbnRfZ3JvdXAgPSBleHBvcnRzLnNwb3J0ID0gZXhwb3J0cy5zaWduZWRfdHJhbnNhY3Rpb24gPSBleHBvcnRzLnRyYW5zYWN0aW9uID0gZXhwb3J0cy5iZXRfYWRqdXN0ZWQgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X3VwZGF0ZSA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlID0gZXhwb3J0cy50b3VybmFtZW50X2xlYXZlID0gZXhwb3J0cy50b3VybmFtZW50X3BheW91dCA9IGV4cG9ydHMucGF5b3V0X3R5cGUgPSBleHBvcnRzLmJldF9jYW5jZWxlZCA9IGV4cG9ydHMuYmV0X2NhbmNlbCA9IGV4cG9ydHMuYmV0X21hdGNoZWQgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX2NhbmNlbF91bm1hdGNoZWRfYmV0cyA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWQgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmUgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X3Jlc29sdXRpb25fdHlwZSA9IGV4cG9ydHMuYmV0X3BsYWNlID0gZXhwb3J0cy5iZXRfdHlwZSA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfY3JlYXRlID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGUgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZSA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfcnVsZXNfY3JlYXRlID0gZXhwb3J0cy5ldmVudF91cGRhdGUgPSBleHBvcnRzLmV2ZW50X2NyZWF0ZSA9IGV4cG9ydHMuZXZlbnRfZ3JvdXBfdXBkYXRlID0gZXhwb3J0cy5ldmVudF9ncm91cF9jcmVhdGUgPSBleHBvcnRzLnNwb3J0X3VwZGF0ZSA9IGV4cG9ydHMuc3BvcnRfY3JlYXRlID0gZXhwb3J0cy5hc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb24gPSBleHBvcnRzLmFzc2V0X3VwZGF0ZV9kaXZpZGVuZCA9IGV4cG9ydHMuZGl2aWRlbmRfYXNzZXRfb3B0aW9ucyA9IGV4cG9ydHMuZ2FtZV9tb3ZlID0gZXhwb3J0cy5yb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X3JldmVhbCA9IGV4cG9ydHMucm9ja19wYXBlcl9zY2lzc29yc190aHJvd19jb21taXQgPSBleHBvcnRzLnJvY2tfcGFwZXJfc2Npc3NvcnNfZ2VzdHVyZSA9IGV4cG9ydHMudG91cm5hbWVudF9qb2luID0gZXhwb3J0cy50b3VybmFtZW50X2NyZWF0ZSA9IGV4cG9ydHMudG91cm5hbWVudF9vcHRpb25zID0gZXhwb3J0cy5yb2NrX3BhcGVyX3NjaXNzb3JzX2dhbWVfb3B0aW9ucyA9IGV4cG9ydHMuZmJhX2Rpc3RyaWJ1dGUgPSBleHBvcnRzLmFzc2V0X2NsYWltX2ZlZXMgPSBleHBvcnRzLmFzc2V0X3NldHRsZV9jYW5jZWwgPSBleHBvcnRzLnRyYW5zZmVyX2Zyb21fYmxpbmQgPSBleHBvcnRzLmJsaW5kX3RyYW5zZmVyID0gZXhwb3J0cy5ibGluZF9pbnB1dCA9IGV4cG9ydHMudHJhbnNmZXJfdG9fYmxpbmQgPSBleHBvcnRzLmJsaW5kX291dHB1dCA9IGV4cG9ydHMuc3RlYWx0aF9jb25maXJtYXRpb24gPSBleHBvcnRzLm92ZXJyaWRlX3RyYW5zZmVyID0gZXhwb3J0cy5iYWxhbmNlX2NsYWltID0gZXhwb3J0cy5hc3NlcnQgPSBleHBvcnRzLmJsb2NrX2lkX3ByZWRpY2F0ZSA9IGV4cG9ydHMuYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUgPSBleHBvcnRzLmFjY291bnRfbmFtZV9lcV9saXRfcHJlZGljYXRlID0gZXhwb3J0cy5jdXN0b20gPSBleHBvcnRzLndvcmtlcl9jcmVhdGUgPSBleHBvcnRzLmJ1cm5fd29ya2VyX2luaXRpYWxpemVyID0gZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd29ya2VyX2luaXRpYWxpemVyID0gZXhwb3J0cy5yZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyID0gZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXcgPSBleHBvcnRzLnZlc3RpbmdfYmFsYW5jZV9jcmVhdGUgPSBleHBvcnRzLmNkZF92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplciA9IGV4cG9ydHMubGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVycyA9IGV4cG9ydHMuY2hhaW5fcGFyYW1ldGVycyA9IGV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGUgPSBleHBvcnRzLmNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlID0gZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbSA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGUgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlID0gZXhwb3J0cy5wcm9wb3NhbF9kZWxldGUgPSBleHBvcnRzLnByb3Bvc2FsX3VwZGF0ZSA9IGV4cG9ydHMucHJvcG9zYWxfY3JlYXRlID0gZXhwb3J0cy5vcF93cmFwcGVyID0gZXhwb3J0cy53aXRuZXNzX3VwZGF0ZSA9IGV4cG9ydHMud2l0bmVzc19jcmVhdGUgPSBleHBvcnRzLmFzc2V0X3B1Ymxpc2hfZmVlZCA9IGV4cG9ydHMucHJpY2VfZmVlZCA9IGV4cG9ydHMuYXNzZXRfZ2xvYmFsX3NldHRsZSA9IGV4cG9ydHMuYXNzZXRfc2V0dGxlID0gZXhwb3J0cy5hc3NldF9mdW5kX2ZlZV9wb29sID0gZXhwb3J0cy5hc3NldF9yZXNlcnZlID0gZXhwb3J0cy5hc3NldF9pc3N1ZSA9IHVuZGVmaW5lZDtcbmV4cG9ydHMuYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfYml0YXNzZXQgPSBleHBvcnRzLmFzc2V0X3VwZGF0ZSA9IGV4cG9ydHMuYXNzZXRfY3JlYXRlID0gZXhwb3J0cy5iaXRhc3NldF9vcHRpb25zID0gZXhwb3J0cy5hc3NldF9vcHRpb25zID0gZXhwb3J0cy5wcmljZSA9IGV4cG9ydHMuYWNjb3VudF90cmFuc2ZlciA9IGV4cG9ydHMuYWNjb3VudF91cGdyYWRlID0gZXhwb3J0cy5hY2NvdW50X3doaXRlbGlzdCA9IGV4cG9ydHMuYWNjb3VudF91cGRhdGUgPSBleHBvcnRzLmFjY291bnRfY3JlYXRlID0gZXhwb3J0cy5hY2NvdW50X29wdGlvbnMgPSBleHBvcnRzLmF1dGhvcml0eSA9IGV4cG9ydHMuZmlsbF9vcmRlciA9IGV4cG9ydHMuY2FsbF9vcmRlcl91cGRhdGUgPSBleHBvcnRzLmxpbWl0X29yZGVyX2NhbmNlbCA9IGV4cG9ydHMubGltaXRfb3JkZXJfY3JlYXRlID0gZXhwb3J0cy50cmFuc2ZlciA9IGV4cG9ydHMubWVtb19kYXRhID0gZXhwb3J0cy5zaWduZWRfYmxvY2tfaGVhZGVyID0gZXhwb3J0cy5ibG9ja19oZWFkZXIgPSBleHBvcnRzLnNpZ25lZF9ibG9jayA9IGV4cG9ydHMucHJvY2Vzc2VkX3RyYW5zYWN0aW9uID0gZXhwb3J0cy5hc3NldCA9IGV4cG9ydHMudm9pZF9yZXN1bHQgPSBleHBvcnRzLmZlZV9zY2hlZHVsZSA9IGV4cG9ydHMuYmV0X2FkanVzdGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudG91cm5hbWVudF9sZWF2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLnRvdXJuYW1lbnRfcGF5b3V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuZ2FtZV9tb3ZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudG91cm5hbWVudF9qb2luX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudG91cm5hbWVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXRfY2FuY2VsZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXRfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYmV0X21hdGNoZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXRfcGxhY2Vfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5ldmVudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5ldmVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5ldmVudF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5ldmVudF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5zcG9ydF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5zcG9ydF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb25fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfZGl2aWRlbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5mYmFfZGlzdHJpYnV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X2NsYWltX2ZlZXNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudHJhbnNmZXJfZnJvbV9ibGluZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJsaW5kX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5vdmVycmlkZV90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJhbGFuY2VfY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NlcnRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jdXN0b21fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53b3JrZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudmVzdGluZ19iYWxhbmNlX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5wcm9wb3NhbF9kZWxldGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5wcm9wb3NhbF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5wcm9wb3NhbF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndpdG5lc3NfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfcHVibGlzaF9mZWVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfZ2xvYmFsX3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9yZXNlcnZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfYml0YXNzZXRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hY2NvdW50X3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYWNjb3VudF91cGdyYWRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hY2NvdW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFjY291bnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuZmlsbF9vcmRlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmNhbGxfb3JkZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMubGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMubGltaXRfb3JkZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5vcGVyYXRpb24gPSB1bmRlZmluZWQ7XG5cbnZhciBfdHlwZXMgPSByZXF1aXJlKDI2KTtcblxudmFyIF90eXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90eXBlcyk7XG5cbnZhciBfc2VyaWFsaXplciA9IHJlcXVpcmUoMjQpO1xuXG52YXIgX3NlcmlhbGl6ZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc2VyaWFsaXplcik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciB1aW50OCA9IF90eXBlczIuZGVmYXVsdC51aW50OCxcbiAgICB1aW50MTYgPSBfdHlwZXMyLmRlZmF1bHQudWludDE2LFxuICAgIHVpbnQzMiA9IF90eXBlczIuZGVmYXVsdC51aW50MzIsXG4gICAgaW50NjQgPSBfdHlwZXMyLmRlZmF1bHQuaW50NjQsXG4gICAgdWludDY0ID0gX3R5cGVzMi5kZWZhdWx0LnVpbnQ2NCxcbiAgICBzdHJpbmcgPSBfdHlwZXMyLmRlZmF1bHQuc3RyaW5nLFxuICAgIGJ5dGVzID0gX3R5cGVzMi5kZWZhdWx0LmJ5dGVzLFxuICAgIGJvb2wgPSBfdHlwZXMyLmRlZmF1bHQuYm9vbCxcbiAgICBhcnJheSA9IF90eXBlczIuZGVmYXVsdC5hcnJheSxcbiAgICBwcm90b2NvbF9pZF90eXBlID0gX3R5cGVzMi5kZWZhdWx0LnByb3RvY29sX2lkX3R5cGUsXG4gICAgb2JqZWN0X2lkX3R5cGUgPSBfdHlwZXMyLmRlZmF1bHQub2JqZWN0X2lkX3R5cGUsXG4gICAgdm90ZV9pZCA9IF90eXBlczIuZGVmYXVsdC52b3RlX2lkLFxuICAgIGltcGxlbWVudGF0aW9uX2lkX3R5cGUgPSBfdHlwZXMyLmRlZmF1bHQuaW1wbGVtZW50YXRpb25faWRfdHlwZSxcbiAgICBzdGF0aWNfdmFyaWFudCA9IF90eXBlczIuZGVmYXVsdC5zdGF0aWNfdmFyaWFudCxcbiAgICBtYXAgPSBfdHlwZXMyLmRlZmF1bHQubWFwLFxuICAgIHNldCA9IF90eXBlczIuZGVmYXVsdC5zZXQsXG4gICAgcHVibGljX2tleSA9IF90eXBlczIuZGVmYXVsdC5wdWJsaWNfa2V5LFxuICAgIGFkZHJlc3MgPSBfdHlwZXMyLmRlZmF1bHQuYWRkcmVzcyxcbiAgICB0aW1lX3BvaW50X3NlYyA9IF90eXBlczIuZGVmYXVsdC50aW1lX3BvaW50X3NlYyxcbiAgICBvcHRpb25hbCA9IF90eXBlczIuZGVmYXVsdC5vcHRpb25hbCxcbiAgICB2YXJpYW50X29iamVjdCA9IF90eXBlczIuZGVmYXVsdC52YXJpYW50X29iamVjdCxcbiAgICBlbnVtZXJhdGlvbiA9IF90eXBlczIuZGVmYXVsdC5lbnVtZXJhdGlvbixcbiAgICBzaGEyNTYgPSBfdHlwZXMyLmRlZmF1bHQuc2hhMjU2O1xuXG5cbnZhciBmdXR1cmVfZXh0ZW5zaW9ucyA9IF90eXBlczIuZGVmYXVsdC52b2lkO1xuXG4vKlxuV2hlbiB1cGRhdGluZyBnZW5lcmF0ZWQgY29kZVxuUmVwbGFjZTogIG9wZXJhdGlvbiA9IHN0YXRpY192YXJpYW50IFtcbndpdGg6ICAgICBvcGVyYXRpb24uc3Rfb3BlcmF0aW9ucyA9IFtcblxuRGVsZXRlOlxucHVibGljX2tleSA9IG5ldyBTZXJpYWxpemVyKFxuICAgIFwicHVibGljX2tleVwiXG4gICAga2V5X2RhdGE6IGJ5dGVzIDMzXG4pO1xuKi9cblxuZnVuY3Rpb24gU2VyaWFsaXplcihvcGVyYXRpb25fbmFtZSwgc2VyaWxpemF0aW9uX3R5cGVzX29iamVjdCkge1xuICByZXR1cm4gbmV3IF9zZXJpYWxpemVyMi5kZWZhdWx0KG9wZXJhdGlvbl9uYW1lLCBzZXJpbGl6YXRpb25fdHlwZXNfb2JqZWN0KTtcbn1cbi8vIFBsYWNlLWhvbGRlciwgdGhlaXIgYXJlIGRlcGVuZGVuY2llcyBvbiBcIm9wZXJhdGlvblwiIC4uIFRoZSBmaW5hbCBsaXN0IG9mXG4vLyBvcGVyYXRpb25zIGlzIG5vdCBhdmlhbGJsZSB1bnRpbCB0aGUgdmVyeSBlbmQgb2YgdGhlIGdlbmVyYXRlZCBjb2RlLlxuLy8gU2VlOiBvcGVyYXRpb24uc3Rfb3BlcmF0aW9ucyA9IC4uLlxuLy8gbW9kdWxlLmV4cG9ydHNbXCJvcGVyYXRpb25cIl0gPSBvcGVyYXRpb247XG5cbnZhciBvcGVyYXRpb24gPSBzdGF0aWNfdmFyaWFudCgpO1xuXG4vLyBDdXN0b20tdHlwZXMgZm9sbG93IEdlbmVyYXRlZCBjb2RlOlxuXG4vLyAjIyAgR2VuZXJhdGVkIGNvZGUgZm9sbG93c1xuLy8gIyBwcm9ncmFtcy9qc19vcGVyYXRpb25fc2VyaWFsaXplciA+IG5wbSBpIC1nIGRlY2FmZmVpbmF0ZVxuLy8gIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxudmFyIHRyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd0cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0LFxuICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMlxufSk7XG5cbnZhciBsaW1pdF9vcmRlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2xpbWl0X29yZGVyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGxpbWl0X29yZGVyX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignbGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgY2FsbF9vcmRlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2NhbGxfb3JkZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgZmlsbF9vcmRlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignZmlsbF9vcmRlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnKTtcblxudmFyIGFjY291bnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdhY2NvdW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGJhc2ljX2ZlZTogdWludDY0LFxuICBwcmVtaXVtX2ZlZTogdWludDY0LFxuICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMlxufSk7XG5cbnZhciBhY2NvdW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IGludDY0LFxuICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMlxufSk7XG5cbnZhciBhY2NvdW50X3doaXRlbGlzdF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IGludDY0XG59KTtcblxudmFyIGFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF91cGdyYWRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgbWVtYmVyc2hpcF9hbm51YWxfZmVlOiB1aW50NjQsXG4gIG1lbWJlcnNoaXBfbGlmZXRpbWVfZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYWNjb3VudF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGFzc2V0X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgc3ltYm9sMzogdWludDY0LFxuICBzeW1ib2w0OiB1aW50NjQsXG4gIGxvbmdfc3ltYm9sOiB1aW50NjQsXG4gIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIGFzc2V0X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjQsXG4gIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIGFzc2V0X3VwZGF0ZV9iaXRhc3NldF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBhc3NldF9pc3N1ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgYXNzZXRfcmVzZXJ2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfcmVzZXJ2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGFzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBhc3NldF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBhc3NldF9wdWJsaXNoX2ZlZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3B1Ymxpc2hfZmVlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIHdpdG5lc3NfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd3aXRuZXNzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIHdpdG5lc3NfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd3aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogaW50NjRcbn0pO1xuXG52YXIgcHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdwcm9wb3NhbF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgcHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdwcm9wb3NhbF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgcHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdwcm9wb3NhbF9kZWxldGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjQsXG4gIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIHdpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdjb21taXR0ZWVfbWVtYmVyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIHZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3Zlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXdfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3Zlc3RpbmdfYmFsYW5jZV93aXRoZHJhd19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIHdvcmtlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3dvcmtlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBjdXN0b21fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2N1c3RvbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0LFxuICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMlxufSk7XG5cbnZhciBhc3NlcnRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2VydF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGJhbGFuY2VfY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2JhbGFuY2VfY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJyk7XG5cbnZhciBvdmVycmlkZV90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignb3ZlcnJpZGVfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgdHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zZmVyX3RvX2JsaW5kX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjQsXG4gIHByaWNlX3Blcl9vdXRwdXQ6IHVpbnQzMlxufSk7XG5cbnZhciBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmxpbmRfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX291dHB1dDogdWludDMyXG59KTtcblxudmFyIHRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBhc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycpO1xuXG52YXIgYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdmYmFfZGlzdHJpYnV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7fSk7XG5cbnZhciBhc3NldF91cGRhdGVfZGl2aWRlbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZV9kaXZpZGVuZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGFzc2V0X2RpdmlkZW5kX2Rpc3RyaWJ1dGlvbl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfZGl2aWRlbmRfZGlzdHJpYnV0aW9uX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZGlzdHJpYnV0aW9uX2Jhc2VfZmVlOiB1aW50NjQsXG4gIGRpc3RyaWJ1dGlvbl9mZWVfcGVyX2hvbGRlcjogdWludDMyXG59KTtcblxudmFyIHNwb3J0X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignc3BvcnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgc3BvcnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdzcG9ydF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBldmVudF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2V2ZW50X2dyb3VwX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGV2ZW50X2dyb3VwX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignZXZlbnRfZ3JvdXBfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgZXZlbnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdldmVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBldmVudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2V2ZW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X3J1bGVzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfcnVsZXNfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfcnVsZXNfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X2dyb3VwX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYmV0X3BsYWNlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXRfcGxhY2Vfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycpO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfY2FuY2VsX3VubWF0Y2hlZF9iZXRzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBiZXRfbWF0Y2hlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmV0X21hdGNoZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJyk7XG5cbnZhciBiZXRfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXRfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYmV0X2NhbmNlbGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXRfY2FuY2VsZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJyk7XG5cbnZhciB0b3VybmFtZW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcigndG91cm5hbWVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IGludDY0XG59KTtcblxudmFyIHRvdXJuYW1lbnRfam9pbl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcigndG91cm5hbWVudF9qb2luX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiBpbnQ2NFxufSk7XG5cbnZhciBnYW1lX21vdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2dhbWVfbW92ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogaW50NjRcbn0pO1xuXG52YXIgdG91cm5hbWVudF9wYXlvdXRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3RvdXJuYW1lbnRfcGF5b3V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycpO1xuXG52YXIgdG91cm5hbWVudF9sZWF2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcigndG91cm5hbWVudF9sZWF2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogaW50NjRcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGJldF9hZGp1c3RlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmV0X2FkanVzdGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycpO1xuXG52YXIgZmVlX3BhcmFtZXRlcnMgPSBzdGF0aWNfdmFyaWFudChbdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBsaW1pdF9vcmRlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBsaW1pdF9vcmRlcl9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBjYWxsX29yZGVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGZpbGxfb3JkZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFjY291bnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X3VwZ3JhZGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9yZXNlcnZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfZnVuZF9mZWVfcG9vbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9wdWJsaXNoX2ZlZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRuZXNzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHdpdG5lc3NfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHdpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXdfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3b3JrZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYmFsYW5jZV9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIG92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgdHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgdG91cm5hbWVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB0b3VybmFtZW50X2pvaW5fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBnYW1lX21vdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF91cGRhdGVfZGl2aWRlbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb25fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB0b3VybmFtZW50X3BheW91dF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHRvdXJuYW1lbnRfbGVhdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBzcG9ydF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBzcG9ydF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBldmVudF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBldmVudF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBldmVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBldmVudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXRfcGxhY2Vfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXRfYWRqdXN0ZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXRfbWF0Y2hlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGJldF9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXRfY2FuY2VsZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXG4vLyBNaXNzaW5nIGV2ZW50X3VwZGF0ZV9zdGF0dXNcbl0pO1xuXG52YXIgZmVlX3NjaGVkdWxlID0gbmV3IFNlcmlhbGl6ZXIoJ2ZlZV9zY2hlZHVsZScsIHtcbiAgcGFyYW1ldGVyczogc2V0KGZlZV9wYXJhbWV0ZXJzKSxcbiAgc2NhbGU6IHVpbnQzMlxufSk7XG5cbnZhciB2b2lkX3Jlc3VsdCA9IG5ldyBTZXJpYWxpemVyKCd2b2lkX3Jlc3VsdCcpO1xuXG52YXIgYXNzZXQgPSBuZXcgU2VyaWFsaXplcignYXNzZXQnLCB7XG4gIGFtb3VudDogaW50NjQsXG4gIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpXG59KTtcblxudmFyIG9wZXJhdGlvbl9yZXN1bHQgPSBzdGF0aWNfdmFyaWFudChbdm9pZF9yZXN1bHQsIG9iamVjdF9pZF90eXBlLCBhc3NldF0pO1xuXG52YXIgcHJvY2Vzc2VkX3RyYW5zYWN0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ3Byb2Nlc3NlZF90cmFuc2FjdGlvbicsIHtcbiAgcmVmX2Jsb2NrX251bTogdWludDE2LFxuICByZWZfYmxvY2tfcHJlZml4OiB1aW50MzIsXG4gIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICBvcGVyYXRpb25zOiBhcnJheShvcGVyYXRpb24pLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICBzaWduYXR1cmVzOiBhcnJheShieXRlcyg2NSkpLFxuICBvcGVyYXRpb25fcmVzdWx0czogYXJyYXkob3BlcmF0aW9uX3Jlc3VsdClcbn0pO1xuXG52YXIgc2lnbmVkX2Jsb2NrID0gbmV3IFNlcmlhbGl6ZXIoJ3NpZ25lZF9ibG9jaycsIHtcbiAgcHJldmlvdXM6IGJ5dGVzKDIwKSxcbiAgdGltZXN0YW1wOiB0aW1lX3BvaW50X3NlYyxcbiAgd2l0bmVzczogcHJvdG9jb2xfaWRfdHlwZSgnd2l0bmVzcycpLFxuICBuZXh0X3NlY3JldF9oYXNoOiBieXRlcygyMCksXG4gIHByZXZpb3VzX3NlY3JldDogYnl0ZXMoMjApLFxuICB0cmFuc2FjdGlvbl9tZXJrbGVfcm9vdDogYnl0ZXMoMjApLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICB3aXRuZXNzX3NpZ25hdHVyZTogYnl0ZXMoNjUpLFxuICB0cmFuc2FjdGlvbnM6IGFycmF5KHByb2Nlc3NlZF90cmFuc2FjdGlvbilcbn0pO1xuXG52YXIgYmxvY2tfaGVhZGVyID0gbmV3IFNlcmlhbGl6ZXIoJ2Jsb2NrX2hlYWRlcicsIHtcbiAgcHJldmlvdXM6IGJ5dGVzKDIwKSxcbiAgdGltZXN0YW1wOiB0aW1lX3BvaW50X3NlYyxcbiAgd2l0bmVzczogcHJvdG9jb2xfaWRfdHlwZSgnd2l0bmVzcycpLFxuICBuZXh0X3NlY3JldF9oYXNoOiBieXRlcygyMCksXG4gIHByZXZpb3VzX3NlY3JldDogYnl0ZXMoMjApLFxuICB0cmFuc2FjdGlvbl9tZXJrbGVfcm9vdDogYnl0ZXMoMjApLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIHNpZ25lZF9ibG9ja19oZWFkZXIgPSBuZXcgU2VyaWFsaXplcignc2lnbmVkX2Jsb2NrX2hlYWRlcicsIHtcbiAgcHJldmlvdXM6IGJ5dGVzKDIwKSxcbiAgdGltZXN0YW1wOiB0aW1lX3BvaW50X3NlYyxcbiAgd2l0bmVzczogcHJvdG9jb2xfaWRfdHlwZSgnd2l0bmVzcycpLFxuICBuZXh0X3NlY3JldF9oYXNoOiBieXRlcygyMCksXG4gIHByZXZpb3VzX3NlY3JldDogYnl0ZXMoMjApLFxuICB0cmFuc2FjdGlvbl9tZXJrbGVfcm9vdDogYnl0ZXMoMjApLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICB3aXRuZXNzX3NpZ25hdHVyZTogYnl0ZXMoNjUpXG59KTtcblxudmFyIG1lbW9fZGF0YSA9IG5ldyBTZXJpYWxpemVyKCdtZW1vX2RhdGEnLCB7XG4gIGZyb206IHB1YmxpY19rZXksXG4gIHRvOiBwdWJsaWNfa2V5LFxuICBub25jZTogdWludDY0LFxuICBtZXNzYWdlOiBieXRlcygpXG59KTtcblxudmFyIHRyYW5zZmVyID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zZmVyJywge1xuICBmZWU6IGFzc2V0LFxuICBmcm9tOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHRvOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFtb3VudDogYXNzZXQsXG4gIG1lbW86IG9wdGlvbmFsKG1lbW9fZGF0YSksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgbGltaXRfb3JkZXJfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2xpbWl0X29yZGVyX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgc2VsbGVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFtb3VudF90b19zZWxsOiBhc3NldCxcbiAgbWluX3RvX3JlY2VpdmU6IGFzc2V0LFxuICBleHBpcmF0aW9uOiB0aW1lX3BvaW50X3NlYyxcbiAgZmlsbF9vcl9raWxsOiBib29sLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGxpbWl0X29yZGVyX2NhbmNlbCA9IG5ldyBTZXJpYWxpemVyKCdsaW1pdF9vcmRlcl9jYW5jZWwnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGZlZV9wYXlpbmdfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBvcmRlcjogcHJvdG9jb2xfaWRfdHlwZSgnbGltaXRfb3JkZXInKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBjYWxsX29yZGVyX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKCdjYWxsX29yZGVyX3VwZGF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZnVuZGluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGRlbHRhX2NvbGxhdGVyYWw6IGFzc2V0LFxuICBkZWx0YV9kZWJ0OiBhc3NldCxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBmaWxsX29yZGVyID0gbmV3IFNlcmlhbGl6ZXIoJ2ZpbGxfb3JkZXInLCB7XG4gIGZlZTogYXNzZXQsXG4gIG9yZGVyX2lkOiBvYmplY3RfaWRfdHlwZSxcbiAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBwYXlzOiBhc3NldCxcbiAgcmVjZWl2ZXM6IGFzc2V0XG59KTtcblxudmFyIGF1dGhvcml0eSA9IG5ldyBTZXJpYWxpemVyKCdhdXRob3JpdHknLCB7XG4gIHdlaWdodF90aHJlc2hvbGQ6IHVpbnQzMixcbiAgYWNjb3VudF9hdXRoczogbWFwKHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSwgdWludDE2KSxcbiAga2V5X2F1dGhzOiBtYXAocHVibGljX2tleSwgdWludDE2KSxcbiAgYWRkcmVzc19hdXRoczogbWFwKGFkZHJlc3MsIHVpbnQxNilcbn0pO1xuXG52YXIgYWNjb3VudF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoJ2FjY291bnRfb3B0aW9ucycsIHtcbiAgbWVtb19rZXk6IHB1YmxpY19rZXksXG4gIHZvdGluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIG51bV93aXRuZXNzOiB1aW50MTYsXG4gIG51bV9jb21taXR0ZWU6IHVpbnQxNixcbiAgdm90ZXM6IHNldCh2b3RlX2lkKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhY2NvdW50X2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKCdhY2NvdW50X2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgcmVnaXN0cmFyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHJlZmVycmVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHJlZmVycmVyX3BlcmNlbnQ6IHVpbnQxNixcbiAgbmFtZTogc3RyaW5nLFxuICBvd25lcjogYXV0aG9yaXR5LFxuICBhY3RpdmU6IGF1dGhvcml0eSxcbiAgb3B0aW9uczogYWNjb3VudF9vcHRpb25zLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFjY291bnRfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2FjY291bnRfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBhY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIG93bmVyOiBvcHRpb25hbChhdXRob3JpdHkpLFxuICBhY3RpdmU6IG9wdGlvbmFsKGF1dGhvcml0eSksXG4gIG5ld19vcHRpb25zOiBvcHRpb25hbChhY2NvdW50X29wdGlvbnMpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFjY291bnRfd2hpdGVsaXN0ID0gbmV3IFNlcmlhbGl6ZXIoJ2FjY291bnRfd2hpdGVsaXN0Jywge1xuICBmZWU6IGFzc2V0LFxuICBhdXRob3JpemluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFjY291bnRfdG9fbGlzdDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBuZXdfbGlzdGluZzogdWludDgsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYWNjb3VudF91cGdyYWRlID0gbmV3IFNlcmlhbGl6ZXIoJ2FjY291bnRfdXBncmFkZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgYWNjb3VudF90b191cGdyYWRlOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHVwZ3JhZGVfdG9fbGlmZXRpbWVfbWVtYmVyOiBib29sLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFjY291bnRfdHJhbnNmZXIgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF90cmFuc2ZlcicsIHtcbiAgZmVlOiBhc3NldCxcbiAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBuZXdfb3duZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBwcmljZSA9IG5ldyBTZXJpYWxpemVyKCdwcmljZScsIHtcbiAgYmFzZTogYXNzZXQsXG4gIHF1b3RlOiBhc3NldFxufSk7XG5cbnZhciBhc3NldF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X29wdGlvbnMnLCB7XG4gIG1heF9zdXBwbHk6IGludDY0LFxuICBtYXJrZXRfZmVlX3BlcmNlbnQ6IHVpbnQxNixcbiAgbWF4X21hcmtldF9mZWU6IGludDY0LFxuICBpc3N1ZXJfcGVybWlzc2lvbnM6IHVpbnQxNixcbiAgZmxhZ3M6IHVpbnQxNixcbiAgY29yZV9leGNoYW5nZV9yYXRlOiBwcmljZSxcbiAgd2hpdGVsaXN0X2F1dGhvcml0aWVzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgYmxhY2tsaXN0X2F1dGhvcml0aWVzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgd2hpdGVsaXN0X21hcmtldHM6IHNldChwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpKSxcbiAgYmxhY2tsaXN0X21hcmtldHM6IHNldChwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpKSxcbiAgZGVzY3JpcHRpb246IHN0cmluZyxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiaXRhc3NldF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoJ2JpdGFzc2V0X29wdGlvbnMnLCB7XG4gIGZlZWRfbGlmZXRpbWVfc2VjOiB1aW50MzIsXG4gIG1pbmltdW1fZmVlZHM6IHVpbnQ4LFxuICBmb3JjZV9zZXR0bGVtZW50X2RlbGF5X3NlYzogdWludDMyLFxuICBmb3JjZV9zZXR0bGVtZW50X29mZnNldF9wZXJjZW50OiB1aW50MTYsXG4gIG1heGltdW1fZm9yY2Vfc2V0dGxlbWVudF92b2x1bWU6IHVpbnQxNixcbiAgc2hvcnRfYmFja2luZ19hc3NldDogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfY3JlYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgc3ltYm9sOiBzdHJpbmcsXG4gIHByZWNpc2lvbjogdWludDgsXG4gIGNvbW1vbl9vcHRpb25zOiBhc3NldF9vcHRpb25zLFxuICBiaXRhc3NldF9vcHRzOiBvcHRpb25hbChiaXRhc3NldF9vcHRpb25zKSxcbiAgaXNfcHJlZGljdGlvbl9tYXJrZXQ6IGJvb2wsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgbmV3X2lzc3Vlcjogb3B0aW9uYWwocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgbmV3X29wdGlvbnM6IGFzc2V0X29wdGlvbnMsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2JpdGFzc2V0ID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZV9iaXRhc3NldCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgbmV3X29wdGlvbnM6IGJpdGFzc2V0X29wdGlvbnMsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2VycycsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgbmV3X2ZlZWRfcHJvZHVjZXJzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF9pc3N1ZSA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF9pc3N1ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX2lzc3VlOiBhc3NldCxcbiAgaXNzdWVfdG9fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBtZW1vOiBvcHRpb25hbChtZW1vX2RhdGEpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X3Jlc2VydmUgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfcmVzZXJ2ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgcGF5ZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50X3RvX3Jlc2VydmU6IGFzc2V0LFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X2Z1bmRfZmVlX3Bvb2wgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfZnVuZF9mZWVfcG9vbCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgZnJvbV9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpLFxuICBhbW91bnQ6IGludDY0LFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X3NldHRsZSA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF9zZXR0bGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGFjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50OiBhc3NldCxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF9nbG9iYWxfc2V0dGxlID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X2dsb2JhbF9zZXR0bGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGlzc3VlcjogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBhc3NldF90b19zZXR0bGU6IHByb3RvY29sX2lkX3R5cGUoJ2Fzc2V0JyksXG4gIHNldHRsZV9wcmljZTogcHJpY2UsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgcHJpY2VfZmVlZCA9IG5ldyBTZXJpYWxpemVyKCdwcmljZV9mZWVkJywge1xuICBzZXR0bGVtZW50X3ByaWNlOiBwcmljZSxcbiAgbWFpbnRlbmFuY2VfY29sbGF0ZXJhbF9yYXRpbzogdWludDE2LFxuICBtYXhpbXVtX3Nob3J0X3NxdWVlemVfcmF0aW86IHVpbnQxNixcbiAgY29yZV9leGNoYW5nZV9yYXRlOiBwcmljZVxufSk7XG5cbnZhciBhc3NldF9wdWJsaXNoX2ZlZWQgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfcHVibGlzaF9mZWVkJywge1xuICBmZWU6IGFzc2V0LFxuICBwdWJsaXNoZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYXNzZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2Fzc2V0JyksXG4gIGZlZWQ6IHByaWNlX2ZlZWQsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgd2l0bmVzc19jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignd2l0bmVzc19jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIHdpdG5lc3NfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICB1cmw6IHN0cmluZyxcbiAgYmxvY2tfc2lnbmluZ19rZXk6IHB1YmxpY19rZXksXG4gIGluaXRpYWxfc2VjcmV0OiBieXRlcygyMClcbn0pO1xuXG52YXIgd2l0bmVzc191cGRhdGUgPSBuZXcgU2VyaWFsaXplcignd2l0bmVzc191cGRhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIHdpdG5lc3M6IHByb3RvY29sX2lkX3R5cGUoJ3dpdG5lc3MnKSxcbiAgd2l0bmVzc19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIG5ld191cmw6IG9wdGlvbmFsKHN0cmluZyksXG4gIG5ld19zaWduaW5nX2tleTogb3B0aW9uYWwocHVibGljX2tleSksXG4gIG5ld19pbml0aWFsX3NlY3JldDogb3B0aW9uYWwoYnl0ZXMoMjApKVxufSk7XG5cbnZhciBvcF93cmFwcGVyID0gbmV3IFNlcmlhbGl6ZXIoJ29wX3dyYXBwZXInLCB7XG4gIG9wOiBvcGVyYXRpb25cbn0pO1xuXG52YXIgcHJvcG9zYWxfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ3Byb3Bvc2FsX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZmVlX3BheWluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGV4cGlyYXRpb25fdGltZTogdGltZV9wb2ludF9zZWMsXG4gIHByb3Bvc2VkX29wczogYXJyYXkob3Bfd3JhcHBlciksXG4gIHJldmlld19wZXJpb2Rfc2Vjb25kczogb3B0aW9uYWwodWludDMyKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBwcm9wb3NhbF91cGRhdGUgPSBuZXcgU2VyaWFsaXplcigncHJvcG9zYWxfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBmZWVfcGF5aW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgcHJvcG9zYWw6IHByb3RvY29sX2lkX3R5cGUoJ3Byb3Bvc2FsJyksXG4gIGFjdGl2ZV9hcHByb3ZhbHNfdG9fYWRkOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgYWN0aXZlX2FwcHJvdmFsc190b19yZW1vdmU6IHNldChwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JykpLFxuICBvd25lcl9hcHByb3ZhbHNfdG9fYWRkOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgb3duZXJfYXBwcm92YWxzX3RvX3JlbW92ZTogc2V0KHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSksXG4gIGtleV9hcHByb3ZhbHNfdG9fYWRkOiBzZXQocHVibGljX2tleSksXG4gIGtleV9hcHByb3ZhbHNfdG9fcmVtb3ZlOiBzZXQocHVibGljX2tleSksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgcHJvcG9zYWxfZGVsZXRlID0gbmV3IFNlcmlhbGl6ZXIoJ3Byb3Bvc2FsX2RlbGV0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZmVlX3BheWluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHVzaW5nX293bmVyX2F1dGhvcml0eTogYm9vbCxcbiAgcHJvcG9zYWw6IHByb3RvY29sX2lkX3R5cGUoJ3Byb3Bvc2FsJyksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIHdpdGhkcmF3X2Zyb21fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBhdXRob3JpemVkX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgd2l0aGRyYXdhbF9saW1pdDogYXNzZXQsXG4gIHdpdGhkcmF3YWxfcGVyaW9kX3NlYzogdWludDMyLFxuICBwZXJpb2RzX3VudGlsX2V4cGlyYXRpb246IHVpbnQzMixcbiAgcGVyaW9kX3N0YXJ0X3RpbWU6IHRpbWVfcG9pbnRfc2VjXG59KTtcblxudmFyIHdpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ3dpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICB3aXRoZHJhd19mcm9tX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYXV0aG9yaXplZF9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHBlcm1pc3Npb25fdG9fdXBkYXRlOiBwcm90b2NvbF9pZF90eXBlKCd3aXRoZHJhd19wZXJtaXNzaW9uJyksXG4gIHdpdGhkcmF3YWxfbGltaXQ6IGFzc2V0LFxuICB3aXRoZHJhd2FsX3BlcmlvZF9zZWM6IHVpbnQzMixcbiAgcGVyaW9kX3N0YXJ0X3RpbWU6IHRpbWVfcG9pbnRfc2VjLFxuICBwZXJpb2RzX3VudGlsX2V4cGlyYXRpb246IHVpbnQzMlxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltID0gbmV3IFNlcmlhbGl6ZXIoJ3dpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW0nLCB7XG4gIGZlZTogYXNzZXQsXG4gIHdpdGhkcmF3X3Blcm1pc3Npb246IHByb3RvY29sX2lkX3R5cGUoJ3dpdGhkcmF3X3Blcm1pc3Npb24nKSxcbiAgd2l0aGRyYXdfZnJvbV9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHdpdGhkcmF3X3RvX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50X3RvX3dpdGhkcmF3OiBhc3NldCxcbiAgbWVtbzogb3B0aW9uYWwobWVtb19kYXRhKVxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSA9IG5ldyBTZXJpYWxpemVyKCd3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgd2l0aGRyYXdfZnJvbV9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGF1dGhvcml6ZWRfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICB3aXRoZHJhd2FsX3Blcm1pc3Npb246IHByb3RvY29sX2lkX3R5cGUoJ3dpdGhkcmF3X3Blcm1pc3Npb24nKVxufSk7XG5cbnZhciBjb21taXR0ZWVfbWVtYmVyX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKCdjb21taXR0ZWVfbWVtYmVyX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgY29tbWl0dGVlX21lbWJlcl9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHVybDogc3RyaW5nXG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2NvbW1pdHRlZV9tZW1iZXJfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBjb21taXR0ZWVfbWVtYmVyOiBwcm90b2NvbF9pZF90eXBlKCdjb21taXR0ZWVfbWVtYmVyJyksXG4gIGNvbW1pdHRlZV9tZW1iZXJfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBuZXdfdXJsOiBvcHRpb25hbChzdHJpbmcpXG59KTtcblxudmFyIGNoYWluX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignY2hhaW5fcGFyYW1ldGVycycsIHtcbiAgY3VycmVudF9mZWVzOiBmZWVfc2NoZWR1bGUsXG4gIGJsb2NrX2ludGVydmFsOiB1aW50OCxcbiAgbWFpbnRlbmFuY2VfaW50ZXJ2YWw6IHVpbnQzMixcbiAgbWFpbnRlbmFuY2Vfc2tpcF9zbG90czogdWludDgsXG4gIGNvbW1pdHRlZV9wcm9wb3NhbF9yZXZpZXdfcGVyaW9kOiB1aW50MzIsXG4gIG1heGltdW1fdHJhbnNhY3Rpb25fc2l6ZTogdWludDMyLFxuICBtYXhpbXVtX2Jsb2NrX3NpemU6IHVpbnQzMixcbiAgbWF4aW11bV90aW1lX3VudGlsX2V4cGlyYXRpb246IHVpbnQzMixcbiAgbWF4aW11bV9wcm9wb3NhbF9saWZldGltZTogdWludDMyLFxuICBtYXhpbXVtX2Fzc2V0X3doaXRlbGlzdF9hdXRob3JpdGllczogdWludDgsXG4gIG1heGltdW1fYXNzZXRfZmVlZF9wdWJsaXNoZXJzOiB1aW50OCxcbiAgbWF4aW11bV93aXRuZXNzX2NvdW50OiB1aW50MTYsXG4gIG1heGltdW1fY29tbWl0dGVlX2NvdW50OiB1aW50MTYsXG4gIG1heGltdW1fYXV0aG9yaXR5X21lbWJlcnNoaXA6IHVpbnQxNixcbiAgcmVzZXJ2ZV9wZXJjZW50X29mX2ZlZTogdWludDE2LFxuICBuZXR3b3JrX3BlcmNlbnRfb2ZfZmVlOiB1aW50MTYsXG4gIGxpZmV0aW1lX3JlZmVycmVyX3BlcmNlbnRfb2ZfZmVlOiB1aW50MTYsXG4gIGNhc2hiYWNrX3Zlc3RpbmdfcGVyaW9kX3NlY29uZHM6IHVpbnQzMixcbiAgY2FzaGJhY2tfdmVzdGluZ190aHJlc2hvbGQ6IGludDY0LFxuICBjb3VudF9ub25fbWVtYmVyX3ZvdGVzOiBib29sLFxuICBhbGxvd19ub25fbWVtYmVyX3doaXRlbGlzdHM6IGJvb2wsXG4gIHdpdG5lc3NfcGF5X3Blcl9ibG9jazogaW50NjQsXG4gIHdvcmtlcl9idWRnZXRfcGVyX2RheTogaW50NjQsXG4gIG1heF9wcmVkaWNhdGVfb3Bjb2RlOiB1aW50MTYsXG4gIGZlZV9saXF1aWRhdGlvbl90aHJlc2hvbGQ6IGludDY0LFxuICBhY2NvdW50c19wZXJfZmVlX3NjYWxlOiB1aW50MTYsXG4gIGFjY291bnRfZmVlX3NjYWxlX2JpdHNoaWZ0czogdWludDgsXG4gIG1heF9hdXRob3JpdHlfZGVwdGg6IHVpbnQ4LFxuICBtaW5fYmV0X211bHRpcGxpZXI6IHVpbnQzMixcbiAgbWF4X2JldF9tdWx0aXBsaWVyOiB1aW50MzIsXG4gIGJldHRpbmdfcmFrZV9mZWVfcGVyY2VudGFnZTogdWludDE2LFxuICBwZXJtaXR0ZWRfYmV0dGluZ19vZGRzX2luY3JlbWVudHM6IG1hcCh1aW50MzIsIHVpbnQzMiksXG4gIHdpdG5lc3Nfc2NoZWR1bGVfYWxnb3JpdGhtOiB1aW50OCxcbiAgbGl2ZV9iZXR0aW5nX2RlbGF5X3RpbWU6IHVpbnQxNixcbiAgbWluX3JvdW5kX2RlbGF5OiB1aW50MzIsXG4gIG1heF9yb3VuZF9kZWxheTogdWludDMyLFxuICBtaW5fdGltZV9wZXJfY29tbWl0X21vdmU6IHVpbnQzMixcbiAgbWF4X3RpbWVfcGVyX2NvbW1pdF9tb3ZlOiB1aW50MzIsXG4gIG1pbl90aW1lX3Blcl9yZXZlYWxfbW92ZTogdWludDMyLFxuICBtYXhfdGltZV9wZXJfcmV2ZWFsX21vdmU6IHVpbnQzMixcbiAgcmFrZV9mZWVfcGVyY2VudGFnZTogdWludDE2LFxuICBtYXhpbXVtX3JlZ2lzdHJhdGlvbl9kZWFkbGluZTogdWludDMyLFxuICBtYXhpbXVtX3BsYXllcnNfaW5fdG91cm5hbWVudDogdWludDE2LFxuICBtYXhpbXVtX3RvdXJuYW1lbnRfd2hpdGVsaXN0X2xlbmd0aDogdWludDE2LFxuICBtYXhpbXVtX3RvdXJuYW1lbnRfc3RhcnRfdGltZV9pbl9mdXR1cmU6IHVpbnQzMixcbiAgbWF4aW11bV90b3VybmFtZW50X3N0YXJ0X2RlbGF5OiB1aW50MzIsXG4gIG1heGltdW1fdG91cm5hbWVudF9udW1iZXJfb2Zfd2luczogdWludDE2LFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2NvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzJywge1xuICBmZWU6IGFzc2V0LFxuICBuZXdfcGFyYW1ldGVyczogY2hhaW5fcGFyYW1ldGVyc1xufSk7XG5cbnZhciBsaW5lYXJfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXIgPSBuZXcgU2VyaWFsaXplcignbGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyJywge1xuICBiZWdpbl90aW1lc3RhbXA6IHRpbWVfcG9pbnRfc2VjLFxuICB2ZXN0aW5nX2NsaWZmX3NlY29uZHM6IHVpbnQzMixcbiAgdmVzdGluZ19kdXJhdGlvbl9zZWNvbmRzOiB1aW50MzJcbn0pO1xuXG52YXIgY2RkX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXIoJ2NkZF92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplcicsIHtcbiAgc3RhcnRfY2xhaW06IHRpbWVfcG9pbnRfc2VjLFxuICB2ZXN0aW5nX3NlY29uZHM6IHVpbnQzMlxufSk7XG5cbnZhciB2ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplciA9IHN0YXRpY192YXJpYW50KFtsaW5lYXJfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXIsIGNkZF92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplcl0pO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKCd2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBjcmVhdG9yOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIG93bmVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFtb3VudDogYXNzZXQsXG4gIHBvbGljeTogdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXJcbn0pO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3ID0gbmV3IFNlcmlhbGl6ZXIoJ3Zlc3RpbmdfYmFsYW5jZV93aXRoZHJhdycsIHtcbiAgZmVlOiBhc3NldCxcbiAgdmVzdGluZ19iYWxhbmNlOiBwcm90b2NvbF9pZF90eXBlKCd2ZXN0aW5nX2JhbGFuY2UnKSxcbiAgb3duZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50OiBhc3NldFxufSk7XG5cbnZhciByZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXIoJ3JlZnVuZF93b3JrZXJfaW5pdGlhbGl6ZXInKTtcblxudmFyIHZlc3RpbmdfYmFsYW5jZV93b3JrZXJfaW5pdGlhbGl6ZXIgPSBuZXcgU2VyaWFsaXplcigndmVzdGluZ19iYWxhbmNlX3dvcmtlcl9pbml0aWFsaXplcicsIHtcbiAgcGF5X3Zlc3RpbmdfcGVyaW9kX2RheXM6IHVpbnQxNlxufSk7XG5cbnZhciBidXJuX3dvcmtlcl9pbml0aWFsaXplciA9IG5ldyBTZXJpYWxpemVyKCdidXJuX3dvcmtlcl9pbml0aWFsaXplcicpO1xuXG52YXIgd29ya2VyX2luaXRpYWxpemVyID0gc3RhdGljX3ZhcmlhbnQoW3JlZnVuZF93b3JrZXJfaW5pdGlhbGl6ZXIsIHZlc3RpbmdfYmFsYW5jZV93b3JrZXJfaW5pdGlhbGl6ZXIsIGJ1cm5fd29ya2VyX2luaXRpYWxpemVyXSk7XG5cbnZhciB3b3JrZXJfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ3dvcmtlcl9jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIG93bmVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHdvcmtfYmVnaW5fZGF0ZTogdGltZV9wb2ludF9zZWMsXG4gIHdvcmtfZW5kX2RhdGU6IHRpbWVfcG9pbnRfc2VjLFxuICBkYWlseV9wYXk6IGludDY0LFxuICBuYW1lOiBzdHJpbmcsXG4gIHVybDogc3RyaW5nLFxuICBpbml0aWFsaXplcjogd29ya2VyX2luaXRpYWxpemVyXG59KTtcblxudmFyIGN1c3RvbSA9IG5ldyBTZXJpYWxpemVyKCdjdXN0b20nLCB7XG4gIGZlZTogYXNzZXQsXG4gIHBheWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHJlcXVpcmVkX2F1dGhzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgaWQ6IHVpbnQxNixcbiAgZGF0YTogYnl0ZXMoKVxufSk7XG5cbnZhciBhY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZSA9IG5ldyBTZXJpYWxpemVyKCdhY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZScsIHtcbiAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBuYW1lOiBzdHJpbmdcbn0pO1xuXG52YXIgYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUnLCB7XG4gIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpLFxuICBzeW1ib2w6IHN0cmluZ1xufSk7XG5cbnZhciBibG9ja19pZF9wcmVkaWNhdGUgPSBuZXcgU2VyaWFsaXplcignYmxvY2tfaWRfcHJlZGljYXRlJywge1xuICBpZDogYnl0ZXMoMjApXG59KTtcblxudmFyIHByZWRpY2F0ZSA9IHN0YXRpY192YXJpYW50KFthY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZSwgYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUsIGJsb2NrX2lkX3ByZWRpY2F0ZV0pO1xuXG52YXIgYXNzZXJ0ID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2VydCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgZmVlX3BheWluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHByZWRpY2F0ZXM6IGFycmF5KHByZWRpY2F0ZSksXG4gIHJlcXVpcmVkX2F1dGhzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiYWxhbmNlX2NsYWltID0gbmV3IFNlcmlhbGl6ZXIoJ2JhbGFuY2VfY2xhaW0nLCB7XG4gIGZlZTogYXNzZXQsXG4gIGRlcG9zaXRfdG9fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBiYWxhbmNlX3RvX2NsYWltOiBwcm90b2NvbF9pZF90eXBlKCdiYWxhbmNlJyksXG4gIGJhbGFuY2Vfb3duZXJfa2V5OiBwdWJsaWNfa2V5LFxuICB0b3RhbF9jbGFpbWVkOiBhc3NldFxufSk7XG5cbnZhciBvdmVycmlkZV90cmFuc2ZlciA9IG5ldyBTZXJpYWxpemVyKCdvdmVycmlkZV90cmFuc2ZlcicsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGZyb206IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgdG86IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50OiBhc3NldCxcbiAgbWVtbzogb3B0aW9uYWwobWVtb19kYXRhKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBzdGVhbHRoX2NvbmZpcm1hdGlvbiA9IG5ldyBTZXJpYWxpemVyKCdzdGVhbHRoX2NvbmZpcm1hdGlvbicsIHtcbiAgb25lX3RpbWVfa2V5OiBwdWJsaWNfa2V5LFxuICB0bzogb3B0aW9uYWwocHVibGljX2tleSksXG4gIGVuY3J5cHRlZF9tZW1vOiBieXRlcygpXG59KTtcblxudmFyIGJsaW5kX291dHB1dCA9IG5ldyBTZXJpYWxpemVyKCdibGluZF9vdXRwdXQnLCB7XG4gIGNvbW1pdG1lbnQ6IGJ5dGVzKDMzKSxcbiAgcmFuZ2VfcHJvb2Y6IGJ5dGVzKCksXG4gIG93bmVyOiBhdXRob3JpdHksXG4gIHN0ZWFsdGhfbWVtbzogb3B0aW9uYWwoc3RlYWx0aF9jb25maXJtYXRpb24pXG59KTtcblxudmFyIHRyYW5zZmVyX3RvX2JsaW5kID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zZmVyX3RvX2JsaW5kJywge1xuICBmZWU6IGFzc2V0LFxuICBhbW91bnQ6IGFzc2V0LFxuICBmcm9tOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGJsaW5kaW5nX2ZhY3RvcjogYnl0ZXMoMzIpLFxuICBvdXRwdXRzOiBhcnJheShibGluZF9vdXRwdXQpXG59KTtcblxudmFyIGJsaW5kX2lucHV0ID0gbmV3IFNlcmlhbGl6ZXIoJ2JsaW5kX2lucHV0Jywge1xuICBjb21taXRtZW50OiBieXRlcygzMyksXG4gIG93bmVyOiBhdXRob3JpdHlcbn0pO1xuXG52YXIgYmxpbmRfdHJhbnNmZXIgPSBuZXcgU2VyaWFsaXplcignYmxpbmRfdHJhbnNmZXInLCB7XG4gIGZlZTogYXNzZXQsXG4gIGlucHV0czogYXJyYXkoYmxpbmRfaW5wdXQpLFxuICBvdXRwdXRzOiBhcnJheShibGluZF9vdXRwdXQpXG59KTtcblxudmFyIHRyYW5zZmVyX2Zyb21fYmxpbmQgPSBuZXcgU2VyaWFsaXplcigndHJhbnNmZXJfZnJvbV9ibGluZCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgYW1vdW50OiBhc3NldCxcbiAgdG86IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmxpbmRpbmdfZmFjdG9yOiBieXRlcygzMiksXG4gIGlucHV0czogYXJyYXkoYmxpbmRfaW5wdXQpXG59KTtcblxudmFyIGFzc2V0X3NldHRsZV9jYW5jZWwgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfc2V0dGxlX2NhbmNlbCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgc2V0dGxlbWVudDogcHJvdG9jb2xfaWRfdHlwZSgnZm9yY2Vfc2V0dGxlbWVudCcpLFxuICBhY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFtb3VudDogYXNzZXQsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfY2xhaW1fZmVlcyA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF9jbGFpbV9mZWVzJywge1xuICBmZWU6IGFzc2V0LFxuICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50X3RvX2NsYWltOiBhc3NldCxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBmYmFfZGlzdHJpYnV0ZSA9IG5ldyBTZXJpYWxpemVyKCdmYmFfZGlzdHJpYnV0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBmYmFfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2ZiYV9hY2N1bXVsYXRvcicpLFxuICBhbW91bnQ6IGludDY0XG59KTtcblxudmFyIHJvY2tfcGFwZXJfc2Npc3NvcnNfZ2FtZV9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoJ3JvY2tfcGFwZXJfc2Npc3NvcnNfZ2FtZV9vcHRpb25zJywge1xuICBpbnN1cmFuY2VfZW5hYmxlZDogYm9vbCxcbiAgdGltZV9wZXJfY29tbWl0X21vdmU6IHVpbnQzMixcbiAgdGltZV9wZXJfcmV2ZWFsX21vdmU6IHVpbnQzMixcbiAgbnVtYmVyX29mX2dlc3R1cmVzOiB1aW50OFxufSk7XG5cbnZhciBnYW1lX3NwZWNpZmljX2RldGFpbHMgPSBzdGF0aWNfdmFyaWFudChbcm9ja19wYXBlcl9zY2lzc29yc19nYW1lX29wdGlvbnNdKTtcblxudmFyIHRvdXJuYW1lbnRfb3B0aW9ucyA9IG5ldyBTZXJpYWxpemVyKCd0b3VybmFtZW50X29wdGlvbnMnLCB7XG4gIHR5cGVfb2ZfZ2FtZTogdWludDE2LFxuICByZWdpc3RyYXRpb25fZGVhZGxpbmU6IHRpbWVfcG9pbnRfc2VjLFxuICBudW1iZXJfb2ZfcGxheWVyczogdWludDMyLFxuICBidXlfaW46IGFzc2V0LFxuICB3aGl0ZWxpc3Q6IHNldChwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JykpLFxuICBzdGFydF90aW1lOiBvcHRpb25hbCh0aW1lX3BvaW50X3NlYyksXG4gIHN0YXJ0X2RlbGF5OiBvcHRpb25hbCh1aW50MzIpLFxuICByb3VuZF9kZWxheTogdWludDMyLFxuICBudW1iZXJfb2Zfd2luczogdWludDMyLFxuICBtZXRhOiB2YXJpYW50X29iamVjdCxcbiAgZ2FtZV9vcHRpb25zOiBnYW1lX3NwZWNpZmljX2RldGFpbHNcbn0pO1xuXG52YXIgdG91cm5hbWVudF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcigndG91cm5hbWVudF9jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGNyZWF0b3I6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgb3B0aW9uczogdG91cm5hbWVudF9vcHRpb25zLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIHRvdXJuYW1lbnRfam9pbiA9IG5ldyBTZXJpYWxpemVyKCd0b3VybmFtZW50X2pvaW4nLCB7XG4gIGZlZTogYXNzZXQsXG4gIHBheWVyX2FjY291bnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgcGxheWVyX2FjY291bnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgdG91cm5hbWVudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgndG91cm5hbWVudCcpLFxuICBidXlfaW46IGFzc2V0LFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIHJvY2tfcGFwZXJfc2Npc3NvcnNfZ2VzdHVyZSA9IGVudW1lcmF0aW9uKFsncm9jaycsICdwYXBlcicsICdzY2lzc29ycycsICdzcG9jaycsICdsaXphcmQnXSk7XG5cbnZhciByb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X2NvbW1pdCA9IG5ldyBTZXJpYWxpemVyKCdyb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X2NvbW1pdCcsIHtcbiAgbm9uY2UxOiB1aW50NjQsXG4gIHRocm93X2hhc2g6IHNoYTI1NlxufSk7XG5cbnZhciByb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X3JldmVhbCA9IG5ldyBTZXJpYWxpemVyKCdyb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X3JldmVhbCcsIHtcbiAgbm9uY2UyOiB1aW50NjQsXG4gIGdlc3R1cmU6IHJvY2tfcGFwZXJfc2Npc3NvcnNfZ2VzdHVyZVxufSk7XG5cbnZhciBnYW1lX3NwZWNpZmljX21vdmVzID0gc3RhdGljX3ZhcmlhbnQoW3JvY2tfcGFwZXJfc2Npc3NvcnNfdGhyb3dfY29tbWl0LCByb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X3JldmVhbF0pO1xuXG52YXIgZ2FtZV9tb3ZlID0gbmV3IFNlcmlhbGl6ZXIoJ2dhbWVfbW92ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZ2FtZV9pZDogcHJvdG9jb2xfaWRfdHlwZSgnZ2FtZScpLFxuICBwbGF5ZXJfYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBtb3ZlOiBnYW1lX3NwZWNpZmljX21vdmVzLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGRpdmlkZW5kX2Fzc2V0X29wdGlvbnMgPSBuZXcgU2VyaWFsaXplcignZGl2aWRlbmRfYXNzZXRfb3B0aW9ucycsIHtcbiAgbmV4dF9wYXlvdXRfdGltZTogb3B0aW9uYWwodGltZV9wb2ludF9zZWMpLFxuICBwYXlvdXRfaW50ZXJ2YWw6IG9wdGlvbmFsKHVpbnQzMiksXG4gIG1pbmltdW1fZmVlX3BlcmNlbnRhZ2U6IHVpbnQ2NCxcbiAgbWluaW11bV9kaXN0cmlidXRpb25faW50ZXJ2YWw6IG9wdGlvbmFsKHVpbnQzMiksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2RpdmlkZW5kID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZV9kaXZpZGVuZCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgbmV3X29wdGlvbnM6IGRpdmlkZW5kX2Fzc2V0X29wdGlvbnMsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfZGl2aWRlbmRfZGlzdHJpYnV0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X2RpdmlkZW5kX2Rpc3RyaWJ1dGlvbicsIHtcbiAgZmVlOiBhc3NldCxcbiAgZGl2aWRlbmRfYXNzZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2Fzc2V0JyksXG4gIGFjY291bnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50czogc2V0KGFzc2V0KSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBzcG9ydF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignc3BvcnRfY3JlYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBuYW1lOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIHNwb3J0X3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKCdzcG9ydF91cGRhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIHNwb3J0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdzcG9ydCcpLFxuICBuZXdfbmFtZTogb3B0aW9uYWwobWFwKHN0cmluZywgc3RyaW5nKSksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgZXZlbnRfZ3JvdXBfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2V2ZW50X2dyb3VwX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgbmFtZTogbWFwKHN0cmluZywgc3RyaW5nKSxcbiAgc3BvcnRfaWQ6IG9iamVjdF9pZF90eXBlLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGV2ZW50X2dyb3VwX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKCdldmVudF9ncm91cF91cGRhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIG5ld19zcG9ydF9pZDogb3B0aW9uYWwocHJvdG9jb2xfaWRfdHlwZSgnc3BvcnQnKSksXG4gIG5ld19uYW1lOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgZXZlbnRfZ3JvdXBfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2V2ZW50X2dyb3VwJyksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgZXZlbnRfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2V2ZW50X2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgbmFtZTogbWFwKHN0cmluZywgc3RyaW5nKSxcbiAgc2Vhc29uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBzdGFydF90aW1lOiBvcHRpb25hbCh0aW1lX3BvaW50X3NlYyksXG4gIGV2ZW50X2dyb3VwX2lkOiBvYmplY3RfaWRfdHlwZSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBldmVudF91cGRhdGUgPSBuZXcgU2VyaWFsaXplcignZXZlbnRfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBldmVudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnZXZlbnQnKSxcbiAgbmV3X2V2ZW50X2dyb3VwX2lkOiBvcHRpb25hbChwcm90b2NvbF9pZF90eXBlKCdldmVudF9ncm91cCcpKSxcbiAgbmV3X25hbWU6IG9wdGlvbmFsKG1hcChzdHJpbmcsIHN0cmluZykpLFxuICBuZXdfc2Vhc29uOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgbmV3X3N0YXJ0X3RpbWU6IG9wdGlvbmFsKHRpbWVfcG9pbnRfc2VjKSxcbiAgaXNfbGl2ZV9tYXJrZXQ6IG9wdGlvbmFsKGJvb2wpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X3J1bGVzX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIG5hbWU6IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIGRlc2NyaXB0aW9uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIG5ld19uYW1lOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgbmV3X2Rlc2NyaXB0aW9uOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSxcbiAgYmV0dGluZ19tYXJrZXRfcnVsZXNfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0X3J1bGVzJylcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X2dyb3VwX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZGVzY3JpcHRpb246IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIGV2ZW50X2lkOiBvYmplY3RfaWRfdHlwZSxcbiAgcnVsZXNfaWQ6IG9iamVjdF9pZF90eXBlLFxuICBhc3NldF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfY3JlYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBncm91cF9pZDogb2JqZWN0X2lkX3R5cGUsXG4gIGRlc2NyaXB0aW9uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBwYXlvdXRfY29uZGl0aW9uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldF90eXBlID0gZW51bWVyYXRpb24oWydiYWNrJywgJ2xheSddKTtcblxudmFyIGJldF9wbGFjZSA9IG5ldyBTZXJpYWxpemVyKCdiZXRfcGxhY2UnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGJldHRvcl9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBiZXR0aW5nX21hcmtldF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXQnKSxcbiAgYW1vdW50X3RvX2JldDogYXNzZXQsXG4gIGJhY2tlcl9tdWx0aXBsaWVyOiB1aW50MzIsXG4gIGJhY2tfb3JfbGF5OiBiZXRfdHlwZSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9yZXNvbHV0aW9uX3R5cGUgPSBlbnVtZXJhdGlvbihbJ3dpbicsICdub3Rfd2luJywgJ2NhbmNlbCcsICdCRVRUSU5HX01BUktFVF9SRVNPTFVUSU9OX0NPVU5UJ10pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZSA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlJywge1xuICBmZWU6IGFzc2V0LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfZ3JvdXAnKSxcbiAgcmVzb2x1dGlvbnM6IG1hcChwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldCcpLCBiZXR0aW5nX21hcmtldF9yZXNvbHV0aW9uX3R5cGUpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkJywge1xuICBiZXR0b3JfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmV0dGluZ19tYXJrZXRfZ3JvdXBfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0X2dyb3VwJyksXG4gIHJlc29sdXRpb25zOiBtYXAocHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXQnKSwgYmV0dGluZ19tYXJrZXRfcmVzb2x1dGlvbl90eXBlKSxcbiAgd2lubmluZ3M6IGludDY0LFxuICBmZWVzX3BhaWQ6IGludDY0LFxuICBmZWU6IGFzc2V0XG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X2dyb3VwX2NhbmNlbF91bm1hdGNoZWRfYmV0cyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHMnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGJldHRpbmdfbWFya2V0X2dyb3VwX2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldF9ncm91cCcpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldF9tYXRjaGVkID0gbmV3IFNlcmlhbGl6ZXIoJ2JldF9tYXRjaGVkJywge1xuICBiZXR0b3JfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmV0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgYmV0dGluZ19tYXJrZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0JyksXG4gIGFtb3VudF9iZXQ6IGFzc2V0LFxuICBmZWVzX3BhaWQ6IGludDY0LFxuICBiYWNrZXJfbXVsdGlwbGllcjogdWludDMyLFxuICBndWFyYW50ZWVkX3dpbm5pbmdzX3JldHVybmVkOiBpbnQ2NFxufSk7XG5cbnZhciBiZXRfY2FuY2VsID0gbmV3IFNlcmlhbGl6ZXIoJ2JldF9jYW5jZWwnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGJldHRvcl9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBiZXRfdG9fY2FuY2VsOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXRfY2FuY2VsZWQgPSBuZXcgU2VyaWFsaXplcignYmV0X2NhbmNlbGVkJywge1xuICBiZXR0b3JfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmV0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgc3Rha2VfcmV0dXJuZWQ6IGFzc2V0LFxuICB1bnVzZWRfZmVlc19yZXR1cm5lZDogYXNzZXRcbn0pO1xuXG52YXIgcGF5b3V0X3R5cGUgPSBlbnVtZXJhdGlvbihbJ3ByaXplX2F3YXJkJywgJ2J1eWluX3JlZnVuZCcsICdyYWtlX2ZlZSddKTtcblxudmFyIHRvdXJuYW1lbnRfcGF5b3V0ID0gbmV3IFNlcmlhbGl6ZXIoJ3RvdXJuYW1lbnRfcGF5b3V0Jywge1xuICBmZWU6IGFzc2V0LFxuICBwYXlvdXRfYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICB0b3VybmFtZW50X2lkOiBwcm90b2NvbF9pZF90eXBlKCd0b3VybmFtZW50JyksXG4gIHBheW91dF9hbW91bnQ6IGFzc2V0LFxuICB0eXBlOiBwYXlvdXRfdHlwZSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciB0b3VybmFtZW50X2xlYXZlID0gbmV3IFNlcmlhbGl6ZXIoJ3RvdXJuYW1lbnRfbGVhdmUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGNhbmNlbGluZ19hY2NvdW50X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHBsYXllcl9hY2NvdW50X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHRvdXJuYW1lbnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ3RvdXJuYW1lbnQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGUgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfZ3JvdXAnKSxcbiAgbmV3X2Rlc2NyaXB0aW9uOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgbmV3X3J1bGVzX2lkOiBvcHRpb25hbChwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldF9ydWxlcycpKSxcbiAgZnJlZXplOiBvcHRpb25hbChib29sKSxcbiAgZGVsYXlfYmV0czogb3B0aW9uYWwoYm9vbCksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X3VwZGF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgYmV0dGluZ19tYXJrZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0JyksXG4gIG5ld19ncm91cF9pZDogb3B0aW9uYWwocHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfZ3JvdXAnKSksXG4gIG5ld19kZXNjcmlwdGlvbjogb3B0aW9uYWwobWFwKHN0cmluZywgc3RyaW5nKSksXG4gIG5ld19wYXlvdXRfY29uZGl0aW9uOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXRfYWRqdXN0ZWQgPSBuZXcgU2VyaWFsaXplcignYmV0X2FkanVzdGVkJywge1xuICBiZXR0b3JfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmV0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgc3Rha2VfcmV0dXJuZWQ6IGFzc2V0XG59KTtcblxub3BlcmF0aW9uLnN0X29wZXJhdGlvbnMgPSBbdHJhbnNmZXIsIGxpbWl0X29yZGVyX2NyZWF0ZSwgbGltaXRfb3JkZXJfY2FuY2VsLCBjYWxsX29yZGVyX3VwZGF0ZSwgZmlsbF9vcmRlciwgYWNjb3VudF9jcmVhdGUsIGFjY291bnRfdXBkYXRlLCBhY2NvdW50X3doaXRlbGlzdCwgYWNjb3VudF91cGdyYWRlLCBhY2NvdW50X3RyYW5zZmVyLCBhc3NldF9jcmVhdGUsIGFzc2V0X3VwZGF0ZSwgYXNzZXRfdXBkYXRlX2JpdGFzc2V0LCBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnMsIGFzc2V0X2lzc3VlLCBhc3NldF9yZXNlcnZlLCBhc3NldF9mdW5kX2ZlZV9wb29sLCBhc3NldF9zZXR0bGUsIGFzc2V0X2dsb2JhbF9zZXR0bGUsIGFzc2V0X3B1Ymxpc2hfZmVlZCwgd2l0bmVzc19jcmVhdGUsIHdpdG5lc3NfdXBkYXRlLCBwcm9wb3NhbF9jcmVhdGUsIHByb3Bvc2FsX3VwZGF0ZSwgcHJvcG9zYWxfZGVsZXRlLCB3aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZSwgd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGUsIHdpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW0sIHdpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlLCBjb21taXR0ZWVfbWVtYmVyX2NyZWF0ZSwgY29tbWl0dGVlX21lbWJlcl91cGRhdGUsIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzLCB2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlLCB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXcsIHdvcmtlcl9jcmVhdGUsIGN1c3RvbSwgYXNzZXJ0LCBiYWxhbmNlX2NsYWltLCBvdmVycmlkZV90cmFuc2ZlciwgdHJhbnNmZXJfdG9fYmxpbmQsIGJsaW5kX3RyYW5zZmVyLCB0cmFuc2Zlcl9mcm9tX2JsaW5kLCBhc3NldF9zZXR0bGVfY2FuY2VsLCBhc3NldF9jbGFpbV9mZWVzLCBmYmFfZGlzdHJpYnV0ZSwgdG91cm5hbWVudF9jcmVhdGUsIHRvdXJuYW1lbnRfam9pbiwgZ2FtZV9tb3ZlLCBhc3NldF91cGRhdGVfZGl2aWRlbmQsIGFzc2V0X2RpdmlkZW5kX2Rpc3RyaWJ1dGlvbiwgdG91cm5hbWVudF9wYXlvdXQsIHRvdXJuYW1lbnRfbGVhdmUsIHNwb3J0X2NyZWF0ZSwgc3BvcnRfdXBkYXRlLCBldmVudF9ncm91cF9jcmVhdGUsIGV2ZW50X2dyb3VwX3VwZGF0ZSwgZXZlbnRfY3JlYXRlLCBldmVudF91cGRhdGUsIGJldHRpbmdfbWFya2V0X3J1bGVzX2NyZWF0ZSwgYmV0dGluZ19tYXJrZXRfcnVsZXNfdXBkYXRlLCBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGUsIGJldHRpbmdfbWFya2V0X2NyZWF0ZSwgYmV0X3BsYWNlLCBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlLCBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlZCwgYmV0X2FkanVzdGVkLCBiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHMsIGJldF9tYXRjaGVkLCBiZXRfY2FuY2VsLCBiZXRfY2FuY2VsZWQsIGJldHRpbmdfbWFya2V0X2dyb3VwX3VwZGF0ZSwgYmV0dGluZ19tYXJrZXRfdXBkYXRlXTtcblxudmFyIHRyYW5zYWN0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zYWN0aW9uJywge1xuICByZWZfYmxvY2tfbnVtOiB1aW50MTYsXG4gIHJlZl9ibG9ja19wcmVmaXg6IHVpbnQzMixcbiAgZXhwaXJhdGlvbjogdGltZV9wb2ludF9zZWMsXG4gIG9wZXJhdGlvbnM6IGFycmF5KG9wZXJhdGlvbiksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgc2lnbmVkX3RyYW5zYWN0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ3NpZ25lZF90cmFuc2FjdGlvbicsIHtcbiAgcmVmX2Jsb2NrX251bTogdWludDE2LFxuICByZWZfYmxvY2tfcHJlZml4OiB1aW50MzIsXG4gIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICBvcGVyYXRpb25zOiBhcnJheShvcGVyYXRpb24pLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICBzaWduYXR1cmVzOiBhcnJheShieXRlcyg2NSkpXG59KTtcbi8vICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gIyAgR2VuZXJhdGVkIGNvZGUgZW5kXG4vLyAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gQmV0dGluZyBPYmplY3RzXG5cbnZhciBzcG9ydCA9IG5ldyBTZXJpYWxpemVyKCdzcG9ydCcsIHtcbiAgaWQ6IHByb3RvY29sX2lkX3R5cGUoJ3Nwb3J0JyksXG4gIG5hbWU6IG1hcChzdHJpbmcsIHN0cmluZylcbn0pO1xuXG52YXIgZXZlbnRfZ3JvdXAgPSBuZXcgU2VyaWFsaXplcignZXZlbnRfZ3JvdXAnLCB7XG4gIGlkOiBwcm90b2NvbF9pZF90eXBlKCdldmVudF9ncm91cCcpLFxuICBuYW1lOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBzcG9ydF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnc3BvcnQnKVxufSk7XG5cbnZhciBldmVudF9zdGF0dXMgPSBlbnVtZXJhdGlvbihbJ3VwY29taW5nJywgJ2luX3Byb2dyZXNzJywgJ2Zyb3plbicsICdmaW5pc2hlZCcsICdjb21wbGV0ZWQnLCAnY2FuY2VsZWQnLCAnU1RBVFVTX0NPVU5UJ10pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfc3RhdHVzID0gZW51bWVyYXRpb24oWyd1bnJlc29sdmVkJywgJ2Zyb3plbicsICdncmFkZWQnLCAnY2FuY2VsZWQnLCAnc2V0dGxlZCddKTtcblxudmFyIGJldHRpbmdfbWFya2V0X2dyb3VwX3N0YXR1cyA9IGVudW1lcmF0aW9uKFsndXBjb21pbmcnLCAnaW5fcGxheScsICdjbG9zZWQnLCAnZ3JhZGVkJywgJ3JlLWdyYWRpbmcnLCAnc2V0dGxlZCcsICdmcm96ZW4nLCAnY2FuY2VsZWQnXSk7XG5cbnZhciBldmVudCA9IG5ldyBTZXJpYWxpemVyKCdldmVudCcsIHtcbiAgaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2V2ZW50JyksXG4gIG5hbWU6IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIHNlYXNvbjogbWFwKHN0cmluZywgc3RyaW5nKSxcbiAgc3RhcnRfdGltZTogb3B0aW9uYWwodGltZV9wb2ludF9zZWMpLFxuICBldmVudF9ncm91cF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnZXZlbnRfZ3JvdXAnKSxcbiAgaXNfbGl2ZV9tYXJrZXQ6IGJvb2wsXG4gIHN0YXR1czogZXZlbnRfc3RhdHVzLFxuICBzY29yZXM6IGFycmF5KHN0cmluZylcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfcnVsZXMgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfcnVsZXMnLCB7XG4gIGlkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldF9ydWxlcycpLFxuICBuYW1lOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBkZXNjcmlwdGlvbjogbWFwKHN0cmluZywgc3RyaW5nKVxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9ncm91cCA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cCcsIHtcbiAgaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0X2dyb3VwJyksXG4gIGRlc2NyaXB0aW9uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBldmVudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnZXZlbnQnKSxcbiAgcnVsZXNfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0X3J1bGVzJyksXG4gIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpLFxuICB0b3RhbF9tYXRjaGVkX2JldHNfYW1vdW50OiB1aW50NjQsXG4gIGZyb3plbjogYm9vbCxcbiAgZGVsYXlfYmV0czogYm9vbCxcbiAgc3RhdHVzOiBiZXR0aW5nX21hcmtldF9ncm91cF9zdGF0dXNcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXQgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXQnLCB7XG4gIGlkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldCcpLFxuICBncm91cF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfZ3JvdXAnKSxcbiAgZGVzY3JpcHRpb246IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIHBheW91dF9jb25kaXRpb246IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIHN0YXR1czogYmV0dGluZ19tYXJrZXRfc3RhdHVzXG59KTtcblxudmFyIGJldCA9IG5ldyBTZXJpYWxpemVyKCdiZXQnLCB7XG4gIGlkOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgYmV0dG9yX2lkOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGJldHRpbmdfbWFya2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldCcpLFxuICBhbW91bnRfdG9fYmV0OiBhc3NldCxcbiAgYmFja2VyX211bHRpcGxpZXI6IHVpbnQzMixcbiAgYmFja19vcl9sYXk6IGJldF90eXBlXG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X3Bvc2l0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X3Bvc2l0aW9uJywge1xuICBpZDogaW1wbGVtZW50YXRpb25faWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfcG9zaXRpb24nKSxcbiAgYmV0dG9yX2lkOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGJldHRpbmdfbWFya2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldCcpLFxuICBwYXlfaWZfcGF5b3V0X2NvbmRpdGlvbjogaW50NjQsXG4gIHBheV9pZl9ub3RfcGF5b3V0X2NvbmRpdGlvbjogaW50NjQsXG4gIHBheV9pZl9jYW5jZWxlZDogaW50NjQsXG4gIHBheV9pZl9ub3RfY2FuY2VsZWQ6IGludDY0LFxuICBmZWVzX2NvbGxlY3RlZDogaW50NjRcbn0pO1xuXG52YXIgZ2xvYmFsX2JldHRpbmdfc3RhdGlzdGljcyA9IG5ldyBTZXJpYWxpemVyKCdnbG9iYWxfYmV0dGluZ19zdGF0aXN0aWNzJywge1xuICBpZDogaW1wbGVtZW50YXRpb25faWRfdHlwZSgnZ2xvYmFsX2JldHRpbmdfc3RhdGlzdGljcycpLFxuICBudW1iZXJfb2ZfYWN0aXZlX2V2ZW50czogdWludDMyLFxuICB0b3RhbF9hbW91bnRfc3Rha2VkOiBtYXAocHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSwgaW50NjQpXG59KTtcblxuLy8gZW9mIEJldHRpbmcgT2JqZWN0c1xuXG4vLyBDdXN0b20gVHlwZXNcblxudmFyIHN0ZWFsdGhfbWVtb19kYXRhID0gbmV3IFNlcmlhbGl6ZXIoJ3N0ZWFsdGhfbWVtb19kYXRhJywge1xuICBmcm9tOiBvcHRpb25hbChwdWJsaWNfa2V5KSxcbiAgYW1vdW50OiBhc3NldCxcbiAgYmxpbmRpbmdfZmFjdG9yOiBieXRlcygzMiksXG4gIGNvbW1pdG1lbnQ6IGJ5dGVzKDMzKSxcbiAgY2hlY2s6IHVpbnQzMlxufSk7XG4vLyB2YXIgc3RlYWx0aF9jb25maXJtYXRpb24gPSBuZXcgU2VyaWFsaXplcihcbi8vICAgICBcInN0ZWFsdGhfY29uZmlybWF0aW9uXCIsIHtcbi8vICAgICBvbmVfdGltZV9rZXk6IHB1YmxpY19rZXksXG4vLyAgICAgdG86IG9wdGlvbmFsKCBwdWJsaWNfa2V5ICksXG4vLyAgICAgZW5jcnlwdGVkX21lbW86IHN0ZWFsdGhfbWVtb19kYXRhXG4vLyB9KVxuXG5leHBvcnRzLm9wZXJhdGlvbiA9IG9wZXJhdGlvbjtcbmV4cG9ydHMudHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5saW1pdF9vcmRlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbGltaXRfb3JkZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMubGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGxpbWl0X29yZGVyX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmNhbGxfb3JkZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGNhbGxfb3JkZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuZmlsbF9vcmRlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBmaWxsX29yZGVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYWNjb3VudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYWNjb3VudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hY2NvdW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhY2NvdW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFjY291bnRfd2hpdGVsaXN0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFjY291bnRfd2hpdGVsaXN0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYWNjb3VudF91cGdyYWRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFjY291bnRfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYWNjb3VudF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hc3NldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFzc2V0X3VwZGF0ZV9iaXRhc3NldF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2Vyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hc3NldF9pc3N1ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF9pc3N1ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X3Jlc2VydmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfcmVzZXJ2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfZnVuZF9mZWVfcG9vbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hc3NldF9nbG9iYWxfc2V0dGxlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hc3NldF9wdWJsaXNoX2ZlZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfcHVibGlzaF9mZWVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMud2l0bmVzc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gd2l0bmVzc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy53aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSB3aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnByb3Bvc2FsX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBwcm9wb3NhbF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5wcm9wb3NhbF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gcHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMucHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHByb3Bvc2FsX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHdpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHdpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdmVzdGluZ19iYWxhbmNlX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnZlc3RpbmdfYmFsYW5jZV93aXRoZHJhd19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXdfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy53b3JrZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHdvcmtlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5jdXN0b21fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFzc2VydF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJhbGFuY2VfY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmFsYW5jZV9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLm92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMudHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5ibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdHJhbnNmZXJfZnJvbV9ibGluZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X3NldHRsZV9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfc2V0dGxlX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X2NsYWltX2ZlZXNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYXNzZXRfdXBkYXRlX2RpdmlkZW5kX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFzc2V0X3VwZGF0ZV9kaXZpZGVuZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X2RpdmlkZW5kX2Rpc3RyaWJ1dGlvbl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb25fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5zcG9ydF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gc3BvcnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuc3BvcnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHNwb3J0X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmV2ZW50X2dyb3VwX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBldmVudF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5ldmVudF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXZlbnRfZ3JvdXBfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuZXZlbnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV2ZW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmV2ZW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBldmVudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmV0dGluZ19tYXJrZXRfcnVsZXNfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfcnVsZXNfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmV0dGluZ19tYXJrZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0X3BsYWNlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldF9wbGFjZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfY2FuY2VsX3VubWF0Y2hlZF9iZXRzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldHRpbmdfbWFya2V0X2dyb3VwX2NhbmNlbF91bm1hdGNoZWRfYmV0c19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldF9tYXRjaGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldF9tYXRjaGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0X2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBiZXRfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0X2NhbmNlbGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldF9jYW5jZWxlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnRvdXJuYW1lbnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHRvdXJuYW1lbnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMudG91cm5hbWVudF9qb2luX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHRvdXJuYW1lbnRfam9pbl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmdhbWVfbW92ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBnYW1lX21vdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy50b3VybmFtZW50X3BheW91dF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSB0b3VybmFtZW50X3BheW91dF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnRvdXJuYW1lbnRfbGVhdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdG91cm5hbWVudF9sZWF2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmV0dGluZ19tYXJrZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0X2FkanVzdGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldF9hZGp1c3RlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmZlZV9zY2hlZHVsZSA9IGZlZV9zY2hlZHVsZTtcbmV4cG9ydHMudm9pZF9yZXN1bHQgPSB2b2lkX3Jlc3VsdDtcbmV4cG9ydHMuYXNzZXQgPSBhc3NldDtcbmV4cG9ydHMucHJvY2Vzc2VkX3RyYW5zYWN0aW9uID0gcHJvY2Vzc2VkX3RyYW5zYWN0aW9uO1xuZXhwb3J0cy5zaWduZWRfYmxvY2sgPSBzaWduZWRfYmxvY2s7XG5leHBvcnRzLmJsb2NrX2hlYWRlciA9IGJsb2NrX2hlYWRlcjtcbmV4cG9ydHMuc2lnbmVkX2Jsb2NrX2hlYWRlciA9IHNpZ25lZF9ibG9ja19oZWFkZXI7XG5leHBvcnRzLm1lbW9fZGF0YSA9IG1lbW9fZGF0YTtcbmV4cG9ydHMudHJhbnNmZXIgPSB0cmFuc2ZlcjtcbmV4cG9ydHMubGltaXRfb3JkZXJfY3JlYXRlID0gbGltaXRfb3JkZXJfY3JlYXRlO1xuZXhwb3J0cy5saW1pdF9vcmRlcl9jYW5jZWwgPSBsaW1pdF9vcmRlcl9jYW5jZWw7XG5leHBvcnRzLmNhbGxfb3JkZXJfdXBkYXRlID0gY2FsbF9vcmRlcl91cGRhdGU7XG5leHBvcnRzLmZpbGxfb3JkZXIgPSBmaWxsX29yZGVyO1xuZXhwb3J0cy5hdXRob3JpdHkgPSBhdXRob3JpdHk7XG5leHBvcnRzLmFjY291bnRfb3B0aW9ucyA9IGFjY291bnRfb3B0aW9ucztcbmV4cG9ydHMuYWNjb3VudF9jcmVhdGUgPSBhY2NvdW50X2NyZWF0ZTtcbmV4cG9ydHMuYWNjb3VudF91cGRhdGUgPSBhY2NvdW50X3VwZGF0ZTtcbmV4cG9ydHMuYWNjb3VudF93aGl0ZWxpc3QgPSBhY2NvdW50X3doaXRlbGlzdDtcbmV4cG9ydHMuYWNjb3VudF91cGdyYWRlID0gYWNjb3VudF91cGdyYWRlO1xuZXhwb3J0cy5hY2NvdW50X3RyYW5zZmVyID0gYWNjb3VudF90cmFuc2ZlcjtcbmV4cG9ydHMucHJpY2UgPSBwcmljZTtcbmV4cG9ydHMuYXNzZXRfb3B0aW9ucyA9IGFzc2V0X29wdGlvbnM7XG5leHBvcnRzLmJpdGFzc2V0X29wdGlvbnMgPSBiaXRhc3NldF9vcHRpb25zO1xuZXhwb3J0cy5hc3NldF9jcmVhdGUgPSBhc3NldF9jcmVhdGU7XG5leHBvcnRzLmFzc2V0X3VwZGF0ZSA9IGFzc2V0X3VwZGF0ZTtcbmV4cG9ydHMuYXNzZXRfdXBkYXRlX2JpdGFzc2V0ID0gYXNzZXRfdXBkYXRlX2JpdGFzc2V0O1xuZXhwb3J0cy5hc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnMgPSBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnM7XG5leHBvcnRzLmFzc2V0X2lzc3VlID0gYXNzZXRfaXNzdWU7XG5leHBvcnRzLmFzc2V0X3Jlc2VydmUgPSBhc3NldF9yZXNlcnZlO1xuZXhwb3J0cy5hc3NldF9mdW5kX2ZlZV9wb29sID0gYXNzZXRfZnVuZF9mZWVfcG9vbDtcbmV4cG9ydHMuYXNzZXRfc2V0dGxlID0gYXNzZXRfc2V0dGxlO1xuZXhwb3J0cy5hc3NldF9nbG9iYWxfc2V0dGxlID0gYXNzZXRfZ2xvYmFsX3NldHRsZTtcbmV4cG9ydHMucHJpY2VfZmVlZCA9IHByaWNlX2ZlZWQ7XG5leHBvcnRzLmFzc2V0X3B1Ymxpc2hfZmVlZCA9IGFzc2V0X3B1Ymxpc2hfZmVlZDtcbmV4cG9ydHMud2l0bmVzc19jcmVhdGUgPSB3aXRuZXNzX2NyZWF0ZTtcbmV4cG9ydHMud2l0bmVzc191cGRhdGUgPSB3aXRuZXNzX3VwZGF0ZTtcbmV4cG9ydHMub3Bfd3JhcHBlciA9IG9wX3dyYXBwZXI7XG5leHBvcnRzLnByb3Bvc2FsX2NyZWF0ZSA9IHByb3Bvc2FsX2NyZWF0ZTtcbmV4cG9ydHMucHJvcG9zYWxfdXBkYXRlID0gcHJvcG9zYWxfdXBkYXRlO1xuZXhwb3J0cy5wcm9wb3NhbF9kZWxldGUgPSBwcm9wb3NhbF9kZWxldGU7XG5leHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlID0gd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGU7XG5leHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlID0gd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGU7XG5leHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW0gPSB3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltO1xuZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSA9IHdpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlO1xuZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX2NyZWF0ZSA9IGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlO1xuZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZSA9IGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlO1xuZXhwb3J0cy5jaGFpbl9wYXJhbWV0ZXJzID0gY2hhaW5fcGFyYW1ldGVycztcbmV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnMgPSBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVycztcbmV4cG9ydHMubGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gbGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyO1xuZXhwb3J0cy5jZGRfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXIgPSBjZGRfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXI7XG5leHBvcnRzLnZlc3RpbmdfYmFsYW5jZV9jcmVhdGUgPSB2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlO1xuZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXcgPSB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXc7XG5leHBvcnRzLnJlZnVuZF93b3JrZXJfaW5pdGlhbGl6ZXIgPSByZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyO1xuZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd29ya2VyX2luaXRpYWxpemVyID0gdmVzdGluZ19iYWxhbmNlX3dvcmtlcl9pbml0aWFsaXplcjtcbmV4cG9ydHMuYnVybl93b3JrZXJfaW5pdGlhbGl6ZXIgPSBidXJuX3dvcmtlcl9pbml0aWFsaXplcjtcbmV4cG9ydHMud29ya2VyX2NyZWF0ZSA9IHdvcmtlcl9jcmVhdGU7XG5leHBvcnRzLmN1c3RvbSA9IGN1c3RvbTtcbmV4cG9ydHMuYWNjb3VudF9uYW1lX2VxX2xpdF9wcmVkaWNhdGUgPSBhY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZTtcbmV4cG9ydHMuYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUgPSBhc3NldF9zeW1ib2xfZXFfbGl0X3ByZWRpY2F0ZTtcbmV4cG9ydHMuYmxvY2tfaWRfcHJlZGljYXRlID0gYmxvY2tfaWRfcHJlZGljYXRlO1xuZXhwb3J0cy5hc3NlcnQgPSBhc3NlcnQ7XG5leHBvcnRzLmJhbGFuY2VfY2xhaW0gPSBiYWxhbmNlX2NsYWltO1xuZXhwb3J0cy5vdmVycmlkZV90cmFuc2ZlciA9IG92ZXJyaWRlX3RyYW5zZmVyO1xuZXhwb3J0cy5zdGVhbHRoX2NvbmZpcm1hdGlvbiA9IHN0ZWFsdGhfY29uZmlybWF0aW9uO1xuZXhwb3J0cy5ibGluZF9vdXRwdXQgPSBibGluZF9vdXRwdXQ7XG5leHBvcnRzLnRyYW5zZmVyX3RvX2JsaW5kID0gdHJhbnNmZXJfdG9fYmxpbmQ7XG5leHBvcnRzLmJsaW5kX2lucHV0ID0gYmxpbmRfaW5wdXQ7XG5leHBvcnRzLmJsaW5kX3RyYW5zZmVyID0gYmxpbmRfdHJhbnNmZXI7XG5leHBvcnRzLnRyYW5zZmVyX2Zyb21fYmxpbmQgPSB0cmFuc2Zlcl9mcm9tX2JsaW5kO1xuZXhwb3J0cy5hc3NldF9zZXR0bGVfY2FuY2VsID0gYXNzZXRfc2V0dGxlX2NhbmNlbDtcbmV4cG9ydHMuYXNzZXRfY2xhaW1fZmVlcyA9IGFzc2V0X2NsYWltX2ZlZXM7XG5leHBvcnRzLmZiYV9kaXN0cmlidXRlID0gZmJhX2Rpc3RyaWJ1dGU7XG5leHBvcnRzLnJvY2tfcGFwZXJfc2Npc3NvcnNfZ2FtZV9vcHRpb25zID0gcm9ja19wYXBlcl9zY2lzc29yc19nYW1lX29wdGlvbnM7XG5leHBvcnRzLnRvdXJuYW1lbnRfb3B0aW9ucyA9IHRvdXJuYW1lbnRfb3B0aW9ucztcbmV4cG9ydHMudG91cm5hbWVudF9jcmVhdGUgPSB0b3VybmFtZW50X2NyZWF0ZTtcbmV4cG9ydHMudG91cm5hbWVudF9qb2luID0gdG91cm5hbWVudF9qb2luO1xuZXhwb3J0cy5yb2NrX3BhcGVyX3NjaXNzb3JzX2dlc3R1cmUgPSByb2NrX3BhcGVyX3NjaXNzb3JzX2dlc3R1cmU7XG5leHBvcnRzLnJvY2tfcGFwZXJfc2Npc3NvcnNfdGhyb3dfY29tbWl0ID0gcm9ja19wYXBlcl9zY2lzc29yc190aHJvd19jb21taXQ7XG5leHBvcnRzLnJvY2tfcGFwZXJfc2Npc3NvcnNfdGhyb3dfcmV2ZWFsID0gcm9ja19wYXBlcl9zY2lzc29yc190aHJvd19yZXZlYWw7XG5leHBvcnRzLmdhbWVfbW92ZSA9IGdhbWVfbW92ZTtcbmV4cG9ydHMuZGl2aWRlbmRfYXNzZXRfb3B0aW9ucyA9IGRpdmlkZW5kX2Fzc2V0X29wdGlvbnM7XG5leHBvcnRzLmFzc2V0X3VwZGF0ZV9kaXZpZGVuZCA9IGFzc2V0X3VwZGF0ZV9kaXZpZGVuZDtcbmV4cG9ydHMuYXNzZXRfZGl2aWRlbmRfZGlzdHJpYnV0aW9uID0gYXNzZXRfZGl2aWRlbmRfZGlzdHJpYnV0aW9uO1xuZXhwb3J0cy5zcG9ydF9jcmVhdGUgPSBzcG9ydF9jcmVhdGU7XG5leHBvcnRzLnNwb3J0X3VwZGF0ZSA9IHNwb3J0X3VwZGF0ZTtcbmV4cG9ydHMuZXZlbnRfZ3JvdXBfY3JlYXRlID0gZXZlbnRfZ3JvdXBfY3JlYXRlO1xuZXhwb3J0cy5ldmVudF9ncm91cF91cGRhdGUgPSBldmVudF9ncm91cF91cGRhdGU7XG5leHBvcnRzLmV2ZW50X2NyZWF0ZSA9IGV2ZW50X2NyZWF0ZTtcbmV4cG9ydHMuZXZlbnRfdXBkYXRlID0gZXZlbnRfdXBkYXRlO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGUgPSBiZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGU7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZSA9IGJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZTtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfY3JlYXRlID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfY3JlYXRlO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9jcmVhdGUgPSBiZXR0aW5nX21hcmtldF9jcmVhdGU7XG5leHBvcnRzLmJldF90eXBlID0gYmV0X3R5cGU7XG5leHBvcnRzLmJldF9wbGFjZSA9IGJldF9wbGFjZTtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfcmVzb2x1dGlvbl90eXBlID0gYmV0dGluZ19tYXJrZXRfcmVzb2x1dGlvbl90eXBlO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZTtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWQgPSBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlZDtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfY2FuY2VsX3VubWF0Y2hlZF9iZXRzID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfY2FuY2VsX3VubWF0Y2hlZF9iZXRzO1xuZXhwb3J0cy5iZXRfbWF0Y2hlZCA9IGJldF9tYXRjaGVkO1xuZXhwb3J0cy5iZXRfY2FuY2VsID0gYmV0X2NhbmNlbDtcbmV4cG9ydHMuYmV0X2NhbmNlbGVkID0gYmV0X2NhbmNlbGVkO1xuZXhwb3J0cy5wYXlvdXRfdHlwZSA9IHBheW91dF90eXBlO1xuZXhwb3J0cy50b3VybmFtZW50X3BheW91dCA9IHRvdXJuYW1lbnRfcGF5b3V0O1xuZXhwb3J0cy50b3VybmFtZW50X2xlYXZlID0gdG91cm5hbWVudF9sZWF2ZTtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF91cGRhdGUgPSBiZXR0aW5nX21hcmtldF91cGRhdGU7XG5leHBvcnRzLmJldF9hZGp1c3RlZCA9IGJldF9hZGp1c3RlZDtcbmV4cG9ydHMudHJhbnNhY3Rpb24gPSB0cmFuc2FjdGlvbjtcbmV4cG9ydHMuc2lnbmVkX3RyYW5zYWN0aW9uID0gc2lnbmVkX3RyYW5zYWN0aW9uO1xuZXhwb3J0cy5zcG9ydCA9IHNwb3J0O1xuZXhwb3J0cy5ldmVudF9ncm91cCA9IGV2ZW50X2dyb3VwO1xuZXhwb3J0cy5ldmVudCA9IGV2ZW50O1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlcyA9IGJldHRpbmdfbWFya2V0X3J1bGVzO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cCA9IGJldHRpbmdfbWFya2V0X2dyb3VwO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldCA9IGJldHRpbmdfbWFya2V0O1xuZXhwb3J0cy5iZXQgPSBiZXQ7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X3Bvc2l0aW9uID0gYmV0dGluZ19tYXJrZXRfcG9zaXRpb247XG5leHBvcnRzLmdsb2JhbF9iZXR0aW5nX3N0YXRpc3RpY3MgPSBnbG9iYWxfYmV0dGluZ19zdGF0aXN0aWNzO1xuZXhwb3J0cy5zdGVhbHRoX21lbW9fZGF0YSA9IHN0ZWFsdGhfbWVtb19kYXRhOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9ieXRlYnVmZmVyID0gcmVxdWlyZSgnYnl0ZWJ1ZmZlcicpO1xuXG52YXIgX2J5dGVidWZmZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYnl0ZWJ1ZmZlcik7XG5cbnZhciBfZXJyb3Jfd2l0aF9jYXVzZSA9IHJlcXVpcmUoJy4vZXJyb3Jfd2l0aF9jYXVzZScpO1xuXG52YXIgX2Vycm9yX3dpdGhfY2F1c2UyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZXJyb3Jfd2l0aF9jYXVzZSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBIRVhfRFVNUCA9IHByb2Nlc3MuZW52Lm5wbV9jb25maWdfX2dyYXBoZW5lX3NlcmlhbGl6ZXJfaGV4X2R1bXA7XG5cbnZhciBTZXJpYWxpemVyID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTZXJpYWxpemVyKG9wZXJhdGlvbl9uYW1lLCB0eXBlcykge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTZXJpYWxpemVyKTtcblxuICAgIHRoaXMub3BlcmF0aW9uX25hbWUgPSBvcGVyYXRpb25fbmFtZTtcbiAgICB0aGlzLnR5cGVzID0gdHlwZXM7XG5cbiAgICBpZiAodGhpcy50eXBlcykge1xuICAgICAgdGhpcy5rZXlzID0gT2JqZWN0LmtleXModGhpcy50eXBlcyk7XG4gICAgfVxuXG4gICAgU2VyaWFsaXplci5wcmludERlYnVnID0gdHJ1ZTtcbiAgfVxuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLmZyb21CeXRlQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICB2YXIgZmllbGQgPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBpdGVyYWJsZSA9IHRoaXMua2V5cztcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVyYWJsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBmaWVsZCA9IGl0ZXJhYmxlW2ldO1xuICAgICAgICB2YXIgdHlwZSA9IHRoaXMudHlwZXNbZmllbGRdO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKEhFWF9EVU1QKSB7XG4gICAgICAgICAgICBpZiAodHlwZS5vcGVyYXRpb25fbmFtZSkge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHR5cGUub3BlcmF0aW9uX25hbWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdmFyIG8xID0gYi5vZmZzZXQ7XG4gICAgICAgICAgICAgIHR5cGUuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgICAgICAgIHZhciBvMiA9IGIub2Zmc2V0O1xuICAgICAgICAgICAgICBiLm9mZnNldCA9IG8xO1xuICAgICAgICAgICAgICAvLyBiLnJlc2V0KClcbiAgICAgICAgICAgICAgdmFyIF9iID0gYi5jb3B5KG8xLCBvMik7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IodGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgJ1xcdCcsIF9iLnRvSGV4KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIG9iamVjdFtmaWVsZF0gPSB0eXBlLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKFNlcmlhbGl6ZXIucHJpbnREZWJ1Zykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgcmVhZGluZyAnICsgdGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgJyBpbiBkYXRhOicpO1xuICAgICAgICAgICAgYi5wcmludERlYnVnKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBfZXJyb3Jfd2l0aF9jYXVzZTIuZGVmYXVsdC50aHJvdyh0aGlzLm9wZXJhdGlvbl9uYW1lICsgJy4nICsgZmllbGQsIGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9O1xuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLmFwcGVuZEJ5dGVCdWZmZXIgPSBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgIHZhciBmaWVsZCA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy5rZXlzO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZpZWxkID0gaXRlcmFibGVbaV07XG4gICAgICAgIHZhciB0eXBlID0gdGhpcy50eXBlc1tmaWVsZF07XG4gICAgICAgIHR5cGUuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3RbZmllbGRdKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgX2Vycm9yX3dpdGhfY2F1c2UyLmRlZmF1bHQudGhyb3codGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgJyA9ICcgKyBKU09OLnN0cmluZ2lmeShvYmplY3RbZmllbGRdKSwgZXJyb3IpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBjaXJjdWxhciByZWZcbiAgICAgICAgX2Vycm9yX3dpdGhfY2F1c2UyLmRlZmF1bHQudGhyb3codGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgJyA9ICcgKyBvYmplY3RbZmllbGRdLCBlcnJvcik7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KHNlcmlhbGl6ZWRfb2JqZWN0KSB7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIHZhciBmaWVsZCA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy5rZXlzO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZpZWxkID0gaXRlcmFibGVbaV07XG4gICAgICAgIHZhciB0eXBlID0gdGhpcy50eXBlc1tmaWVsZF07XG4gICAgICAgIHZhciB2YWx1ZSA9IHNlcmlhbGl6ZWRfb2JqZWN0W2ZpZWxkXTtcbiAgICAgICAgLy8gREVCVUcgdmFsdWUgPSB2YWx1ZS5yZXNvbHZlIGlmIHZhbHVlLnJlc29sdmVcbiAgICAgICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiB2YWx1ZScsZmllbGQsdmFsdWUpXG4gICAgICAgIHZhciBvYmplY3QgPSB0eXBlLmZyb21PYmplY3QodmFsdWUpO1xuICAgICAgICByZXN1bHRbZmllbGRdID0gb2JqZWN0O1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBfZXJyb3Jfd2l0aF9jYXVzZTIuZGVmYXVsdC50aHJvdyh0aGlzLm9wZXJhdGlvbl9uYW1lICsgJy4nICsgZmllbGQsIGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBAYXJnIHtib29sZWFufSBbZGVidWcudXNlX2RlZmF1bHQgPSBmYWxzZV0gLSBtb3JlIHRlbXBsYXRlIGZyaWVuZGx5XG4gICAgICAgIEBhcmcge2Jvb2xlYW59IFtkZWJ1Zy5hbm5vdGF0ZSA9IGZhbHNlXSAtIGFkZCB1c2VyLWZyaWVuZGx5IGluZm9ybWF0aW9uXG4gICAgKi9cblxuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QoKSB7XG4gICAgdmFyIHNlcmlhbGl6ZWRfb2JqZWN0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB7fTtcbiAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHsgdXNlX2RlZmF1bHQ6IGZhbHNlLCBhbm5vdGF0ZTogZmFsc2UgfTtcblxuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICB2YXIgZmllbGQgPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlmICghdGhpcy50eXBlcykge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICB2YXIgaXRlcmFibGUgPSB0aGlzLmtleXM7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaXRlcmFibGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZmllbGQgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgdmFyIHR5cGUgPSB0aGlzLnR5cGVzW2ZpZWxkXTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHR5cGUudG9PYmplY3QodHlwZW9mIHNlcmlhbGl6ZWRfb2JqZWN0ICE9PSAndW5kZWZpbmVkJyAmJiBzZXJpYWxpemVkX29iamVjdCAhPT0gbnVsbCA/IHNlcmlhbGl6ZWRfb2JqZWN0W2ZpZWxkXSA6IHVuZGVmaW5lZCwgZGVidWcpO1xuICAgICAgICByZXN1bHRbZmllbGRdID0gb2JqZWN0O1xuXG4gICAgICAgIGlmIChIRVhfRFVNUCkge1xuICAgICAgICAgIHZhciBiID0gbmV3IF9ieXRlYnVmZmVyMi5kZWZhdWx0KF9ieXRlYnVmZmVyMi5kZWZhdWx0LkRFRkFVTFRfQ0FQQUNJVFksIF9ieXRlYnVmZmVyMi5kZWZhdWx0LkxJVFRMRV9FTkRJQU4pO1xuICAgICAgICAgIHR5cGUuYXBwZW5kQnl0ZUJ1ZmZlcihiLCB0eXBlb2Ygc2VyaWFsaXplZF9vYmplY3QgIT09ICd1bmRlZmluZWQnICYmIHNlcmlhbGl6ZWRfb2JqZWN0ICE9PSBudWxsID8gc2VyaWFsaXplZF9vYmplY3RbZmllbGRdIDogdW5kZWZpbmVkKTtcbiAgICAgICAgICBiID0gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKHRoaXMub3BlcmF0aW9uX25hbWUgKyAnLicgKyBmaWVsZCwgYi50b0hleCgpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBfZXJyb3Jfd2l0aF9jYXVzZTIuZGVmYXVsdC50aHJvdyh0aGlzLm9wZXJhdGlvbl9uYW1lICsgJy4nICsgZmllbGQsIGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8qKiBTb3J0IGJ5IHRoZSBmaXJzdCBlbGVtZW50IGluIGEgb3BlcmF0aW9uICovXG5cblxuICBTZXJpYWxpemVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG4gICAgdmFyIGZpcnN0X2tleSA9IHRoaXMua2V5c1swXTtcbiAgICB2YXIgZmlyc3RfdHlwZSA9IHRoaXMudHlwZXNbZmlyc3Rfa2V5XTtcblxuICAgIHZhciB2YWxBID0gYVtmaXJzdF9rZXldO1xuICAgIHZhciB2YWxCID0gYltmaXJzdF9rZXldO1xuXG4gICAgaWYgKGZpcnN0X3R5cGUuY29tcGFyZSkge1xuICAgICAgcmV0dXJuIGZpcnN0X3R5cGUuY29tcGFyZSh2YWxBLCB2YWxCKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbEEgPT09ICdudW1iZXInICYmIHR5cGVvZiB2YWxCID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHZhbEEgLSB2YWxCO1xuICAgIH1cblxuICAgIHZhciBlbmNvZGluZyA9IHZvaWQgMDtcblxuICAgIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsQSkgJiYgQnVmZmVyLmlzQnVmZmVyKHZhbEIpKSB7XG4gICAgICAvLyBBIGJpbmFyeSBzdHJpbmcgY29tcGFyZSBkb2VzIG5vdCB3b3JrLiAgSWYgbG9jYWxlQ29tcGFyZSBpcyB3ZWxsIHN1cHBvcnRlZCB0aGF0IGNvdWxkXG4gICAgICAvLyByZXBsYWNlIEhFWC4gIFBlcmZvcm1hbmFuY2UgaXMgdmVyeSBnb29kIHNvIGNvbXBhcmluZyBIRVggd29ya3MuXG4gICAgICBlbmNvZGluZyA9ICdoZXgnO1xuICAgIH1cblxuICAgIHZhciBzdHJBID0gdmFsQS50b1N0cmluZyhlbmNvZGluZyk7XG4gICAgdmFyIHN0ckIgPSB2YWxCLnRvU3RyaW5nKGVuY29kaW5nKTtcblxuICAgIHZhciByZXN1bHQgPSAwO1xuXG4gICAgaWYgKHN0ckEgPiBzdHJCKSB7XG4gICAgICByZXN1bHQgPSAxO1xuICAgIH1cblxuICAgIGlmIChzdHJBIDwgc3RyQikge1xuICAgICAgcmVzdWx0ID0gLTE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyA8aGVscGVyX2Z1bmN0aW9ucz5cblxuICBTZXJpYWxpemVyLnByb3RvdHlwZS5mcm9tSGV4ID0gZnVuY3Rpb24gZnJvbUhleChoZXgpIHtcbiAgICB2YXIgYiA9IF9ieXRlYnVmZmVyMi5kZWZhdWx0LmZyb21IZXgoaGV4LCBfYnl0ZWJ1ZmZlcjIuZGVmYXVsdC5MSVRUTEVfRU5ESUFOKTtcbiAgICByZXR1cm4gdGhpcy5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgfTtcblxuICBTZXJpYWxpemVyLnByb3RvdHlwZS5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICB2YXIgYiA9IF9ieXRlYnVmZmVyMi5kZWZhdWx0LmZyb21CaW5hcnkoYnVmZmVyLnRvU3RyaW5nKCdiaW5hcnknKSwgX2J5dGVidWZmZXIyLmRlZmF1bHQuTElUVExFX0VORElBTik7XG4gICAgcmV0dXJuIHRoaXMuZnJvbUJ5dGVCdWZmZXIoYik7XG4gIH07XG5cbiAgU2VyaWFsaXplci5wcm90b3R5cGUudG9IZXggPSBmdW5jdGlvbiB0b0hleChvYmplY3QpIHtcbiAgICAvLyByZXR1cm4gdGhpcy50b0J1ZmZlcihvYmplY3QpLnRvU3RyaW5nKFwiaGV4XCIpXG4gICAgdmFyIGIgPSB0aGlzLnRvQnl0ZUJ1ZmZlcihvYmplY3QpO1xuICAgIHJldHVybiBiLnRvSGV4KCk7XG4gIH07XG5cbiAgU2VyaWFsaXplci5wcm90b3R5cGUudG9CeXRlQnVmZmVyID0gZnVuY3Rpb24gdG9CeXRlQnVmZmVyKG9iamVjdCkge1xuICAgIHZhciBiID0gbmV3IF9ieXRlYnVmZmVyMi5kZWZhdWx0KF9ieXRlYnVmZmVyMi5kZWZhdWx0LkRFRkFVTFRfQ0FQQUNJVFksIF9ieXRlYnVmZmVyMi5kZWZhdWx0LkxJVFRMRV9FTkRJQU4pO1xuICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpO1xuICAgIHJldHVybiBiLmNvcHkoMCwgYi5vZmZzZXQpO1xuICB9O1xuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gdG9CdWZmZXIob2JqZWN0KSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHRoaXMudG9CeXRlQnVmZmVyKG9iamVjdCkudG9CaW5hcnkoKSwgJ2JpbmFyeScpO1xuICB9O1xuXG4gIHJldHVybiBTZXJpYWxpemVyO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBTZXJpYWxpemVyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLmRlZmF1bHQgPSB0ZW1wbGF0ZTtcbi8qKiBDb25zb2xlIHByaW50IGFueSB0cmFuc2FjdGlvbiBvYmplY3Qgd2l0aCB6ZXJvIGRlZmF1bHQgdmFsdWVzLiAqL1xuZnVuY3Rpb24gdGVtcGxhdGUob3ApIHtcbiAgdmFyIG9iamVjdCA9IG9wLnRvT2JqZWN0KHVuZGVmaW5lZCwgeyB1c2VfZGVmYXVsdDogdHJ1ZSwgYW5ub3RhdGU6IHRydWUgfSk7XG5cbiAgLy8gdmlzdWFsICh3aXRoIGRlc2NyaXB0aW9ucylcbiAgY29uc29sZS5lcnJvcihKU09OLnN0cmluZ2lmeShvYmplY3QsIG51bGwsIDQpKTtcblxuICAvLyB1c2FibGUgaW4gYSBjb3B5LXBhc3RlXG5cbiAgb2JqZWN0ID0gb3AudG9PYmplY3QodW5kZWZpbmVkLCB7IHVzZV9kZWZhdWx0OiB0cnVlLCBhbm5vdGF0ZTogZmFsc2UgfSk7XG5cbiAgLy8gY29weS1wYXN0ZSBvbmUtbGluZWVyXG4gIGNvbnNvbGUuZXJyb3IoSlNPTi5zdHJpbmdpZnkob2JqZWN0KSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9OyAvLyBMb3ctbGV2ZWwgdHlwZXMgdGhhdCBtYWtlIHVwIG9wZXJhdGlvbnNcblxudmFyIF9wZWVycGxheXNqc1dzID0gcmVxdWlyZSgncGVlcnBsYXlzanMtd3MnKTtcblxudmFyIF9TZXJpYWxpemVyVmFsaWRhdGlvbiA9IHJlcXVpcmUoJy4vU2VyaWFsaXplclZhbGlkYXRpb24nKTtcblxudmFyIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TZXJpYWxpemVyVmFsaWRhdGlvbik7XG5cbnZhciBfRmFzdFBhcnNlciA9IHJlcXVpcmUoJy4vRmFzdFBhcnNlcicpO1xuXG52YXIgX0Zhc3RQYXJzZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfRmFzdFBhcnNlcik7XG5cbnZhciBfQ2hhaW5UeXBlcyA9IHJlcXVpcmUoJy4uLy4uL2NoYWluL3NyYy9DaGFpblR5cGVzJyk7XG5cbnZhciBfQ2hhaW5UeXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpblR5cGVzKTtcblxudmFyIF9PYmplY3RJZCA9IHJlcXVpcmUoJy4uLy4uL2NoYWluL3NyYy9PYmplY3RJZCcpO1xuXG52YXIgX09iamVjdElkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX09iamVjdElkKTtcblxudmFyIF9lY2MgPSByZXF1aXJlKCcuLi8uLi9lY2MnKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIE1JTl9TSUdORURfMzIgPSAtMSAqIE1hdGgucG93KDIsIDMxKTtcbnZhciBNQVhfU0lHTkVEXzMyID0gTWF0aC5wb3coMiwgMzEpIC0gMTtcblxudmFyIEhFWF9EVU1QID0gcHJvY2Vzcy5lbnYubnBtX2NvbmZpZ19fZ3JhcGhlbmVfc2VyaWFsaXplcl9oZXhfZHVtcDtcblxudmFyIHN0ckNtcCA9IGZ1bmN0aW9uIHN0ckNtcChhLCBiKSB7XG4gIHZhciByZXN1bHQgPSAwO1xuXG4gIGlmIChhID4gYikge1xuICAgIHJlc3VsdCA9IDE7XG4gIH1cblxuICBpZiAoYSA8IGIpIHtcbiAgICByZXN1bHQgPSAtMTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG52YXIgZmlyc3RFbCA9IGZ1bmN0aW9uIGZpcnN0RWwoZWwpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoZWwpID8gZWxbMF0gOiBlbDtcbn07XG5cbnZhciBzb3J0T3BlcmF0aW9uID0gZnVuY3Rpb24gc29ydE9wZXJhdGlvbihhcnJheSwgc3Rfb3BlcmF0aW9uKSB7XG4gIGlmICghc3Rfb3BlcmF0aW9uLm5vc29ydCkge1xuICAgIC8vIElmIHRoZSBvcGVyYXRpb24gaGFzIGl0cyBvd24gY29tcGFyZSBmdW5jdGlvbi5cbiAgICBpZiAoc3Rfb3BlcmF0aW9uLmNvbXBhcmUpIHtcbiAgICAgIHJldHVybiBhcnJheS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBzdF9vcGVyYXRpb24uY29tcGFyZShmaXJzdEVsKGEpLCBmaXJzdEVsKGIpKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBhcnJheS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICB2YXIgYUZpcnN0ID0gZmlyc3RFbChhKTtcbiAgICAgIHZhciBiRmlyc3QgPSBmaXJzdEVsKGIpO1xuXG4gICAgICAvLyBJZiBib3RoIG9mIHRoZSBmaXJzdCBlbGVtZW50cyBhcmUgbnVtYmVycy5cbiAgICAgIGlmICh0eXBlb2YgYUZpcnN0ID09PSAnbnVtYmVyJyAmJiB0eXBlb2YgYkZpcnN0ID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gYUZpcnN0IC0gYkZpcnN0O1xuICAgICAgfVxuXG4gICAgICAvLyBJZiB0aGV5IGFyZSBib3RoIGJ1ZmZlcnMuXG4gICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKGFGaXJzdCkgJiYgQnVmZmVyLmlzQnVmZmVyKGJGaXJzdCkpIHtcbiAgICAgICAgcmV0dXJuIHN0ckNtcChhRmlyc3QudG9TdHJpbmcoJ2hleCcpLCBiRmlyc3QudG9TdHJpbmcoJ2hleCcpKTtcbiAgICAgIH1cblxuICAgICAgLy8gT3RoZXJ3aXNlXG4gICAgICByZXR1cm4gc3RyQ21wKGFGaXJzdC50b1N0cmluZygpLCBiRmlyc3QudG9TdHJpbmcoKSk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gYXJyYXk7XG59O1xuXG52YXIgVHlwZXMgPSB7fTtcblxuVHlwZXMudWludDggPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIGIucmVhZFVpbnQ4KCk7XG4gIH0sXG4gIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZiwgb2JqZWN0LCAndWludDggJyArIG9iamVjdCk7XG4gICAgYi53cml0ZVVpbnQ4KG9iamVjdCk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZiwgb2JqZWN0LCAndWludDggJyArIG9iamVjdCk7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmYsIG9iamVjdCwgJ3VpbnQ4ICcgKyBvYmplY3QpO1xuICAgIHJldHVybiBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMudWludDE2ID0ge1xuICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHJldHVybiBiLnJlYWRVaW50MTYoKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZSgwLCAweGZmZmYsIG9iamVjdCwgJ3VpbnQxNiAnICsgb2JqZWN0KTtcbiAgICBiLndyaXRlVWludDE2KG9iamVjdCk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmLCBvYmplY3QsICd1aW50MTYgJyArIG9iamVjdCk7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmZmZiwgb2JqZWN0LCAndWludDE2ICcgKyBvYmplY3QpO1xuICAgIHJldHVybiBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMudWludDMyID0ge1xuICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHJldHVybiBiLnJlYWRVaW50MzIoKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZSgwLCAweGZmZmZmZmZmLCBvYmplY3QsICd1aW50MzIgJyArIG9iamVjdCk7XG4gICAgYi53cml0ZVVpbnQzMihvYmplY3QpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmZmZmZmZmYsIG9iamVjdCwgJ3VpbnQzMiAnICsgb2JqZWN0KTtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmZmZmZiwgb2JqZWN0LCAndWludDMyICcgKyBvYmplY3QpO1xuICAgIHJldHVybiBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMudmFyaW50MzIgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIGIucmVhZFZhcmludDMyKCk7XG4gIH0sXG4gIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoTUlOX1NJR05FRF8zMiwgTUFYX1NJR05FRF8zMiwgb2JqZWN0LCAndWludDMyICcgKyBvYmplY3QpO1xuICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKE1JTl9TSUdORURfMzIsIE1BWF9TSUdORURfMzIsIG9iamVjdCwgJ3VpbnQzMiAnICsgb2JqZWN0KTtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoTUlOX1NJR05FRF8zMiwgTUFYX1NJR05FRF8zMiwgb2JqZWN0LCAndWludDMyICcgKyBvYmplY3QpO1xuICAgIHJldHVybiBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMuaW50NjQgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIGIucmVhZEludDY0KCk7XG4gIH0sXG4gIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgYi53cml0ZUludDY0KF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC50b19sb25nKG9iamVjdCkpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgIHJldHVybiBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudG9fbG9uZyhvYmplY3QpO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuICcwJztcbiAgICB9XG5cbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICByZXR1cm4gX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnRvX2xvbmcob2JqZWN0KS50b1N0cmluZygpO1xuICB9XG59O1xuXG5UeXBlcy51aW50NjQgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIGIucmVhZFVpbnQ2NCgpO1xuICB9LFxuICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgIGIud3JpdGVVaW50NjQoX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnRvX3Vsb25nKF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC51bnNpZ25lZChvYmplY3QpKSk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC50b191bG9uZyhfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudW5zaWduZWQob2JqZWN0KSk7XG4gIH0sXG4gIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gJzAnO1xuICAgIH1cblxuICAgIHJldHVybiBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudG9fdWxvbmcob2JqZWN0KS50b1N0cmluZygpO1xuICB9XG59O1xuXG5UeXBlcy5zdHJpbmcgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgdmFyIGJfY29weSA9IHZvaWQgMDtcbiAgICB2YXIgbGVuID0gYi5yZWFkVmFyaW50MzIoKTtcbiAgICBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgbGVuKTtcbiAgICBiLnNraXAobGVuKTtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oYl9jb3B5LnRvQmluYXJ5KCksICdiaW5hcnknKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICBiLndyaXRlVmFyaW50MzIob2JqZWN0Lmxlbmd0aCk7XG4gICAgYi5hcHBlbmQob2JqZWN0LnRvU3RyaW5nKCdiaW5hcnknKSwgJ2JpbmFyeScpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShvYmplY3QpO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHJldHVybiBvYmplY3QudG9TdHJpbmcoKTtcbiAgfVxufTtcblxuVHlwZXMuYnl0ZXMgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICB2YXIgYnl0ZXMgPSB7XG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgIGlmIChzaXplID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIF9iX2NvcHkgPSB2b2lkIDA7XG4gICAgICAgIHZhciBsZW4gPSBiLnJlYWRWYXJpbnQzMigpO1xuICAgICAgICBfYl9jb3B5ID0gYi5jb3B5KGIub2Zmc2V0LCBiLm9mZnNldCArIGxlbik7XG4gICAgICAgIGIuc2tpcChsZW4pO1xuICAgICAgICByZXR1cm4gQnVmZmVyLmZyb20oX2JfY29weS50b0JpbmFyeSgpLCAnYmluYXJ5Jyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgc2l6ZSk7XG4gICAgICBiLnNraXAoc2l6ZSk7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20oYl9jb3B5LnRvQmluYXJ5KCksICdiaW5hcnknKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgICAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG9iamVjdCA9IEJ1ZmZlci5mcm9tKG9iamVjdCwgJ2hleCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QubGVuZ3RoKTtcbiAgICAgIH1cblxuICAgICAgYi5hcHBlbmQob2JqZWN0LnRvU3RyaW5nKCdiaW5hcnknKSwgJ2JpbmFyeScpO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKG9iamVjdCwgJ2hleCcpO1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBuZXcgQXJyYXkoc2l6ZSkuam9pbignMDAnKTtcbiAgICAgIH1cblxuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGJ5dGVzO1xufTtcblxuVHlwZXMuYm9vbCA9IHtcbiAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICByZXR1cm4gYi5yZWFkVWludDgoKSA9PT0gMTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAvLyBzdXBwb3J0cyBib29sZWFuIG9yIGludGVnZXJcbiAgICBiLndyaXRlVWludDgoSlNPTi5wYXJzZShvYmplY3QpID8gMSA6IDApO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiAhIUpTT04ucGFyc2Uob2JqZWN0KTtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gISFKU09OLnBhcnNlKG9iamVjdCk7XG4gIH1cbn07XG5cblR5cGVzLnZvaWQgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJyh2b2lkKSB1bmRlZmluZWQgdHlwZScpO1xuICB9LFxuICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignKHZvaWQpIHVuZGVmaW5lZCB0eXBlJyk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3QoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCcodm9pZCkgdW5kZWZpbmVkIHR5cGUnKTtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCcodm9pZCkgdW5kZWZpbmVkIHR5cGUnKTtcbiAgfVxufTtcblxuVHlwZXMuYXJyYXkgPSBmdW5jdGlvbiAoc3Rfb3BlcmF0aW9uKSB7XG4gIHZhciBhcnJheSA9IHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgdmFyIHNpemUgPSBiLnJlYWRWYXJpbnQzMigpO1xuXG4gICAgICBpZiAoSEVYX0RVTVApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ3ZhcmludDMyIHNpemUgPSAnICsgc2l6ZS50b1N0cmluZygxNikpO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBzaXplID4gMCA/IGkgPCBzaXplIDogaSA+IHNpemU7IHNpemUgPiAwID8gaSsrIDogaSsrKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzb3J0T3BlcmF0aW9uKHJlc3VsdCwgc3Rfb3BlcmF0aW9uKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuICAgICAgYi53cml0ZVZhcmludDMyKG9iamVjdC5sZW5ndGgpO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gb2JqZWN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBvID0gb2JqZWN0W2ldO1xuICAgICAgICBzdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gb2JqZWN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBvID0gb2JqZWN0W2ldO1xuICAgICAgICByZXN1bHQucHVzaChzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFtzdF9vcGVyYXRpb24udG9PYmplY3Qob2JqZWN0LCBkZWJ1ZyldO1xuICAgICAgfVxuXG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBvYmplY3RbaV07XG4gICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi50b09iamVjdChvLCBkZWJ1ZykpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gYXJyYXk7XG59O1xuXG5UeXBlcy50aW1lX3BvaW50X3NlYyA9IHtcbiAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICByZXR1cm4gYi5yZWFkVWludDMyKCk7XG4gIH0sXG4gIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgIT09ICdudW1iZXInKSB7XG4gICAgICBvYmplY3QgPSBUeXBlcy50aW1lX3BvaW50X3NlYy5mcm9tT2JqZWN0KG9iamVjdCk7XG4gICAgfVxuXG4gICAgYi53cml0ZVVpbnQzMihvYmplY3QpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIGlmIChvYmplY3QuZ2V0VGltZSkge1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3Iob2JqZWN0LmdldFRpbWUoKSAvIDEwMDApO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGRhdGUgdHlwZTogJyArIG9iamVjdCk7XG4gICAgfVxuXG4gICAgLy8gaWYodHlwZW9mIG9iamVjdCA9PT0gXCJzdHJpbmdcIiAmJiAhL1okLy50ZXN0KG9iamVjdCkpXG4gICAgLy8gICAgIG9iamVjdCA9IG9iamVjdCArIFwiWlwiXG5cbiAgICByZXR1cm4gTWF0aC5mbG9vcihuZXcgRGF0ZShvYmplY3QpLmdldFRpbWUoKSAvIDEwMDApO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIG5ldyBEYXRlKDApLnRvSVNPU3RyaW5nKCkuc3BsaXQoJy4nKVswXTtcbiAgICB9XG5cbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICBpZiAob2JqZWN0LmdldFRpbWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QudG9JU09TdHJpbmcoKS5zcGxpdCgnLicpWzBdO1xuICAgIH1cblxuICAgIHZhciBpbnQgPSBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZSgwLCAweGZmZmZmZmZmLCBpbnQsICd1aW50MzIgJyArIG9iamVjdCk7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGludCAqIDEwMDApLnRvSVNPU3RyaW5nKCkuc3BsaXQoJy4nKVswXTtcbiAgfVxufTtcblxuVHlwZXMuc2V0ID0gZnVuY3Rpb24gKHN0X29wZXJhdGlvbikge1xuICB2YXIgc2V0X29iamVjdCA9IHtcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24gdmFsaWRhdGUoYXJyYXkpIHtcbiAgICAgIHZhciBkdXBfbWFwID0ge307XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhcnJheS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgbyA9IGFycmF5W2ldO1xuICAgICAgICB2YXIgcmVmID0gdHlwZW9mIG8gPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKG8pO1xuXG4gICAgICAgIGlmIChbJ3N0cmluZycsICdudW1iZXInXS5pbmRleE9mKHJlZikgPj0gMCkge1xuICAgICAgICAgIGlmIChkdXBfbWFwW29dICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZHVwbGljYXRlIChzZXQpJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZHVwX21hcFtvXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNvcnRPcGVyYXRpb24oYXJyYXksIHN0X29wZXJhdGlvbik7XG4gICAgfSxcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgdmFyIHNpemUgPSBiLnJlYWRWYXJpbnQzMigpO1xuXG4gICAgICBpZiAoSEVYX0RVTVApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ3ZhcmludDMyIHNpemUgPSAnICsgc2l6ZS50b1N0cmluZygxNikpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgc2l6ZSA+IDAgPyBpIDwgc2l6ZSA6IGkgPiBzaXplOyBzaXplID4gMCA/IGkrKyA6IGkrKykge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSgpKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICBvYmplY3QgPSBbXTtcbiAgICAgIH1cblxuICAgICAgYi53cml0ZVZhcmludDMyKG9iamVjdC5sZW5ndGgpO1xuICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy52YWxpZGF0ZShvYmplY3QpO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gaXRlcmFibGUubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgbyk7XG4gICAgICB9XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKCFvYmplY3QpIHtcbiAgICAgICAgb2JqZWN0ID0gW107XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICB2YXIgbyA9IG9iamVjdFtpXTtcbiAgICAgICAgICByZXN1bHQucHVzaChzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSgpKTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gW3N0X29wZXJhdGlvbi50b09iamVjdChvYmplY3QsIGRlYnVnKV07XG4gICAgICB9XG5cbiAgICAgIGlmICghb2JqZWN0KSB7XG4gICAgICAgIG9iamVjdCA9IFtdO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBvYmplY3RbaV07XG4gICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi50b09iamVjdChvLCBkZWJ1ZykpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZShyZXN1bHQpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gc2V0X29iamVjdDtcbn07XG5cblR5cGVzLmZpeGVkX2FycmF5ID0gZnVuY3Rpb24gKGNvdW50LCBzdF9vcGVyYXRpb24pIHtcbiAgdmFyIGZpeGVkX2FycmF5ID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICB2YXIgcmVzdWx0cyA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgcmVmID0gY291bnQ7IGkgPCByZWY7IGkrKykge1xuICAgICAgICByZXN1bHRzLnB1c2goc3Rfb3BlcmF0aW9uLmZyb21CeXRlQnVmZmVyKGIpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNvcnRPcGVyYXRpb24ocmVzdWx0cywgc3Rfb3BlcmF0aW9uKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBpZiAoY291bnQgIT09IDApIHtcbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBpID0gMCwgcmVmID0gY291bnQ7IGkgPCByZWY7IGkrKykge1xuICAgICAgICBzdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3RbaV0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChjb3VudCAhPT0gMCkge1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlc3VsdHMgPSBbXTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIHJlZiA9IGNvdW50OyBpIDwgcmVmOyBpKyspIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKHN0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG9iamVjdFtpXSkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QsIGRlYnVnKSB7XG4gICAgICBpZiAoZGVidWcgPT0gbnVsbCkge1xuICAgICAgICBkZWJ1ZyA9IHt9O1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVzdWx0cyA9IHZvaWQgMDtcblxuICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlc3VsdHMgPSBbXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcmVmID0gY291bnQ7IGkgPCByZWY7IGkrKykge1xuICAgICAgICAgIHJlc3VsdHMucHVzaChzdF9vcGVyYXRpb24udG9PYmplY3QodW5kZWZpbmVkLCBkZWJ1ZykpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb3VudCAhPT0gMCkge1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgcmVzdWx0cyA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBfaSA9IDAsIF9yZWYgPSBjb3VudDsgX2kgPCBfcmVmOyBfaSsrKSB7XG4gICAgICAgIHJlc3VsdHMucHVzaChzdF9vcGVyYXRpb24udG9PYmplY3Qob2JqZWN0W19pXSwgZGVidWcpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBmaXhlZF9hcnJheTtcbn07XG5cbi8qIFN1cHBvcnRzIGluc3RhbmNlIG51bWJlcnMgKDExKSBvciBvYmplY3QgdHlwZXMgKDEuMi4xMSkuICBPYmplY3QgdHlwZVxuVmFsaWRhdGlvbiBpcyBlbmZvcmNlZCB3aGVuIGFuIG9iamVjdCB0eXBlIGlzIHVzZWQuICovXG5UeXBlcy5pZF90eXBlID0gZnVuY3Rpb24gKHJlc2VydmVkX3NwYWNlcywgb2JqZWN0X3R5cGUpIHtcbiAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKHJlc2VydmVkX3NwYWNlcywgJ3Jlc2VydmVkX3NwYWNlcycpO1xuICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0X3R5cGUsICdvYmplY3RfdHlwZScpO1xuXG4gIHZhciBpZF90eXBlX29iamVjdCA9IHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgcmV0dXJuIGIucmVhZFZhcmludDMyKCk7XG4gICAgfSxcbiAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG5cbiAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgICAgfVxuXG4gICAgICAvLyBjb252ZXJ0IDEuMi5uIGludG8ganVzdCBuXG4gICAgICBpZiAoL15bMC05XStcXC5bMC05XStcXC5bMC05XSskLy50ZXN0KG9iamVjdCkpIHtcbiAgICAgICAgb2JqZWN0ID0gX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LmdldF9pbnN0YW5jZShyZXNlcnZlZF9zcGFjZXMsIG9iamVjdF90eXBlLCBvYmplY3QpO1xuICAgICAgfVxuXG4gICAgICBiLndyaXRlVmFyaW50MzIoX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnRvX251bWJlcihvYmplY3QpKTtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgICAgaWYgKG9iamVjdC5yZXNvbHZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgb2JqZWN0ID0gb2JqZWN0LnJlc29sdmU7XG4gICAgICB9XG5cbiAgICAgIGlmIChfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQuaXNfZGlnaXRzKG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC50b19udW1iZXIob2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5nZXRfaW5zdGFuY2UocmVzZXJ2ZWRfc3BhY2VzLCBvYmplY3RfdHlwZSwgb2JqZWN0KTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgIHZhciBvYmplY3RfdHlwZV9pZCA9IF9DaGFpblR5cGVzMi5kZWZhdWx0Lm9iamVjdF90eXBlW29iamVjdF90eXBlXTtcblxuICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiByZXNlcnZlZF9zcGFjZXMgKyAnLicgKyBvYmplY3RfdHlwZV9pZCArICcuMCc7XG4gICAgICB9XG5cbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgICBpZiAob2JqZWN0LnJlc29sdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBvYmplY3QgPSBvYmplY3QucmVzb2x2ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKC9eWzAtOV0rXFwuWzAtOV0rXFwuWzAtOV0rJC8udGVzdChvYmplY3QpKSB7XG4gICAgICAgIG9iamVjdCA9IF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5nZXRfaW5zdGFuY2UocmVzZXJ2ZWRfc3BhY2VzLCBvYmplY3RfdHlwZSwgb2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc2VydmVkX3NwYWNlcyArICcuJyArIG9iamVjdF90eXBlX2lkICsgJy4nICsgb2JqZWN0O1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gaWRfdHlwZV9vYmplY3Q7XG59O1xuXG5UeXBlcy5wcm90b2NvbF9pZF90eXBlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG5hbWUsICduYW1lJyk7XG4gIHJldHVybiBUeXBlcy5pZF90eXBlKF9DaGFpblR5cGVzMi5kZWZhdWx0LnJlc2VydmVkX3NwYWNlcy5wcm90b2NvbF9pZHMsIG5hbWUpO1xufTtcblxuVHlwZXMuaW1wbGVtZW50YXRpb25faWRfdHlwZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciByZXN1bHQgPSBUeXBlcy5pZF90eXBlKF9DaGFpblR5cGVzMi5kZWZhdWx0LnJlc2VydmVkX3NwYWNlcy5pbXBsZW1lbnRhdGlvbl9pZHMsIG5hbWUpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuVHlwZXMub2JqZWN0X2lkX3R5cGUgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIF9PYmplY3RJZDIuZGVmYXVsdC5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBvYmplY3QgPSBvYmplY3QucmVzb2x2ZTtcbiAgICB9XG5cbiAgICBvYmplY3QgPSBfT2JqZWN0SWQyLmRlZmF1bHQuZnJvbVN0cmluZyhvYmplY3QpO1xuICAgIG9iamVjdC5hcHBlbmRCeXRlQnVmZmVyKGIpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgaWYgKG9iamVjdC5yZXNvbHZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgIH1cblxuICAgIHJldHVybiBfT2JqZWN0SWQyLmRlZmF1bHQuZnJvbVN0cmluZyhvYmplY3QpO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuICcwLjAuMCc7XG4gICAgfVxuXG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG5cbiAgICBpZiAob2JqZWN0LnJlc29sdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb2JqZWN0ID0gb2JqZWN0LnJlc29sdmU7XG4gICAgfVxuXG4gICAgb2JqZWN0ID0gX09iamVjdElkMi5kZWZhdWx0LmZyb21TdHJpbmcob2JqZWN0KTtcbiAgICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCk7XG4gIH1cbn07XG5cblR5cGVzLnZvdGVfaWQgPSB7XG4gIFRZUEU6IDB4MDAwMDAwZmYsXG4gIElEOiAweGZmZmZmZjAwLFxuICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHZhciB2YWx1ZSA9IGIucmVhZFVpbnQzMigpO1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiB2YWx1ZSAmIHRoaXMuVFlQRSwgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgaWQ6IHZhbHVlICYgdGhpcy5JRCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgfTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgIGlmIChvYmplY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvYmplY3QgPSBUeXBlcy52b3RlX2lkLmZyb21PYmplY3Qob2JqZWN0KTtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWUgPSBvYmplY3QuaWQgPDwgOCB8IG9iamVjdC50eXBlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgYi53cml0ZVVpbnQzMih2YWx1ZSk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCwgJyh0eXBlIHZvdGVfaWQpJyk7XG5cbiAgICBpZiAoKHR5cGVvZiBvYmplY3QgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKG9iamVjdCkpID09PSAnb2JqZWN0Jykge1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdC50eXBlLCAndHlwZScpO1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdC5pZCwgJ2lkJyk7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3Rlc3QoL15bMC05XSs6WzAtOV0rJC8sIG9iamVjdCwgJ3ZvdGVfaWQgZm9ybWF0ICcgKyBvYmplY3QpO1xuXG4gICAgdmFyIF9vYmplY3Qkc3BsaXQgPSBvYmplY3Quc3BsaXQoJzonKSxcbiAgICAgICAgdHlwZSA9IF9vYmplY3Qkc3BsaXRbMF0sXG4gICAgICAgIGlkID0gX29iamVjdCRzcGxpdFsxXTtcblxuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmYsIHR5cGUsICd2b3RlIHR5cGUgJyArIG9iamVjdCk7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmZmYsIGlkLCAndm90ZSBpZCAnICsgb2JqZWN0KTtcbiAgICByZXR1cm4geyB0eXBlOiB0eXBlLCBpZDogaWQgfTtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAnMDowJztcbiAgICB9XG5cbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnc3RyaW5nJykge1xuICAgICAgb2JqZWN0ID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KG9iamVjdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iamVjdC50eXBlICsgJzonICsgb2JqZWN0LmlkO1xuICB9LFxuICBjb21wYXJlOiBmdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgICBpZiAoKHR5cGVvZiBhID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihhKSkgIT09ICdvYmplY3QnKSB7XG4gICAgICBhID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KGEpO1xuICAgIH1cblxuICAgIGlmICgodHlwZW9mIGIgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKGIpKSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIGIgPSBUeXBlcy52b3RlX2lkLmZyb21PYmplY3QoYik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnNlSW50KGEuaWQsIDEwKSAtIHBhcnNlSW50KGIuaWQsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMub3B0aW9uYWwgPSBmdW5jdGlvbiAoc3Rfb3BlcmF0aW9uKSB7XG4gIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChzdF9vcGVyYXRpb24sICdzdF9vcGVyYXRpb24nKTtcbiAgcmV0dXJuIHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgaWYgKCEoYi5yZWFkVWludDgoKSA9PT0gMSkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0ICE9PSBudWxsICYmIG9iamVjdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGIud3JpdGVVaW50OCgxKTtcbiAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGIud3JpdGVVaW50OCgwKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG9iamVjdCk7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAvLyB0b09iamVjdCBpcyBvbmx5IG51bGwgc2F2ZSBpZiB1c2VfZGVmYXVsdCBpcyB0cnVlXG4gICAgICB2YXIgcmVzdWx0X29iamVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KG9iamVjdCwgZGVidWcpO1xuICAgICAgfSgpO1xuXG4gICAgICBpZiAoZGVidWcuYW5ub3RhdGUpIHtcbiAgICAgICAgaWYgKCh0eXBlb2YgcmVzdWx0X29iamVjdCA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YocmVzdWx0X29iamVjdCkpID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHJlc3VsdF9vYmplY3QuX19vcHRpb25hbCA9ICdwYXJlbnQgaXMgb3B0aW9uYWwnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdF9vYmplY3QgPSB7IF9fb3B0aW9uYWw6IHJlc3VsdF9vYmplY3QgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0X29iamVjdDtcbiAgICB9XG4gIH07XG59O1xuXG5UeXBlcy5zdGF0aWNfdmFyaWFudCA9IGZ1bmN0aW9uIChfc3Rfb3BlcmF0aW9ucykge1xuICB2YXIgc3RhdGljX3ZhcmlhbnQgPSB7XG4gICAgbm9zb3J0OiB0cnVlLFxuICAgIHN0X29wZXJhdGlvbnM6IF9zdF9vcGVyYXRpb25zLFxuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICB2YXIgdHlwZV9pZCA9IGIucmVhZFZhcmludDMyKCk7XG4gICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuXG4gICAgICBpZiAoSEVYX0RVTVApIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignc3RhdGljX3ZhcmlhbnQgaWQgMHgnICsgdHlwZV9pZC50b1N0cmluZygxNikgKyAnICgnICsgdHlwZV9pZCArICcpJyk7XG4gICAgICB9XG5cbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChzdF9vcGVyYXRpb24sICdvcGVyYXRpb24gJyArIHR5cGVfaWQpO1xuICAgICAgcmV0dXJuIFt0eXBlX2lkLCBzdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYildO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgdmFyIHR5cGVfaWQgPSBvYmplY3RbMF07XG4gICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKHN0X29wZXJhdGlvbiwgJ29wZXJhdGlvbiAnICsgdHlwZV9pZCk7XG4gICAgICBiLndyaXRlVmFyaW50MzIodHlwZV9pZCk7XG4gICAgICBzdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3RbMV0pO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgdmFyIHR5cGVfaWQgPSBvYmplY3RbMF07XG4gICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuXG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQoc3Rfb3BlcmF0aW9uLCAnb3BlcmF0aW9uICcgKyB0eXBlX2lkKTtcbiAgICAgIHJldHVybiBbdHlwZV9pZCwgc3Rfb3BlcmF0aW9uLmZyb21PYmplY3Qob2JqZWN0WzFdKV07XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFswLCB0aGlzLnN0X29wZXJhdGlvbnNbMF0udG9PYmplY3QodW5kZWZpbmVkLCBkZWJ1ZyldO1xuICAgICAgfVxuXG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIHZhciB0eXBlX2lkID0gb2JqZWN0WzBdO1xuICAgICAgdmFyIHN0X29wZXJhdGlvbiA9IHRoaXMuc3Rfb3BlcmF0aW9uc1t0eXBlX2lkXTtcbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChzdF9vcGVyYXRpb24sICdvcGVyYXRpb24gJyArIHR5cGVfaWQpO1xuICAgICAgcmV0dXJuIFt0eXBlX2lkLCBzdF9vcGVyYXRpb24udG9PYmplY3Qob2JqZWN0WzFdLCBkZWJ1ZyldO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gc3RhdGljX3ZhcmlhbnQ7XG59O1xuXG5UeXBlcy5tYXAgPSBmdW5jdGlvbiAoa2V5X3N0X29wZXJhdGlvbiwgdmFsdWVfc3Rfb3BlcmF0aW9uKSB7XG4gIHZhciBtYXBfb2JqZWN0ID0ge1xuICAgIHZhbGlkYXRlOiBmdW5jdGlvbiB2YWxpZGF0ZShhcnJheSkge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFycmF5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGluZyBhcnJheScpO1xuICAgICAgfVxuXG4gICAgICB2YXIgZHVwX21hcCA9IHt9O1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBhcnJheVtpXTtcbiAgICAgICAgdmFyIHJlZiA9IHZvaWQgMDtcblxuICAgICAgICBpZiAoIShvLmxlbmd0aCA9PT0gMikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGluZyB0d28gZWxlbWVudHMnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlZiA9IF90eXBlb2Yob1swXSk7XG5cbiAgICAgICAgaWYgKHJlZiAmJiBbJ251bWJlcicsICdzdHJpbmcnXS5pbmRleE9mKHJlZikgPj0gMCkge1xuICAgICAgICAgIGlmIChkdXBfbWFwW29bMF1dICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZHVwbGljYXRlIChtYXApJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZHVwX21hcFtvWzBdXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNvcnRPcGVyYXRpb24oYXJyYXksIGtleV9zdF9vcGVyYXRpb24pO1xuICAgIH0sXG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIHZhciBlbmQgPSBiLnJlYWRWYXJpbnQzMigpO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgZW5kID4gMCA/IGkgPCBlbmQgOiBpID4gZW5kOyBlbmQgPiAwID8gaSsrIDogaSsrKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKFtrZXlfc3Rfb3BlcmF0aW9uLmZyb21CeXRlQnVmZmVyKGIpLCB2YWx1ZV9zdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYildKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGUocmVzdWx0KTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICB0aGlzLnZhbGlkYXRlKG9iamVjdCk7XG4gICAgICBiLndyaXRlVmFyaW50MzIob2JqZWN0Lmxlbmd0aCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBvYmplY3RbaV07XG4gICAgICAgIGtleV9zdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvWzBdKTtcbiAgICAgICAgdmFsdWVfc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb1sxXSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBvYmplY3RbaV07XG4gICAgICAgIHJlc3VsdC5wdXNoKFtrZXlfc3Rfb3BlcmF0aW9uLmZyb21PYmplY3Qob1swXSksIHZhbHVlX3N0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG9bMV0pXSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlKHJlc3VsdCk7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFtba2V5X3N0X29wZXJhdGlvbi50b09iamVjdCh1bmRlZmluZWQsIGRlYnVnKSwgdmFsdWVfc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KHVuZGVmaW5lZCwgZGVidWcpXV07XG4gICAgICB9XG5cbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgb2JqZWN0ID0gdGhpcy52YWxpZGF0ZShvYmplY3QpO1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gb2JqZWN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBvID0gb2JqZWN0W2ldO1xuICAgICAgICByZXN1bHQucHVzaChba2V5X3N0X29wZXJhdGlvbi50b09iamVjdChvWzBdLCBkZWJ1ZyksIHZhbHVlX3N0X29wZXJhdGlvbi50b09iamVjdChvWzFdLCBkZWJ1ZyldKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG1hcF9vYmplY3Q7XG59O1xuXG5UeXBlcy5wdWJsaWNfa2V5ID0ge1xuICB0b1B1YmxpYzogZnVuY3Rpb24gdG9QdWJsaWMob2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdC5yZXNvbHZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgIH1cblxuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBfZWNjLlB1YmxpY0tleSkge1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICB2YXIgcmVzdWx0ID0gb2JqZWN0O1xuXG4gICAgaWYgKCFvYmplY3QpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmICghb2JqZWN0LlEpIHtcbiAgICAgIHJlc3VsdCA9IF9lY2MuUHVibGljS2V5LmZyb21TdHJpbmdPclRocm93KG9iamVjdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcbiAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICByZXR1cm4gX0Zhc3RQYXJzZXIyLmRlZmF1bHQucHVibGljX2tleShiKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICBfRmFzdFBhcnNlcjIuZGVmYXVsdC5wdWJsaWNfa2V5KGIsIFR5cGVzLnB1YmxpY19rZXkudG9QdWJsaWMob2JqZWN0KSk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG5cbiAgICBpZiAob2JqZWN0LlEpIHtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgcmV0dXJuIFR5cGVzLnB1YmxpY19rZXkudG9QdWJsaWMob2JqZWN0KTtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeCArICc4NTlneGZuWHlVcmlNZ1VlVGhoMWZXdjNvcWNwTEZ5SGEzVGZGWUM0UEsySHFoVG9WTSc7XG4gICAgfVxuXG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgcmV0dXJuIG9iamVjdC50b1N0cmluZygpO1xuICB9LFxuICBjb21wYXJlOiBmdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgICByZXR1cm4gc3RyQ21wKGEudG9BZGRyZXNzU3RyaW5nKCksIGIudG9BZGRyZXNzU3RyaW5nKCkpO1xuICB9XG59O1xuXG5UeXBlcy5hZGRyZXNzID0ge1xuICBfdG9fYWRkcmVzczogZnVuY3Rpb24gX3RvX2FkZHJlc3Mob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG5cbiAgICBpZiAob2JqZWN0LmFkZHkpIHtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9lY2MuQWRkcmVzcy5mcm9tU3RyaW5nKG9iamVjdCk7XG4gIH0sXG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIG5ldyBfZWNjLkFkZHJlc3MoX0Zhc3RQYXJzZXIyLmRlZmF1bHQucmlwZW1kMTYwKGIpKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfRmFzdFBhcnNlcjIuZGVmYXVsdC5yaXBlbWQxNjAoYiwgVHlwZXMuYWRkcmVzcy5fdG9fYWRkcmVzcyhvYmplY3QpLnRvQnVmZmVyKCkpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBUeXBlcy5hZGRyZXNzLl90b19hZGRyZXNzKG9iamVjdCk7XG4gIH0sXG4gIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXggKyAnNjY0S21IeFN1UXlEc2Z3bzRXRUp2V3B6ZzFRS2RnNjdTJztcbiAgICB9XG5cbiAgICByZXR1cm4gVHlwZXMuYWRkcmVzcy5fdG9fYWRkcmVzcyhvYmplY3QpLnRvU3RyaW5nKCk7XG4gIH0sXG4gIGNvbXBhcmU6IGZ1bmN0aW9uIGNvbXBhcmUoYSwgYikge1xuICAgIHJldHVybiBzdHJDbXAoYS50b1N0cmluZygpLCBiLnRvU3RyaW5nKCkpO1xuICB9XG59O1xuXG5UeXBlcy52YXJpYW50ID0ge1xuICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHZhciB0eXBlID0gYi5yZWFkVWludDgoKTtcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIFR5cGVzLmludDY0LmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gVHlwZXMudWludDY0LmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXR1cm4gYi5yZWFkRG91YmxlKCk7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJldHVybiBUeXBlcy5ib29sLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgY2FzZSA1OlxuICAgICAgICByZXR1cm4gVHlwZXMuc3RyaW5nLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgY2FzZSA2OlxuICAgICAgICByZXR1cm4gVHlwZXMuYXJyYXkoVHlwZXMudmFyaWFudCkuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICBjYXNlIDc6XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gVHlwZXMudmFyaWFudF9vYmplY3QuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgfVxuICB9LFxuICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnbnVtYmVyJykge1xuICAgICAgaWYgKE51bWJlci5pc0ludGVnZXIob2JqZWN0KSkge1xuICAgICAgICBpZiAob2JqZWN0ID49IDApIHtcbiAgICAgICAgICBiLndyaXRlVWludDgoMik7XG4gICAgICAgICAgVHlwZXMudWludDY0LmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBiLndyaXRlVWludDgoMSk7XG4gICAgICAgICAgVHlwZXMuaW50NjQuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBiLndyaXRlVWludDgoMyk7XG4gICAgICAgIGIud3JpdGVEb3VibGUoTnVtYmVyLnBhcnNlRmxvYXQob2JqZWN0KSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnYm9vbGVhbicpIHtcbiAgICAgIGIud3JpdGVVaW50OCg0KTtcbiAgICAgIFR5cGVzLmJvb2wuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9iamVjdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGIud3JpdGVVaW50OCg1KTtcbiAgICAgIFR5cGVzLnN0cmluZy5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCk7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG9iamVjdCkpIHtcbiAgICAgIGIud3JpdGVVaW50OCg2KTtcbiAgICAgIFR5cGVzLmFycmF5KFR5cGVzLnZhcmlhbnQpLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYi53cml0ZVVpbnQ4KDcpO1xuICAgICAgVHlwZXMudmFyaWFudF9vYmplY3QuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpO1xuICAgIH1cbiAgfSxcbiAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShvYmplY3QpO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2Uob2JqZWN0KTtcbiAgfVxufTtcblxuVHlwZXMudmFyaWFudF9vYmplY3QgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgdmFyIGNvdW50ID0gYi5yZWFkVmFyaW50MzIoKTtcbiAgICB2YXIgcmVzdWx0ID0ge307XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcbiAgICAgIHZhciBrZXkgPSBUeXBlcy5zdHJpbmcuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICByZXN1bHRba2V5XSA9IFR5cGVzLnZhcmlhbnQuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7XG5cbiAgICBiLndyaXRlVmFyaW50MzIoa2V5cy5sZW5ndGgpOyAvLyBudW1iZXIgb2Yga2V5L3ZhbHVlIHBhaXJzXG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0ga2V5cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICBUeXBlcy5zdHJpbmcuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBrZXkpO1xuICAgICAgVHlwZXMudmFyaWFudC5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdFtrZXldKTtcbiAgICB9XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIG5ld09iamVjdCA9IHt9O1xuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGtleXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgbmV3T2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3T2JqZWN0O1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIG5ld09iamVjdCA9IHt9O1xuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGtleXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgbmV3T2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3T2JqZWN0O1xuICB9XG59O1xuXG5UeXBlcy5lbnVtZXJhdGlvbiA9IGZ1bmN0aW9uICh2YWx1ZXMpIHtcbiAgdmFyIGVudW1lcmF0aW9uID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICByZXR1cm4gdmFsdWVzW2IucmVhZFZhcmludDMyWmlnWmFnKCldO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgIGIud3JpdGVWYXJpbnQzMlppZ1phZyh2YWx1ZXMuaW5kZXhPZihvYmplY3QpKTtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGVudW1lcmF0aW9uO1xufTtcblxuVHlwZXMuc2hhMjU2ID0gVHlwZXMuYnl0ZXMoMzIpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBUeXBlcztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuLy8gY29tcGFyZSBhbmQgaXNCdWZmZXIgdGFrZW4gZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9ibG9iLzY4MGU5ZTVlNDg4ZjIyYWFjMjc1OTlhNTdkYzg0NGE2MzE1OTI4ZGQvaW5kZXguanNcbi8vIG9yaWdpbmFsIG5vdGljZTpcblxuLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG4gIGlmIChhID09PSBiKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICB2YXIgeCA9IGEubGVuZ3RoO1xuICB2YXIgeSA9IGIubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldO1xuICAgICAgeSA9IGJbaV07XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKHkgPCB4KSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5mdW5jdGlvbiBpc0J1ZmZlcihiKSB7XG4gIGlmIChnbG9iYWwuQnVmZmVyICYmIHR5cGVvZiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIoYik7XG4gIH1cbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcik7XG59XG5cbi8vIGJhc2VkIG9uIG5vZGUgYXNzZXJ0LCBvcmlnaW5hbCBub3RpY2U6XG5cbi8vIGh0dHA6Ly93aWtpLmNvbW1vbmpzLm9yZy93aWtpL1VuaXRfVGVzdGluZy8xLjBcbi8vXG4vLyBUSElTIElTIE5PVCBURVNURUQgTk9SIExJS0VMWSBUTyBXT1JLIE9VVFNJREUgVjghXG4vL1xuLy8gT3JpZ2luYWxseSBmcm9tIG5hcndoYWwuanMgKGh0dHA6Ly9uYXJ3aGFsanMub3JnKVxuLy8gQ29weXJpZ2h0IChjKSAyMDA5IFRob21hcyBSb2JpbnNvbiA8Mjgwbm9ydGguY29tPlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICdTb2Z0d2FyZScpLCB0b1xuLy8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAnQVMgSVMnLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU5cbi8vIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT05cbi8vIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwvJyk7XG52YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBwU2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgZnVuY3Rpb25zSGF2ZU5hbWVzID0gKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbygpIHt9Lm5hbWUgPT09ICdmb28nO1xufSgpKTtcbmZ1bmN0aW9uIHBUb1N0cmluZyAob2JqKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKTtcbn1cbmZ1bmN0aW9uIGlzVmlldyhhcnJidWYpIHtcbiAgaWYgKGlzQnVmZmVyKGFycmJ1ZikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBnbG9iYWwuQXJyYXlCdWZmZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlci5pc1ZpZXcgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQXJyYXlCdWZmZXIuaXNWaWV3KGFycmJ1Zik7XG4gIH1cbiAgaWYgKCFhcnJidWYpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGFycmJ1ZiBpbnN0YW5jZW9mIERhdGFWaWV3KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGFycmJ1Zi5idWZmZXIgJiYgYXJyYnVmLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuLy8gMS4gVGhlIGFzc2VydCBtb2R1bGUgcHJvdmlkZXMgZnVuY3Rpb25zIHRoYXQgdGhyb3dcbi8vIEFzc2VydGlvbkVycm9yJ3Mgd2hlbiBwYXJ0aWN1bGFyIGNvbmRpdGlvbnMgYXJlIG5vdCBtZXQuIFRoZVxuLy8gYXNzZXJ0IG1vZHVsZSBtdXN0IGNvbmZvcm0gdG8gdGhlIGZvbGxvd2luZyBpbnRlcmZhY2UuXG5cbnZhciBhc3NlcnQgPSBtb2R1bGUuZXhwb3J0cyA9IG9rO1xuXG4vLyAyLiBUaGUgQXNzZXJ0aW9uRXJyb3IgaXMgZGVmaW5lZCBpbiBhc3NlcnQuXG4vLyBuZXcgYXNzZXJ0LkFzc2VydGlvbkVycm9yKHsgbWVzc2FnZTogbWVzc2FnZSxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YWw6IGFjdHVhbCxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQgfSlcblxudmFyIHJlZ2V4ID0gL1xccypmdW5jdGlvblxccysoW15cXChcXHNdKilcXHMqLztcbi8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9samhhcmIvZnVuY3Rpb24ucHJvdG90eXBlLm5hbWUvYmxvYi9hZGVlZWVjOGJmY2M2MDY4YjE4N2Q3ZDlmYjNkNWJiMWQzYTMwODk5L2ltcGxlbWVudGF0aW9uLmpzXG5mdW5jdGlvbiBnZXROYW1lKGZ1bmMpIHtcbiAgaWYgKCF1dGlsLmlzRnVuY3Rpb24oZnVuYykpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGZ1bmN0aW9uc0hhdmVOYW1lcykge1xuICAgIHJldHVybiBmdW5jLm5hbWU7XG4gIH1cbiAgdmFyIHN0ciA9IGZ1bmMudG9TdHJpbmcoKTtcbiAgdmFyIG1hdGNoID0gc3RyLm1hdGNoKHJlZ2V4KTtcbiAgcmV0dXJuIG1hdGNoICYmIG1hdGNoWzFdO1xufVxuYXNzZXJ0LkFzc2VydGlvbkVycm9yID0gZnVuY3Rpb24gQXNzZXJ0aW9uRXJyb3Iob3B0aW9ucykge1xuICB0aGlzLm5hbWUgPSAnQXNzZXJ0aW9uRXJyb3InO1xuICB0aGlzLmFjdHVhbCA9IG9wdGlvbnMuYWN0dWFsO1xuICB0aGlzLmV4cGVjdGVkID0gb3B0aW9ucy5leHBlY3RlZDtcbiAgdGhpcy5vcGVyYXRvciA9IG9wdGlvbnMub3BlcmF0b3I7XG4gIGlmIChvcHRpb25zLm1lc3NhZ2UpIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBvcHRpb25zLm1lc3NhZ2U7XG4gICAgdGhpcy5nZW5lcmF0ZWRNZXNzYWdlID0gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5tZXNzYWdlID0gZ2V0TWVzc2FnZSh0aGlzKTtcbiAgICB0aGlzLmdlbmVyYXRlZE1lc3NhZ2UgPSB0cnVlO1xuICB9XG4gIHZhciBzdGFja1N0YXJ0RnVuY3Rpb24gPSBvcHRpb25zLnN0YWNrU3RhcnRGdW5jdGlvbiB8fCBmYWlsO1xuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICB9IGVsc2Uge1xuICAgIC8vIG5vbiB2OCBicm93c2VycyBzbyB3ZSBjYW4gaGF2ZSBhIHN0YWNrdHJhY2VcbiAgICB2YXIgZXJyID0gbmV3IEVycm9yKCk7XG4gICAgaWYgKGVyci5zdGFjaykge1xuICAgICAgdmFyIG91dCA9IGVyci5zdGFjaztcblxuICAgICAgLy8gdHJ5IHRvIHN0cmlwIHVzZWxlc3MgZnJhbWVzXG4gICAgICB2YXIgZm5fbmFtZSA9IGdldE5hbWUoc3RhY2tTdGFydEZ1bmN0aW9uKTtcbiAgICAgIHZhciBpZHggPSBvdXQuaW5kZXhPZignXFxuJyArIGZuX25hbWUpO1xuICAgICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICAgIC8vIG9uY2Ugd2UgaGF2ZSBsb2NhdGVkIHRoZSBmdW5jdGlvbiBmcmFtZVxuICAgICAgICAvLyB3ZSBuZWVkIHRvIHN0cmlwIG91dCBldmVyeXRoaW5nIGJlZm9yZSBpdCAoYW5kIGl0cyBsaW5lKVxuICAgICAgICB2YXIgbmV4dF9saW5lID0gb3V0LmluZGV4T2YoJ1xcbicsIGlkeCArIDEpO1xuICAgICAgICBvdXQgPSBvdXQuc3Vic3RyaW5nKG5leHRfbGluZSArIDEpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnN0YWNrID0gb3V0O1xuICAgIH1cbiAgfVxufTtcblxuLy8gYXNzZXJ0LkFzc2VydGlvbkVycm9yIGluc3RhbmNlb2YgRXJyb3JcbnV0aWwuaW5oZXJpdHMoYXNzZXJ0LkFzc2VydGlvbkVycm9yLCBFcnJvcik7XG5cbmZ1bmN0aW9uIHRydW5jYXRlKHMsIG4pIHtcbiAgaWYgKHR5cGVvZiBzID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBzLmxlbmd0aCA8IG4gPyBzIDogcy5zbGljZSgwLCBuKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcztcbiAgfVxufVxuZnVuY3Rpb24gaW5zcGVjdChzb21ldGhpbmcpIHtcbiAgaWYgKGZ1bmN0aW9uc0hhdmVOYW1lcyB8fCAhdXRpbC5pc0Z1bmN0aW9uKHNvbWV0aGluZykpIHtcbiAgICByZXR1cm4gdXRpbC5pbnNwZWN0KHNvbWV0aGluZyk7XG4gIH1cbiAgdmFyIHJhd25hbWUgPSBnZXROYW1lKHNvbWV0aGluZyk7XG4gIHZhciBuYW1lID0gcmF3bmFtZSA/ICc6ICcgKyByYXduYW1lIDogJyc7XG4gIHJldHVybiAnW0Z1bmN0aW9uJyArICBuYW1lICsgJ10nO1xufVxuZnVuY3Rpb24gZ2V0TWVzc2FnZShzZWxmKSB7XG4gIHJldHVybiB0cnVuY2F0ZShpbnNwZWN0KHNlbGYuYWN0dWFsKSwgMTI4KSArICcgJyArXG4gICAgICAgICBzZWxmLm9wZXJhdG9yICsgJyAnICtcbiAgICAgICAgIHRydW5jYXRlKGluc3BlY3Qoc2VsZi5leHBlY3RlZCksIDEyOCk7XG59XG5cbi8vIEF0IHByZXNlbnQgb25seSB0aGUgdGhyZWUga2V5cyBtZW50aW9uZWQgYWJvdmUgYXJlIHVzZWQgYW5kXG4vLyB1bmRlcnN0b29kIGJ5IHRoZSBzcGVjLiBJbXBsZW1lbnRhdGlvbnMgb3Igc3ViIG1vZHVsZXMgY2FuIHBhc3Ncbi8vIG90aGVyIGtleXMgdG8gdGhlIEFzc2VydGlvbkVycm9yJ3MgY29uc3RydWN0b3IgLSB0aGV5IHdpbGwgYmVcbi8vIGlnbm9yZWQuXG5cbi8vIDMuIEFsbCBvZiB0aGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBtdXN0IHRocm93IGFuIEFzc2VydGlvbkVycm9yXG4vLyB3aGVuIGEgY29ycmVzcG9uZGluZyBjb25kaXRpb24gaXMgbm90IG1ldCwgd2l0aCBhIG1lc3NhZ2UgdGhhdFxuLy8gbWF5IGJlIHVuZGVmaW5lZCBpZiBub3QgcHJvdmlkZWQuICBBbGwgYXNzZXJ0aW9uIG1ldGhvZHMgcHJvdmlkZVxuLy8gYm90aCB0aGUgYWN0dWFsIGFuZCBleHBlY3RlZCB2YWx1ZXMgdG8gdGhlIGFzc2VydGlvbiBlcnJvciBmb3Jcbi8vIGRpc3BsYXkgcHVycG9zZXMuXG5cbmZ1bmN0aW9uIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgb3BlcmF0b3IsIHN0YWNrU3RhcnRGdW5jdGlvbikge1xuICB0aHJvdyBuZXcgYXNzZXJ0LkFzc2VydGlvbkVycm9yKHtcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIGFjdHVhbDogYWN0dWFsLFxuICAgIGV4cGVjdGVkOiBleHBlY3RlZCxcbiAgICBvcGVyYXRvcjogb3BlcmF0b3IsXG4gICAgc3RhY2tTdGFydEZ1bmN0aW9uOiBzdGFja1N0YXJ0RnVuY3Rpb25cbiAgfSk7XG59XG5cbi8vIEVYVEVOU0lPTiEgYWxsb3dzIGZvciB3ZWxsIGJlaGF2ZWQgZXJyb3JzIGRlZmluZWQgZWxzZXdoZXJlLlxuYXNzZXJ0LmZhaWwgPSBmYWlsO1xuXG4vLyA0LiBQdXJlIGFzc2VydGlvbiB0ZXN0cyB3aGV0aGVyIGEgdmFsdWUgaXMgdHJ1dGh5LCBhcyBkZXRlcm1pbmVkXG4vLyBieSAhIWd1YXJkLlxuLy8gYXNzZXJ0Lm9rKGd1YXJkLCBtZXNzYWdlX29wdCk7XG4vLyBUaGlzIHN0YXRlbWVudCBpcyBlcXVpdmFsZW50IHRvIGFzc2VydC5lcXVhbCh0cnVlLCAhIWd1YXJkLFxuLy8gbWVzc2FnZV9vcHQpOy4gVG8gdGVzdCBzdHJpY3RseSBmb3IgdGhlIHZhbHVlIHRydWUsIHVzZVxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKHRydWUsIGd1YXJkLCBtZXNzYWdlX29wdCk7LlxuXG5mdW5jdGlvbiBvayh2YWx1ZSwgbWVzc2FnZSkge1xuICBpZiAoIXZhbHVlKSBmYWlsKHZhbHVlLCB0cnVlLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQub2spO1xufVxuYXNzZXJ0Lm9rID0gb2s7XG5cbi8vIDUuIFRoZSBlcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgc2hhbGxvdywgY29lcmNpdmUgZXF1YWxpdHkgd2l0aFxuLy8gPT0uXG4vLyBhc3NlcnQuZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBlcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgIT0gZXhwZWN0ZWQpIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09JywgYXNzZXJ0LmVxdWFsKTtcbn07XG5cbi8vIDYuIFRoZSBub24tZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIGZvciB3aGV0aGVyIHR3byBvYmplY3RzIGFyZSBub3QgZXF1YWxcbi8vIHdpdGggIT0gYXNzZXJ0Lm5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdEVxdWFsID0gZnVuY3Rpb24gbm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsID09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT0nLCBhc3NlcnQubm90RXF1YWwpO1xuICB9XG59O1xuXG4vLyA3LiBUaGUgZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGEgZGVlcCBlcXVhbGl0eSByZWxhdGlvbi5cbi8vIGFzc2VydC5kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuZGVlcEVxdWFsID0gZnVuY3Rpb24gZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKCFfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIGZhbHNlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ2RlZXBFcXVhbCcsIGFzc2VydC5kZWVwRXF1YWwpO1xuICB9XG59O1xuXG5hc3NlcnQuZGVlcFN0cmljdEVxdWFsID0gZnVuY3Rpb24gZGVlcFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKCFfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIHRydWUpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnZGVlcFN0cmljdEVxdWFsJywgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgc3RyaWN0LCBtZW1vcykge1xuICAvLyA3LjEuIEFsbCBpZGVudGljYWwgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChpc0J1ZmZlcihhY3R1YWwpICYmIGlzQnVmZmVyKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBjb21wYXJlKGFjdHVhbCwgZXhwZWN0ZWQpID09PSAwO1xuXG4gIC8vIDcuMi4gSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgRGF0ZSBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgRGF0ZSBvYmplY3QgdGhhdCByZWZlcnMgdG8gdGhlIHNhbWUgdGltZS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzRGF0ZShhY3R1YWwpICYmIHV0aWwuaXNEYXRlKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuZ2V0VGltZSgpID09PSBleHBlY3RlZC5nZXRUaW1lKCk7XG5cbiAgLy8gNy4zIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIFJlZ0V4cCBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgUmVnRXhwIG9iamVjdCB3aXRoIHRoZSBzYW1lIHNvdXJjZSBhbmRcbiAgLy8gcHJvcGVydGllcyAoYGdsb2JhbGAsIGBtdWx0aWxpbmVgLCBgbGFzdEluZGV4YCwgYGlnbm9yZUNhc2VgKS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzUmVnRXhwKGFjdHVhbCkgJiYgdXRpbC5pc1JlZ0V4cChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLnNvdXJjZSA9PT0gZXhwZWN0ZWQuc291cmNlICYmXG4gICAgICAgICAgIGFjdHVhbC5nbG9iYWwgPT09IGV4cGVjdGVkLmdsb2JhbCAmJlxuICAgICAgICAgICBhY3R1YWwubXVsdGlsaW5lID09PSBleHBlY3RlZC5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgYWN0dWFsLmxhc3RJbmRleCA9PT0gZXhwZWN0ZWQubGFzdEluZGV4ICYmXG4gICAgICAgICAgIGFjdHVhbC5pZ25vcmVDYXNlID09PSBleHBlY3RlZC5pZ25vcmVDYXNlO1xuXG4gIC8vIDcuNC4gT3RoZXIgcGFpcnMgdGhhdCBkbyBub3QgYm90aCBwYXNzIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JyxcbiAgLy8gZXF1aXZhbGVuY2UgaXMgZGV0ZXJtaW5lZCBieSA9PS5cbiAgfSBlbHNlIGlmICgoYWN0dWFsID09PSBudWxsIHx8IHR5cGVvZiBhY3R1YWwgIT09ICdvYmplY3QnKSAmJlxuICAgICAgICAgICAgIChleHBlY3RlZCA9PT0gbnVsbCB8fCB0eXBlb2YgZXhwZWN0ZWQgIT09ICdvYmplY3QnKSkge1xuICAgIHJldHVybiBzdHJpY3QgPyBhY3R1YWwgPT09IGV4cGVjdGVkIDogYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIElmIGJvdGggdmFsdWVzIGFyZSBpbnN0YW5jZXMgb2YgdHlwZWQgYXJyYXlzLCB3cmFwIHRoZWlyIHVuZGVybHlpbmdcbiAgLy8gQXJyYXlCdWZmZXJzIGluIGEgQnVmZmVyIGVhY2ggdG8gaW5jcmVhc2UgcGVyZm9ybWFuY2VcbiAgLy8gVGhpcyBvcHRpbWl6YXRpb24gcmVxdWlyZXMgdGhlIGFycmF5cyB0byBoYXZlIHRoZSBzYW1lIHR5cGUgYXMgY2hlY2tlZCBieVxuICAvLyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nIChha2EgcFRvU3RyaW5nKS4gTmV2ZXIgcGVyZm9ybSBiaW5hcnlcbiAgLy8gY29tcGFyaXNvbnMgZm9yIEZsb2F0KkFycmF5cywgdGhvdWdoLCBzaW5jZSBlLmcuICswID09PSAtMCBidXQgdGhlaXJcbiAgLy8gYml0IHBhdHRlcm5zIGFyZSBub3QgaWRlbnRpY2FsLlxuICB9IGVsc2UgaWYgKGlzVmlldyhhY3R1YWwpICYmIGlzVmlldyhleHBlY3RlZCkgJiZcbiAgICAgICAgICAgICBwVG9TdHJpbmcoYWN0dWFsKSA9PT0gcFRvU3RyaW5nKGV4cGVjdGVkKSAmJlxuICAgICAgICAgICAgICEoYWN0dWFsIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5IHx8XG4gICAgICAgICAgICAgICBhY3R1YWwgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkpKSB7XG4gICAgcmV0dXJuIGNvbXBhcmUobmV3IFVpbnQ4QXJyYXkoYWN0dWFsLmJ1ZmZlciksXG4gICAgICAgICAgICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoZXhwZWN0ZWQuYnVmZmVyKSkgPT09IDA7XG5cbiAgLy8gNy41IEZvciBhbGwgb3RoZXIgT2JqZWN0IHBhaXJzLCBpbmNsdWRpbmcgQXJyYXkgb2JqZWN0cywgZXF1aXZhbGVuY2UgaXNcbiAgLy8gZGV0ZXJtaW5lZCBieSBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGFzIHZlcmlmaWVkXG4gIC8vIHdpdGggT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKSwgdGhlIHNhbWUgc2V0IG9mIGtleXNcbiAgLy8gKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksIGVxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeVxuICAvLyBjb3JyZXNwb25kaW5nIGtleSwgYW5kIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS4gTm90ZTogdGhpc1xuICAvLyBhY2NvdW50cyBmb3IgYm90aCBuYW1lZCBhbmQgaW5kZXhlZCBwcm9wZXJ0aWVzIG9uIEFycmF5cy5cbiAgfSBlbHNlIGlmIChpc0J1ZmZlcihhY3R1YWwpICE9PSBpc0J1ZmZlcihleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgbWVtb3MgPSBtZW1vcyB8fCB7YWN0dWFsOiBbXSwgZXhwZWN0ZWQ6IFtdfTtcblxuICAgIHZhciBhY3R1YWxJbmRleCA9IG1lbW9zLmFjdHVhbC5pbmRleE9mKGFjdHVhbCk7XG4gICAgaWYgKGFjdHVhbEluZGV4ICE9PSAtMSkge1xuICAgICAgaWYgKGFjdHVhbEluZGV4ID09PSBtZW1vcy5leHBlY3RlZC5pbmRleE9mKGV4cGVjdGVkKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBtZW1vcy5hY3R1YWwucHVzaChhY3R1YWwpO1xuICAgIG1lbW9zLmV4cGVjdGVkLnB1c2goZXhwZWN0ZWQpO1xuXG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQsIHN0cmljdCwgbWVtb3MpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIsIHN0cmljdCwgYWN0dWFsVmlzaXRlZE9iamVjdHMpIHtcbiAgaWYgKGEgPT09IG51bGwgfHwgYSA9PT0gdW5kZWZpbmVkIHx8IGIgPT09IG51bGwgfHwgYiA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy8gaWYgb25lIGlzIGEgcHJpbWl0aXZlLCB0aGUgb3RoZXIgbXVzdCBiZSBzYW1lXG4gIGlmICh1dGlsLmlzUHJpbWl0aXZlKGEpIHx8IHV0aWwuaXNQcmltaXRpdmUoYikpXG4gICAgcmV0dXJuIGEgPT09IGI7XG4gIGlmIChzdHJpY3QgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpICE9PSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYikpXG4gICAgcmV0dXJuIGZhbHNlO1xuICB2YXIgYUlzQXJncyA9IGlzQXJndW1lbnRzKGEpO1xuICB2YXIgYklzQXJncyA9IGlzQXJndW1lbnRzKGIpO1xuICBpZiAoKGFJc0FyZ3MgJiYgIWJJc0FyZ3MpIHx8ICghYUlzQXJncyAmJiBiSXNBcmdzKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIGlmIChhSXNBcmdzKSB7XG4gICAgYSA9IHBTbGljZS5jYWxsKGEpO1xuICAgIGIgPSBwU2xpY2UuY2FsbChiKTtcbiAgICByZXR1cm4gX2RlZXBFcXVhbChhLCBiLCBzdHJpY3QpO1xuICB9XG4gIHZhciBrYSA9IG9iamVjdEtleXMoYSk7XG4gIHZhciBrYiA9IG9iamVjdEtleXMoYik7XG4gIHZhciBrZXksIGk7XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT09IGtiLmxlbmd0aClcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vdGhlIHNhbWUgc2V0IG9mIGtleXMgKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksXG4gIGthLnNvcnQoKTtcbiAga2Iuc29ydCgpO1xuICAvL35+fmNoZWFwIGtleSB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGthW2ldICE9PSBrYltpXSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvL2VxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeSBjb3JyZXNwb25kaW5nIGtleSwgYW5kXG4gIC8vfn5+cG9zc2libHkgZXhwZW5zaXZlIGRlZXAgdGVzdFxuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGtleSA9IGthW2ldO1xuICAgIGlmICghX2RlZXBFcXVhbChhW2tleV0sIGJba2V5XSwgc3RyaWN0LCBhY3R1YWxWaXNpdGVkT2JqZWN0cykpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIDguIFRoZSBub24tZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGZvciBhbnkgZGVlcCBpbmVxdWFsaXR5LlxuLy8gYXNzZXJ0Lm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3REZWVwRXF1YWwgPSBmdW5jdGlvbiBub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBmYWxzZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdub3REZWVwRXF1YWwnLCBhc3NlcnQubm90RGVlcEVxdWFsKTtcbiAgfVxufTtcblxuYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbCA9IG5vdERlZXBTdHJpY3RFcXVhbDtcbmZ1bmN0aW9uIG5vdERlZXBTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIHRydWUpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnbm90RGVlcFN0cmljdEVxdWFsJywgbm90RGVlcFN0cmljdEVxdWFsKTtcbiAgfVxufVxuXG5cbi8vIDkuIFRoZSBzdHJpY3QgZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIHN0cmljdCBlcXVhbGl0eSwgYXMgZGV0ZXJtaW5lZCBieSA9PT0uXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuc3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBzdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgIT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT09JywgYXNzZXJ0LnN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuLy8gMTAuIFRoZSBzdHJpY3Qgbm9uLWVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBmb3Igc3RyaWN0IGluZXF1YWxpdHksIGFzXG4vLyBkZXRlcm1pbmVkIGJ5ICE9PS4gIGFzc2VydC5ub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3RTdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIG5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPT0nLCBhc3NlcnQubm90U3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIGlmICghYWN0dWFsIHx8ICFleHBlY3RlZCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZXhwZWN0ZWQpID09ICdbb2JqZWN0IFJlZ0V4cF0nKSB7XG4gICAgcmV0dXJuIGV4cGVjdGVkLnRlc3QoYWN0dWFsKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgaWYgKGFjdHVhbCBpbnN0YW5jZW9mIGV4cGVjdGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBJZ25vcmUuICBUaGUgaW5zdGFuY2VvZiBjaGVjayBkb2Vzbid0IHdvcmsgZm9yIGFycm93IGZ1bmN0aW9ucy5cbiAgfVxuXG4gIGlmIChFcnJvci5pc1Byb3RvdHlwZU9mKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBleHBlY3RlZC5jYWxsKHt9LCBhY3R1YWwpID09PSB0cnVlO1xufVxuXG5mdW5jdGlvbiBfdHJ5QmxvY2soYmxvY2spIHtcbiAgdmFyIGVycm9yO1xuICB0cnkge1xuICAgIGJsb2NrKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnJvciA9IGU7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuXG5mdW5jdGlvbiBfdGhyb3dzKHNob3VsZFRocm93LCBibG9jaywgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgdmFyIGFjdHVhbDtcblxuICBpZiAodHlwZW9mIGJsb2NrICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJibG9ja1wiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBleHBlY3RlZCA9PT0gJ3N0cmluZycpIHtcbiAgICBtZXNzYWdlID0gZXhwZWN0ZWQ7XG4gICAgZXhwZWN0ZWQgPSBudWxsO1xuICB9XG5cbiAgYWN0dWFsID0gX3RyeUJsb2NrKGJsb2NrKTtcblxuICBtZXNzYWdlID0gKGV4cGVjdGVkICYmIGV4cGVjdGVkLm5hbWUgPyAnICgnICsgZXhwZWN0ZWQubmFtZSArICcpLicgOiAnLicpICtcbiAgICAgICAgICAgIChtZXNzYWdlID8gJyAnICsgbWVzc2FnZSA6ICcuJyk7XG5cbiAgaWYgKHNob3VsZFRocm93ICYmICFhY3R1YWwpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdNaXNzaW5nIGV4cGVjdGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIHZhciB1c2VyUHJvdmlkZWRNZXNzYWdlID0gdHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnO1xuICB2YXIgaXNVbndhbnRlZEV4Y2VwdGlvbiA9ICFzaG91bGRUaHJvdyAmJiB1dGlsLmlzRXJyb3IoYWN0dWFsKTtcbiAgdmFyIGlzVW5leHBlY3RlZEV4Y2VwdGlvbiA9ICFzaG91bGRUaHJvdyAmJiBhY3R1YWwgJiYgIWV4cGVjdGVkO1xuXG4gIGlmICgoaXNVbndhbnRlZEV4Y2VwdGlvbiAmJlxuICAgICAgdXNlclByb3ZpZGVkTWVzc2FnZSAmJlxuICAgICAgZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8XG4gICAgICBpc1VuZXhwZWN0ZWRFeGNlcHRpb24pIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdHb3QgdW53YW50ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgaWYgKChzaG91bGRUaHJvdyAmJiBhY3R1YWwgJiYgZXhwZWN0ZWQgJiZcbiAgICAgICFleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkgfHwgKCFzaG91bGRUaHJvdyAmJiBhY3R1YWwpKSB7XG4gICAgdGhyb3cgYWN0dWFsO1xuICB9XG59XG5cbi8vIDExLiBFeHBlY3RlZCB0byB0aHJvdyBhbiBlcnJvcjpcbi8vIGFzc2VydC50aHJvd3MoYmxvY2ssIEVycm9yX29wdCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQudGhyb3dzID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL2Vycm9yLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3ModHJ1ZSwgYmxvY2ssIGVycm9yLCBtZXNzYWdlKTtcbn07XG5cbi8vIEVYVEVOU0lPTiEgVGhpcyBpcyBhbm5veWluZyB0byB3cml0ZSBvdXRzaWRlIHRoaXMgbW9kdWxlLlxuYXNzZXJ0LmRvZXNOb3RUaHJvdyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzKGZhbHNlLCBibG9jaywgZXJyb3IsIG1lc3NhZ2UpO1xufTtcblxuYXNzZXJ0LmlmRXJyb3IgPSBmdW5jdGlvbihlcnIpIHsgaWYgKGVycikgdGhyb3cgZXJyOyB9O1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXNPd24uY2FsbChvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufTtcbiIsIi8vIGJhc2UteCBlbmNvZGluZ1xuLy8gRm9ya2VkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2NyeXB0b2NvaW5qcy9iczU4XG4vLyBPcmlnaW5hbGx5IHdyaXR0ZW4gYnkgTWlrZSBIZWFybiBmb3IgQml0Y29pbkpcbi8vIENvcHlyaWdodCAoYykgMjAxMSBHb29nbGUgSW5jXG4vLyBQb3J0ZWQgdG8gSmF2YVNjcmlwdCBieSBTdGVmYW4gVGhvbWFzXG4vLyBNZXJnZWQgQnVmZmVyIHJlZmFjdG9yaW5ncyBmcm9tIGJhc2U1OC1uYXRpdmUgYnkgU3RlcGhlbiBQYWlyXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTMgQml0UGF5IEluY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJhc2UgKEFMUEhBQkVUKSB7XG4gIHZhciBBTFBIQUJFVF9NQVAgPSB7fVxuICB2YXIgQkFTRSA9IEFMUEhBQkVULmxlbmd0aFxuICB2YXIgTEVBREVSID0gQUxQSEFCRVQuY2hhckF0KDApXG5cbiAgLy8gcHJlLWNvbXB1dGUgbG9va3VwIHRhYmxlXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgQUxQSEFCRVQubGVuZ3RoOyBpKyspIHtcbiAgICBBTFBIQUJFVF9NQVBbQUxQSEFCRVQuY2hhckF0KGkpXSA9IGlcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuY29kZSAoc291cmNlKSB7XG4gICAgaWYgKHNvdXJjZS5sZW5ndGggPT09IDApIHJldHVybiAnJ1xuXG4gICAgdmFyIGRpZ2l0cyA9IFswXVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aDsgKytpKSB7XG4gICAgICBmb3IgKHZhciBqID0gMCwgY2FycnkgPSBzb3VyY2VbaV07IGogPCBkaWdpdHMubGVuZ3RoOyArK2opIHtcbiAgICAgICAgY2FycnkgKz0gZGlnaXRzW2pdIDw8IDhcbiAgICAgICAgZGlnaXRzW2pdID0gY2FycnkgJSBCQVNFXG4gICAgICAgIGNhcnJ5ID0gKGNhcnJ5IC8gQkFTRSkgfCAwXG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChjYXJyeSA+IDApIHtcbiAgICAgICAgZGlnaXRzLnB1c2goY2FycnkgJSBCQVNFKVxuICAgICAgICBjYXJyeSA9IChjYXJyeSAvIEJBU0UpIHwgMFxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBzdHJpbmcgPSAnJ1xuXG4gICAgLy8gZGVhbCB3aXRoIGxlYWRpbmcgemVyb3NcbiAgICBmb3IgKHZhciBrID0gMDsgc291cmNlW2tdID09PSAwICYmIGsgPCBzb3VyY2UubGVuZ3RoIC0gMTsgKytrKSBzdHJpbmcgKz0gQUxQSEFCRVRbMF1cbiAgICAvLyBjb252ZXJ0IGRpZ2l0cyB0byBhIHN0cmluZ1xuICAgIGZvciAodmFyIHEgPSBkaWdpdHMubGVuZ3RoIC0gMTsgcSA+PSAwOyAtLXEpIHN0cmluZyArPSBBTFBIQUJFVFtkaWdpdHNbcV1dXG5cbiAgICByZXR1cm4gc3RyaW5nXG4gIH1cblxuICBmdW5jdGlvbiBkZWNvZGVVbnNhZmUgKHN0cmluZykge1xuICAgIGlmIChzdHJpbmcubGVuZ3RoID09PSAwKSByZXR1cm4gW11cblxuICAgIHZhciBieXRlcyA9IFswXVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdmFsdWUgPSBBTFBIQUJFVF9NQVBbc3RyaW5nW2ldXVxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVyblxuXG4gICAgICBmb3IgKHZhciBqID0gMCwgY2FycnkgPSB2YWx1ZTsgaiA8IGJ5dGVzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIGNhcnJ5ICs9IGJ5dGVzW2pdICogQkFTRVxuICAgICAgICBieXRlc1tqXSA9IGNhcnJ5ICYgMHhmZlxuICAgICAgICBjYXJyeSA+Pj0gOFxuICAgICAgfVxuXG4gICAgICB3aGlsZSAoY2FycnkgPiAwKSB7XG4gICAgICAgIGJ5dGVzLnB1c2goY2FycnkgJiAweGZmKVxuICAgICAgICBjYXJyeSA+Pj0gOFxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGRlYWwgd2l0aCBsZWFkaW5nIHplcm9zXG4gICAgZm9yICh2YXIgayA9IDA7IHN0cmluZ1trXSA9PT0gTEVBREVSICYmIGsgPCBzdHJpbmcubGVuZ3RoIC0gMTsgKytrKSB7XG4gICAgICBieXRlcy5wdXNoKDApXG4gICAgfVxuXG4gICAgcmV0dXJuIGJ5dGVzLnJldmVyc2UoKVxuICB9XG5cbiAgZnVuY3Rpb24gZGVjb2RlIChzdHJpbmcpIHtcbiAgICB2YXIgYXJyYXkgPSBkZWNvZGVVbnNhZmUoc3RyaW5nKVxuICAgIGlmIChhcnJheSkgcmV0dXJuIGFycmF5XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05vbi1iYXNlJyArIEJBU0UgKyAnIGNoYXJhY3RlcicpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGVuY29kZTogZW5jb2RlLFxuICAgIGRlY29kZVVuc2FmZTogZGVjb2RlVW5zYWZlLFxuICAgIGRlY29kZTogZGVjb2RlXG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0J1xuXG5leHBvcnRzLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5leHBvcnRzLnRvQnl0ZUFycmF5ID0gdG9CeXRlQXJyYXlcbmV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IGZyb21CeXRlQXJyYXlcblxudmFyIGxvb2t1cCA9IFtdXG52YXIgcmV2TG9va3VwID0gW11cbnZhciBBcnIgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBVaW50OEFycmF5IDogQXJyYXlcblxudmFyIGNvZGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcbmZvciAodmFyIGkgPSAwLCBsZW4gPSBjb2RlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gIGxvb2t1cFtpXSA9IGNvZGVbaV1cbiAgcmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV0gPSBpXG59XG5cbi8vIFN1cHBvcnQgZGVjb2RpbmcgVVJMLXNhZmUgYmFzZTY0IHN0cmluZ3MsIGFzIE5vZGUuanMgZG9lcy5cbi8vIFNlZTogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQmFzZTY0I1VSTF9hcHBsaWNhdGlvbnNcbnJldkxvb2t1cFsnLScuY2hhckNvZGVBdCgwKV0gPSA2MlxucmV2TG9va3VwWydfJy5jaGFyQ29kZUF0KDApXSA9IDYzXG5cbmZ1bmN0aW9uIGdldExlbnMgKGI2NCkge1xuICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXG4gIGlmIChsZW4gJSA0ID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG4gIH1cblxuICAvLyBUcmltIG9mZiBleHRyYSBieXRlcyBhZnRlciBwbGFjZWhvbGRlciBieXRlcyBhcmUgZm91bmRcbiAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vYmVhdGdhbW1pdC9iYXNlNjQtanMvaXNzdWVzLzQyXG4gIHZhciB2YWxpZExlbiA9IGI2NC5pbmRleE9mKCc9JylcbiAgaWYgKHZhbGlkTGVuID09PSAtMSkgdmFsaWRMZW4gPSBsZW5cblxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gdmFsaWRMZW4gPT09IGxlblxuICAgID8gMFxuICAgIDogNCAtICh2YWxpZExlbiAlIDQpXG5cbiAgcmV0dXJuIFt2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuXVxufVxuXG4vLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKGI2NCkge1xuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiBfYnl0ZUxlbmd0aCAoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSB7XG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiB0b0J5dGVBcnJheSAoYjY0KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuXG4gIHZhciBhcnIgPSBuZXcgQXJyKF9ieXRlTGVuZ3RoKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikpXG5cbiAgdmFyIGN1ckJ5dGUgPSAwXG5cbiAgLy8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuICB2YXIgbGVuID0gcGxhY2VIb2xkZXJzTGVuID4gMFxuICAgID8gdmFsaWRMZW4gLSA0XG4gICAgOiB2YWxpZExlblxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHxcbiAgICAgIHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAyKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMSkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArXG4gICAgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9XG4gICAgICAoKHVpbnQ4W2ldIDw8IDE2KSAmIDB4RkYwMDAwKSArXG4gICAgICAoKHVpbnQ4W2kgKyAxXSA8PCA4KSAmIDB4RkYwMCkgK1xuICAgICAgKHVpbnQ4W2kgKyAyXSAmIDB4RkYpXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsoXG4gICAgICB1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpXG4gICAgKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDJdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl0gK1xuICAgICAgJz09J1xuICAgIClcbiAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgdG1wID0gKHVpbnQ4W2xlbiAtIDJdIDw8IDgpICsgdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAxMF0gK1xuICAgICAgbG9va3VwWyh0bXAgPj4gNCkgJiAweDNGXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCAyKSAmIDB4M0ZdICtcbiAgICAgICc9J1xuICAgIClcbiAgfVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuIiwiLy8gKHB1YmxpYykgQ29uc3RydWN0b3JcbmZ1bmN0aW9uIEJpZ0ludGVnZXIoYSwgYiwgYykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQmlnSW50ZWdlcikpXG4gICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGEsIGIsIGMpXG5cbiAgaWYgKGEgIT0gbnVsbCkge1xuICAgIGlmIChcIm51bWJlclwiID09IHR5cGVvZiBhKSB0aGlzLmZyb21OdW1iZXIoYSwgYiwgYylcbiAgICBlbHNlIGlmIChiID09IG51bGwgJiYgXCJzdHJpbmdcIiAhPSB0eXBlb2YgYSkgdGhpcy5mcm9tU3RyaW5nKGEsIDI1NilcbiAgICBlbHNlIHRoaXMuZnJvbVN0cmluZyhhLCBiKVxuICB9XG59XG5cbnZhciBwcm90byA9IEJpZ0ludGVnZXIucHJvdG90eXBlXG5cbi8vIGR1Y2stdHlwZWQgaXNCaWdJbnRlZ2VyXG5wcm90by5fX2JpZ2kgPSByZXF1aXJlKDMzKS52ZXJzaW9uXG5CaWdJbnRlZ2VyLmlzQmlnSW50ZWdlciA9IGZ1bmN0aW9uIChvYmosIGNoZWNrX3Zlcikge1xuICByZXR1cm4gb2JqICYmIG9iai5fX2JpZ2kgJiYgKCFjaGVja192ZXIgfHwgb2JqLl9fYmlnaSA9PT0gcHJvdG8uX19iaWdpKVxufVxuXG4vLyBCaXRzIHBlciBkaWdpdFxudmFyIGRiaXRzXG5cbi8vIGFtOiBDb21wdXRlIHdfaiArPSAoeCp0aGlzX2kpLCBwcm9wYWdhdGUgY2Fycmllcyxcbi8vIGMgaXMgaW5pdGlhbCBjYXJyeSwgcmV0dXJucyBmaW5hbCBjYXJyeS5cbi8vIGMgPCAzKmR2YWx1ZSwgeCA8IDIqZHZhbHVlLCB0aGlzX2kgPCBkdmFsdWVcbi8vIFdlIG5lZWQgdG8gc2VsZWN0IHRoZSBmYXN0ZXN0IG9uZSB0aGF0IHdvcmtzIGluIHRoaXMgZW52aXJvbm1lbnQuXG5cbi8vIGFtMTogdXNlIGEgc2luZ2xlIG11bHQgYW5kIGRpdmlkZSB0byBnZXQgdGhlIGhpZ2ggYml0cyxcbi8vIG1heCBkaWdpdCBiaXRzIHNob3VsZCBiZSAyNiBiZWNhdXNlXG4vLyBtYXggaW50ZXJuYWwgdmFsdWUgPSAyKmR2YWx1ZV4yLTIqZHZhbHVlICg8IDJeNTMpXG5mdW5jdGlvbiBhbTEoaSwgeCwgdywgaiwgYywgbikge1xuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgdiA9IHggKiB0aGlzW2krK10gKyB3W2pdICsgY1xuICAgIGMgPSBNYXRoLmZsb29yKHYgLyAweDQwMDAwMDApXG4gICAgd1tqKytdID0gdiAmIDB4M2ZmZmZmZlxuICB9XG4gIHJldHVybiBjXG59XG4vLyBhbTIgYXZvaWRzIGEgYmlnIG11bHQtYW5kLWV4dHJhY3QgY29tcGxldGVseS5cbi8vIE1heCBkaWdpdCBiaXRzIHNob3VsZCBiZSA8PSAzMCBiZWNhdXNlIHdlIGRvIGJpdHdpc2Ugb3BzXG4vLyBvbiB2YWx1ZXMgdXAgdG8gMipoZHZhbHVlXjItaGR2YWx1ZS0xICg8IDJeMzEpXG5mdW5jdGlvbiBhbTIoaSwgeCwgdywgaiwgYywgbikge1xuICB2YXIgeGwgPSB4ICYgMHg3ZmZmLFxuICAgIHhoID0geCA+PiAxNVxuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgbCA9IHRoaXNbaV0gJiAweDdmZmZcbiAgICB2YXIgaCA9IHRoaXNbaSsrXSA+PiAxNVxuICAgIHZhciBtID0geGggKiBsICsgaCAqIHhsXG4gICAgbCA9IHhsICogbCArICgobSAmIDB4N2ZmZikgPDwgMTUpICsgd1tqXSArIChjICYgMHgzZmZmZmZmZilcbiAgICBjID0gKGwgPj4+IDMwKSArIChtID4+PiAxNSkgKyB4aCAqIGggKyAoYyA+Pj4gMzApXG4gICAgd1tqKytdID0gbCAmIDB4M2ZmZmZmZmZcbiAgfVxuICByZXR1cm4gY1xufVxuLy8gQWx0ZXJuYXRlbHksIHNldCBtYXggZGlnaXQgYml0cyB0byAyOCBzaW5jZSBzb21lXG4vLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuXG5mdW5jdGlvbiBhbTMoaSwgeCwgdywgaiwgYywgbikge1xuICB2YXIgeGwgPSB4ICYgMHgzZmZmLFxuICAgIHhoID0geCA+PiAxNFxuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgbCA9IHRoaXNbaV0gJiAweDNmZmZcbiAgICB2YXIgaCA9IHRoaXNbaSsrXSA+PiAxNFxuICAgIHZhciBtID0geGggKiBsICsgaCAqIHhsXG4gICAgbCA9IHhsICogbCArICgobSAmIDB4M2ZmZikgPDwgMTQpICsgd1tqXSArIGNcbiAgICBjID0gKGwgPj4gMjgpICsgKG0gPj4gMTQpICsgeGggKiBoXG4gICAgd1tqKytdID0gbCAmIDB4ZmZmZmZmZlxuICB9XG4gIHJldHVybiBjXG59XG5cbi8vIHd0Zj9cbkJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0xXG5kYml0cyA9IDI2XG5cbkJpZ0ludGVnZXIucHJvdG90eXBlLkRCID0gZGJpdHNcbkJpZ0ludGVnZXIucHJvdG90eXBlLkRNID0gKCgxIDw8IGRiaXRzKSAtIDEpXG52YXIgRFYgPSBCaWdJbnRlZ2VyLnByb3RvdHlwZS5EViA9ICgxIDw8IGRiaXRzKVxuXG52YXIgQklfRlAgPSA1MlxuQmlnSW50ZWdlci5wcm90b3R5cGUuRlYgPSBNYXRoLnBvdygyLCBCSV9GUClcbkJpZ0ludGVnZXIucHJvdG90eXBlLkYxID0gQklfRlAgLSBkYml0c1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyICogZGJpdHMgLSBCSV9GUFxuXG4vLyBEaWdpdCBjb252ZXJzaW9uc1xudmFyIEJJX1JNID0gXCIwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIlxudmFyIEJJX1JDID0gbmV3IEFycmF5KClcbnZhciByciwgdnZcbnJyID0gXCIwXCIuY2hhckNvZGVBdCgwKVxuZm9yICh2diA9IDA7IHZ2IDw9IDk7ICsrdnYpIEJJX1JDW3JyKytdID0gdnZcbnJyID0gXCJhXCIuY2hhckNvZGVBdCgwKVxuZm9yICh2diA9IDEwOyB2diA8IDM2OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2XG5yciA9IFwiQVwiLmNoYXJDb2RlQXQoMClcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2dlxuXG5mdW5jdGlvbiBpbnQyY2hhcihuKSB7XG4gIHJldHVybiBCSV9STS5jaGFyQXQobilcbn1cblxuZnVuY3Rpb24gaW50QXQocywgaSkge1xuICB2YXIgYyA9IEJJX1JDW3MuY2hhckNvZGVBdChpKV1cbiAgcmV0dXJuIChjID09IG51bGwpID8gLTEgOiBjXG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvcHkgdGhpcyB0byByXG5mdW5jdGlvbiBibnBDb3B5VG8ocikge1xuICBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSB0aGlzW2ldXG4gIHIudCA9IHRoaXMudFxuICByLnMgPSB0aGlzLnNcbn1cblxuLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gaW50ZWdlciB2YWx1ZSB4LCAtRFYgPD0geCA8IERWXG5mdW5jdGlvbiBibnBGcm9tSW50KHgpIHtcbiAgdGhpcy50ID0gMVxuICB0aGlzLnMgPSAoeCA8IDApID8gLTEgOiAwXG4gIGlmICh4ID4gMCkgdGhpc1swXSA9IHhcbiAgZWxzZSBpZiAoeCA8IC0xKSB0aGlzWzBdID0geCArIERWXG4gIGVsc2UgdGhpcy50ID0gMFxufVxuXG4vLyByZXR1cm4gYmlnaW50IGluaXRpYWxpemVkIHRvIHZhbHVlXG5mdW5jdGlvbiBuYnYoaSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgci5mcm9tSW50KGkpXG4gIHJldHVybiByXG59XG5cbi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIHN0cmluZyBhbmQgcmFkaXhcbmZ1bmN0aW9uIGJucEZyb21TdHJpbmcocywgYikge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICB2YXIga1xuICBpZiAoYiA9PSAxNikgayA9IDRcbiAgZWxzZSBpZiAoYiA9PSA4KSBrID0gM1xuICBlbHNlIGlmIChiID09IDI1NikgayA9IDg7IC8vIGJ5dGUgYXJyYXlcbiAgZWxzZSBpZiAoYiA9PSAyKSBrID0gMVxuICBlbHNlIGlmIChiID09IDMyKSBrID0gNVxuICBlbHNlIGlmIChiID09IDQpIGsgPSAyXG4gIGVsc2Uge1xuICAgIHNlbGYuZnJvbVJhZGl4KHMsIGIpXG4gICAgcmV0dXJuXG4gIH1cbiAgc2VsZi50ID0gMFxuICBzZWxmLnMgPSAwXG4gIHZhciBpID0gcy5sZW5ndGgsXG4gICAgbWkgPSBmYWxzZSxcbiAgICBzaCA9IDBcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgdmFyIHggPSAoayA9PSA4KSA/IHNbaV0gJiAweGZmIDogaW50QXQocywgaSlcbiAgICBpZiAoeCA8IDApIHtcbiAgICAgIGlmIChzLmNoYXJBdChpKSA9PSBcIi1cIikgbWkgPSB0cnVlXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBtaSA9IGZhbHNlXG4gICAgaWYgKHNoID09IDApXG4gICAgICBzZWxmW3NlbGYudCsrXSA9IHhcbiAgICBlbHNlIGlmIChzaCArIGsgPiBzZWxmLkRCKSB7XG4gICAgICBzZWxmW3NlbGYudCAtIDFdIHw9ICh4ICYgKCgxIDw8IChzZWxmLkRCIC0gc2gpKSAtIDEpKSA8PCBzaFxuICAgICAgc2VsZltzZWxmLnQrK10gPSAoeCA+PiAoc2VsZi5EQiAtIHNoKSlcbiAgICB9IGVsc2VcbiAgICAgIHNlbGZbc2VsZi50IC0gMV0gfD0geCA8PCBzaFxuICAgIHNoICs9IGtcbiAgICBpZiAoc2ggPj0gc2VsZi5EQikgc2ggLT0gc2VsZi5EQlxuICB9XG4gIGlmIChrID09IDggJiYgKHNbMF0gJiAweDgwKSAhPSAwKSB7XG4gICAgc2VsZi5zID0gLTFcbiAgICBpZiAoc2ggPiAwKSBzZWxmW3NlbGYudCAtIDFdIHw9ICgoMSA8PCAoc2VsZi5EQiAtIHNoKSkgLSAxKSA8PCBzaFxuICB9XG4gIHNlbGYuY2xhbXAoKVxuICBpZiAobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhzZWxmLCBzZWxmKVxufVxuXG4vLyAocHJvdGVjdGVkKSBjbGFtcCBvZmYgZXhjZXNzIGhpZ2ggd29yZHNcbmZ1bmN0aW9uIGJucENsYW1wKCkge1xuICB2YXIgYyA9IHRoaXMucyAmIHRoaXMuRE1cbiAgd2hpbGUgKHRoaXMudCA+IDAgJiYgdGhpc1t0aGlzLnQgLSAxXSA9PSBjKS0tdGhpcy50XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gaW4gZ2l2ZW4gcmFkaXhcbmZ1bmN0aW9uIGJuVG9TdHJpbmcoYikge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKHNlbGYucyA8IDApIHJldHVybiBcIi1cIiArIHNlbGYubmVnYXRlKClcbiAgICAudG9TdHJpbmcoYilcbiAgdmFyIGtcbiAgaWYgKGIgPT0gMTYpIGsgPSA0XG4gIGVsc2UgaWYgKGIgPT0gOCkgayA9IDNcbiAgZWxzZSBpZiAoYiA9PSAyKSBrID0gMVxuICBlbHNlIGlmIChiID09IDMyKSBrID0gNVxuICBlbHNlIGlmIChiID09IDQpIGsgPSAyXG4gIGVsc2UgcmV0dXJuIHNlbGYudG9SYWRpeChiKVxuICB2YXIga20gPSAoMSA8PCBrKSAtIDEsXG4gICAgZCwgbSA9IGZhbHNlLFxuICAgIHIgPSBcIlwiLFxuICAgIGkgPSBzZWxmLnRcbiAgdmFyIHAgPSBzZWxmLkRCIC0gKGkgKiBzZWxmLkRCKSAlIGtcbiAgaWYgKGktLSA+IDApIHtcbiAgICBpZiAocCA8IHNlbGYuREIgJiYgKGQgPSBzZWxmW2ldID4+IHApID4gMCkge1xuICAgICAgbSA9IHRydWVcbiAgICAgIHIgPSBpbnQyY2hhcihkKVxuICAgIH1cbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAocCA8IGspIHtcbiAgICAgICAgZCA9IChzZWxmW2ldICYgKCgxIDw8IHApIC0gMSkpIDw8IChrIC0gcClcbiAgICAgICAgZCB8PSBzZWxmWy0taV0gPj4gKHAgKz0gc2VsZi5EQiAtIGspXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkID0gKHNlbGZbaV0gPj4gKHAgLT0gaykpICYga21cbiAgICAgICAgaWYgKHAgPD0gMCkge1xuICAgICAgICAgIHAgKz0gc2VsZi5EQlxuICAgICAgICAgIC0taVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZCA+IDApIG0gPSB0cnVlXG4gICAgICBpZiAobSkgciArPSBpbnQyY2hhcihkKVxuICAgIH1cbiAgfVxuICByZXR1cm4gbSA/IHIgOiBcIjBcIlxufVxuXG4vLyAocHVibGljKSAtdGhpc1xuZnVuY3Rpb24gYm5OZWdhdGUoKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgfHRoaXN8XG5mdW5jdGlvbiBibkFicygpIHtcbiAgcmV0dXJuICh0aGlzLnMgPCAwKSA/IHRoaXMubmVnYXRlKCkgOiB0aGlzXG59XG5cbi8vIChwdWJsaWMpIHJldHVybiArIGlmIHRoaXMgPiBhLCAtIGlmIHRoaXMgPCBhLCAwIGlmIGVxdWFsXG5mdW5jdGlvbiBibkNvbXBhcmVUbyhhKSB7XG4gIHZhciByID0gdGhpcy5zIC0gYS5zXG4gIGlmIChyICE9IDApIHJldHVybiByXG4gIHZhciBpID0gdGhpcy50XG4gIHIgPSBpIC0gYS50XG4gIGlmIChyICE9IDApIHJldHVybiAodGhpcy5zIDwgMCkgPyAtciA6IHJcbiAgd2hpbGUgKC0taSA+PSAwKVxuICAgIGlmICgociA9IHRoaXNbaV0gLSBhW2ldKSAhPSAwKSByZXR1cm4gclxuICByZXR1cm4gMFxufVxuXG4vLyByZXR1cm5zIGJpdCBsZW5ndGggb2YgdGhlIGludGVnZXIgeFxuZnVuY3Rpb24gbmJpdHMoeCkge1xuICB2YXIgciA9IDEsXG4gICAgdFxuICBpZiAoKHQgPSB4ID4+PiAxNikgIT0gMCkge1xuICAgIHggPSB0XG4gICAgciArPSAxNlxuICB9XG4gIGlmICgodCA9IHggPj4gOCkgIT0gMCkge1xuICAgIHggPSB0XG4gICAgciArPSA4XG4gIH1cbiAgaWYgKCh0ID0geCA+PiA0KSAhPSAwKSB7XG4gICAgeCA9IHRcbiAgICByICs9IDRcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDIpICE9IDApIHtcbiAgICB4ID0gdFxuICAgIHIgKz0gMlxuICB9XG4gIGlmICgodCA9IHggPj4gMSkgIT0gMCkge1xuICAgIHggPSB0XG4gICAgciArPSAxXG4gIH1cbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBpbiBcInRoaXNcIlxuZnVuY3Rpb24gYm5CaXRMZW5ndGgoKSB7XG4gIGlmICh0aGlzLnQgPD0gMCkgcmV0dXJuIDBcbiAgcmV0dXJuIHRoaXMuREIgKiAodGhpcy50IC0gMSkgKyBuYml0cyh0aGlzW3RoaXMudCAtIDFdIF4gKHRoaXMucyAmIHRoaXMuRE0pKVxufVxuXG4vLyAocHVibGljKSByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBpbiBcInRoaXNcIlxuZnVuY3Rpb24gYm5CeXRlTGVuZ3RoKCkge1xuICByZXR1cm4gdGhpcy5iaXRMZW5ndGgoKSA+PiAzXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG4qREJcbmZ1bmN0aW9uIGJucERMU2hpZnRUbyhuLCByKSB7XG4gIHZhciBpXG4gIGZvciAoaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByW2kgKyBuXSA9IHRoaXNbaV1cbiAgZm9yIChpID0gbiAtIDE7IGkgPj0gMDsgLS1pKSByW2ldID0gMFxuICByLnQgPSB0aGlzLnQgKyBuXG4gIHIucyA9IHRoaXMuc1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuKkRCXG5mdW5jdGlvbiBibnBEUlNoaWZ0VG8obiwgcikge1xuICBmb3IgKHZhciBpID0gbjsgaSA8IHRoaXMudDsgKytpKSByW2kgLSBuXSA9IHRoaXNbaV1cbiAgci50ID0gTWF0aC5tYXgodGhpcy50IC0gbiwgMClcbiAgci5zID0gdGhpcy5zXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG5cbmZ1bmN0aW9uIGJucExTaGlmdFRvKG4sIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBicyA9IG4gJSBzZWxmLkRCXG4gIHZhciBjYnMgPSBzZWxmLkRCIC0gYnNcbiAgdmFyIGJtID0gKDEgPDwgY2JzKSAtIDFcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gc2VsZi5EQiksXG4gICAgYyA9IChzZWxmLnMgPDwgYnMpICYgc2VsZi5ETSxcbiAgICBpXG4gIGZvciAoaSA9IHNlbGYudCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgcltpICsgZHMgKyAxXSA9IChzZWxmW2ldID4+IGNicykgfCBjXG4gICAgYyA9IChzZWxmW2ldICYgYm0pIDw8IGJzXG4gIH1cbiAgZm9yIChpID0gZHMgLSAxOyBpID49IDA7IC0taSkgcltpXSA9IDBcbiAgcltkc10gPSBjXG4gIHIudCA9IHNlbGYudCArIGRzICsgMVxuICByLnMgPSBzZWxmLnNcbiAgci5jbGFtcCgpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzID4+IG5cbmZ1bmN0aW9uIGJucFJTaGlmdFRvKG4sIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHIucyA9IHNlbGYuc1xuICB2YXIgZHMgPSBNYXRoLmZsb29yKG4gLyBzZWxmLkRCKVxuICBpZiAoZHMgPj0gc2VsZi50KSB7XG4gICAgci50ID0gMFxuICAgIHJldHVyblxuICB9XG4gIHZhciBicyA9IG4gJSBzZWxmLkRCXG4gIHZhciBjYnMgPSBzZWxmLkRCIC0gYnNcbiAgdmFyIGJtID0gKDEgPDwgYnMpIC0gMVxuICByWzBdID0gc2VsZltkc10gPj4gYnNcbiAgZm9yICh2YXIgaSA9IGRzICsgMTsgaSA8IHNlbGYudDsgKytpKSB7XG4gICAgcltpIC0gZHMgLSAxXSB8PSAoc2VsZltpXSAmIGJtKSA8PCBjYnNcbiAgICByW2kgLSBkc10gPSBzZWxmW2ldID4+IGJzXG4gIH1cbiAgaWYgKGJzID4gMCkgcltzZWxmLnQgLSBkcyAtIDFdIHw9IChzZWxmLnMgJiBibSkgPDwgY2JzXG4gIHIudCA9IHNlbGYudCAtIGRzXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyAtIGFcbmZ1bmN0aW9uIGJucFN1YlRvKGEsIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBpID0gMCxcbiAgICBjID0gMCxcbiAgICBtID0gTWF0aC5taW4oYS50LCBzZWxmLnQpXG4gIHdoaWxlIChpIDwgbSkge1xuICAgIGMgKz0gc2VsZltpXSAtIGFbaV1cbiAgICByW2krK10gPSBjICYgc2VsZi5ETVxuICAgIGMgPj49IHNlbGYuREJcbiAgfVxuICBpZiAoYS50IDwgc2VsZi50KSB7XG4gICAgYyAtPSBhLnNcbiAgICB3aGlsZSAoaSA8IHNlbGYudCkge1xuICAgICAgYyArPSBzZWxmW2ldXG4gICAgICByW2krK10gPSBjICYgc2VsZi5ETVxuICAgICAgYyA+Pj0gc2VsZi5EQlxuICAgIH1cbiAgICBjICs9IHNlbGYuc1xuICB9IGVsc2Uge1xuICAgIGMgKz0gc2VsZi5zXG4gICAgd2hpbGUgKGkgPCBhLnQpIHtcbiAgICAgIGMgLT0gYVtpXVxuICAgICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICAgIGMgPj49IHNlbGYuREJcbiAgICB9XG4gICAgYyAtPSBhLnNcbiAgfVxuICByLnMgPSAoYyA8IDApID8gLTEgOiAwXG4gIGlmIChjIDwgLTEpIHJbaSsrXSA9IHNlbGYuRFYgKyBjXG4gIGVsc2UgaWYgKGMgPiAwKSByW2krK10gPSBjXG4gIHIudCA9IGlcbiAgci5jbGFtcCgpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICogYSwgciAhPSB0aGlzLGEgKEhBQyAxNC4xMilcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbmZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYSwgcikge1xuICB2YXIgeCA9IHRoaXMuYWJzKCksXG4gICAgeSA9IGEuYWJzKClcbiAgdmFyIGkgPSB4LnRcbiAgci50ID0gaSArIHkudFxuICB3aGlsZSAoLS1pID49IDApIHJbaV0gPSAwXG4gIGZvciAoaSA9IDA7IGkgPCB5LnQ7ICsraSkgcltpICsgeC50XSA9IHguYW0oMCwgeVtpXSwgciwgaSwgMCwgeC50KVxuICByLnMgPSAwXG4gIHIuY2xhbXAoKVxuICBpZiAodGhpcy5zICE9IGEucykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIsIHIpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzXjIsIHIgIT0gdGhpcyAoSEFDIDE0LjE2KVxuZnVuY3Rpb24gYm5wU3F1YXJlVG8ocikge1xuICB2YXIgeCA9IHRoaXMuYWJzKClcbiAgdmFyIGkgPSByLnQgPSAyICogeC50XG4gIHdoaWxlICgtLWkgPj0gMCkgcltpXSA9IDBcbiAgZm9yIChpID0gMDsgaSA8IHgudCAtIDE7ICsraSkge1xuICAgIHZhciBjID0geC5hbShpLCB4W2ldLCByLCAyICogaSwgMCwgMSlcbiAgICBpZiAoKHJbaSArIHgudF0gKz0geC5hbShpICsgMSwgMiAqIHhbaV0sIHIsIDIgKiBpICsgMSwgYywgeC50IC0gaSAtIDEpKSA+PSB4LkRWKSB7XG4gICAgICByW2kgKyB4LnRdIC09IHguRFZcbiAgICAgIHJbaSArIHgudCArIDFdID0gMVxuICAgIH1cbiAgfVxuICBpZiAoci50ID4gMCkgcltyLnQgLSAxXSArPSB4LmFtKGksIHhbaV0sIHIsIDIgKiBpLCAwLCAxKVxuICByLnMgPSAwXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSBkaXZpZGUgdGhpcyBieSBtLCBxdW90aWVudCBhbmQgcmVtYWluZGVyIHRvIHEsIHIgKEhBQyAxNC4yMClcbi8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLlxuZnVuY3Rpb24gYm5wRGl2UmVtVG8obSwgcSwgcikge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIHBtID0gbS5hYnMoKVxuICBpZiAocG0udCA8PSAwKSByZXR1cm5cbiAgdmFyIHB0ID0gc2VsZi5hYnMoKVxuICBpZiAocHQudCA8IHBtLnQpIHtcbiAgICBpZiAocSAhPSBudWxsKSBxLmZyb21JbnQoMClcbiAgICBpZiAociAhPSBudWxsKSBzZWxmLmNvcHlUbyhyKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChyID09IG51bGwpIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHZhciB5ID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICB0cyA9IHNlbGYucyxcbiAgICBtcyA9IG0uc1xuICB2YXIgbnNoID0gc2VsZi5EQiAtIG5iaXRzKHBtW3BtLnQgLSAxXSk7IC8vIG5vcm1hbGl6ZSBtb2R1bHVzXG4gIGlmIChuc2ggPiAwKSB7XG4gICAgcG0ubFNoaWZ0VG8obnNoLCB5KVxuICAgIHB0LmxTaGlmdFRvKG5zaCwgcilcbiAgfSBlbHNlIHtcbiAgICBwbS5jb3B5VG8oeSlcbiAgICBwdC5jb3B5VG8ocilcbiAgfVxuICB2YXIgeXMgPSB5LnRcbiAgdmFyIHkwID0geVt5cyAtIDFdXG4gIGlmICh5MCA9PSAwKSByZXR1cm5cbiAgdmFyIHl0ID0geTAgKiAoMSA8PCBzZWxmLkYxKSArICgoeXMgPiAxKSA/IHlbeXMgLSAyXSA+PiBzZWxmLkYyIDogMClcbiAgdmFyIGQxID0gc2VsZi5GViAvIHl0LFxuICAgIGQyID0gKDEgPDwgc2VsZi5GMSkgLyB5dCxcbiAgICBlID0gMSA8PCBzZWxmLkYyXG4gIHZhciBpID0gci50LFxuICAgIGogPSBpIC0geXMsXG4gICAgdCA9IChxID09IG51bGwpID8gbmV3IEJpZ0ludGVnZXIoKSA6IHFcbiAgeS5kbFNoaWZ0VG8oaiwgdClcbiAgaWYgKHIuY29tcGFyZVRvKHQpID49IDApIHtcbiAgICByW3IudCsrXSA9IDFcbiAgICByLnN1YlRvKHQsIHIpXG4gIH1cbiAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKHlzLCB0KVxuICB0LnN1YlRvKHksIHkpOyAvLyBcIm5lZ2F0aXZlXCIgeSBzbyB3ZSBjYW4gcmVwbGFjZSBzdWIgd2l0aCBhbSBsYXRlclxuICB3aGlsZSAoeS50IDwgeXMpIHlbeS50KytdID0gMFxuICB3aGlsZSAoLS1qID49IDApIHtcbiAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdFxuICAgIHZhciBxZCA9IChyWy0taV0gPT0geTApID8gc2VsZi5ETSA6IE1hdGguZmxvb3IocltpXSAqIGQxICsgKHJbaSAtIDFdICsgZSkgKiBkMilcbiAgICBpZiAoKHJbaV0gKz0geS5hbSgwLCBxZCwgciwgaiwgMCwgeXMpKSA8IHFkKSB7IC8vIFRyeSBpdCBvdXRcbiAgICAgIHkuZGxTaGlmdFRvKGosIHQpXG4gICAgICByLnN1YlRvKHQsIHIpXG4gICAgICB3aGlsZSAocltpXSA8IC0tcWQpIHIuc3ViVG8odCwgcilcbiAgICB9XG4gIH1cbiAgaWYgKHEgIT0gbnVsbCkge1xuICAgIHIuZHJTaGlmdFRvKHlzLCBxKVxuICAgIGlmICh0cyAhPSBtcykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHEsIHEpXG4gIH1cbiAgci50ID0geXNcbiAgci5jbGFtcCgpXG4gIGlmIChuc2ggPiAwKSByLnJTaGlmdFRvKG5zaCwgcik7IC8vIERlbm9ybWFsaXplIHJlbWFpbmRlclxuICBpZiAodHMgPCAwKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ociwgcilcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBtb2QgYVxuZnVuY3Rpb24gYm5Nb2QoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5hYnMoKVxuICAgIC5kaXZSZW1UbyhhLCBudWxsLCByKVxuICBpZiAodGhpcy5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgYS5zdWJUbyhyLCByKVxuICByZXR1cm4gclxufVxuXG4vLyBNb2R1bGFyIHJlZHVjdGlvbiB1c2luZyBcImNsYXNzaWNcIiBhbGdvcml0aG1cbmZ1bmN0aW9uIENsYXNzaWMobSkge1xuICB0aGlzLm0gPSBtXG59XG5cbmZ1bmN0aW9uIGNDb252ZXJ0KHgpIHtcbiAgaWYgKHgucyA8IDAgfHwgeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSByZXR1cm4geC5tb2QodGhpcy5tKVxuICBlbHNlIHJldHVybiB4XG59XG5cbmZ1bmN0aW9uIGNSZXZlcnQoeCkge1xuICByZXR1cm4geFxufVxuXG5mdW5jdGlvbiBjUmVkdWNlKHgpIHtcbiAgeC5kaXZSZW1Ubyh0aGlzLm0sIG51bGwsIHgpXG59XG5cbmZ1bmN0aW9uIGNNdWxUbyh4LCB5LCByKSB7XG4gIHgubXVsdGlwbHlUbyh5LCByKVxuICB0aGlzLnJlZHVjZShyKVxufVxuXG5mdW5jdGlvbiBjU3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpXG4gIHRoaXMucmVkdWNlKHIpXG59XG5cbkNsYXNzaWMucHJvdG90eXBlLmNvbnZlcnQgPSBjQ29udmVydFxuQ2xhc3NpYy5wcm90b3R5cGUucmV2ZXJ0ID0gY1JldmVydFxuQ2xhc3NpYy5wcm90b3R5cGUucmVkdWNlID0gY1JlZHVjZVxuQ2xhc3NpYy5wcm90b3R5cGUubXVsVG8gPSBjTXVsVG9cbkNsYXNzaWMucHJvdG90eXBlLnNxclRvID0gY1NxclRvXG5cbi8vIChwcm90ZWN0ZWQpIHJldHVybiBcIi0xL3RoaXMgJSAyXkRCXCI7IHVzZWZ1bCBmb3IgTW9udC4gcmVkdWN0aW9uXG4vLyBqdXN0aWZpY2F0aW9uOlxuLy8gICAgICAgICB4eSA9PSAxIChtb2QgbSlcbi8vICAgICAgICAgeHkgPSAgMStrbVxuLy8gICB4eSgyLXh5KSA9ICgxK2ttKSgxLWttKVxuLy8geFt5KDIteHkpXSA9IDEta14ybV4yXG4vLyB4W3koMi14eSldID09IDEgKG1vZCBtXjIpXG4vLyBpZiB5IGlzIDEveCBtb2QgbSwgdGhlbiB5KDIteHkpIGlzIDEveCBtb2QgbV4yXG4vLyBzaG91bGQgcmVkdWNlIHggYW5kIHkoMi14eSkgYnkgbV4yIGF0IGVhY2ggc3RlcCB0byBrZWVwIHNpemUgYm91bmRlZC5cbi8vIEpTIG11bHRpcGx5IFwib3ZlcmZsb3dzXCIgZGlmZmVyZW50bHkgZnJvbSBDL0MrKywgc28gY2FyZSBpcyBuZWVkZWQgaGVyZS5cbmZ1bmN0aW9uIGJucEludkRpZ2l0KCkge1xuICBpZiAodGhpcy50IDwgMSkgcmV0dXJuIDBcbiAgdmFyIHggPSB0aGlzWzBdXG4gIGlmICgoeCAmIDEpID09IDApIHJldHVybiAwXG4gIHZhciB5ID0geCAmIDM7IC8vIHkgPT0gMS94IG1vZCAyXjJcbiAgeSA9ICh5ICogKDIgLSAoeCAmIDB4ZikgKiB5KSkgJiAweGY7IC8vIHkgPT0gMS94IG1vZCAyXjRcbiAgeSA9ICh5ICogKDIgLSAoeCAmIDB4ZmYpICogeSkpICYgMHhmZjsgLy8geSA9PSAxL3ggbW9kIDJeOFxuICB5ID0gKHkgKiAoMiAtICgoKHggJiAweGZmZmYpICogeSkgJiAweGZmZmYpKSkgJiAweGZmZmY7IC8vIHkgPT0gMS94IG1vZCAyXjE2XG4gIC8vIGxhc3Qgc3RlcCAtIGNhbGN1bGF0ZSBpbnZlcnNlIG1vZCBEViBkaXJlY3RseVxuICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHNcbiAgeSA9ICh5ICogKDIgLSB4ICogeSAlIHRoaXMuRFYpKSAlIHRoaXMuRFY7IC8vIHkgPT0gMS94IG1vZCAyXmRiaXRzXG4gIC8vIHdlIHJlYWxseSB3YW50IHRoZSBuZWdhdGl2ZSBpbnZlcnNlLCBhbmQgLURWIDwgeSA8IERWXG4gIHJldHVybiAoeSA+IDApID8gdGhpcy5EViAtIHkgOiAteVxufVxuXG4vLyBNb250Z29tZXJ5IHJlZHVjdGlvblxuZnVuY3Rpb24gTW9udGdvbWVyeShtKSB7XG4gIHRoaXMubSA9IG1cbiAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKVxuICB0aGlzLm1wbCA9IHRoaXMubXAgJiAweDdmZmZcbiAgdGhpcy5tcGggPSB0aGlzLm1wID4+IDE1XG4gIHRoaXMudW0gPSAoMSA8PCAobS5EQiAtIDE1KSkgLSAxXG4gIHRoaXMubXQyID0gMiAqIG0udFxufVxuXG4vLyB4UiBtb2QgbVxuZnVuY3Rpb24gbW9udENvbnZlcnQoeCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgeC5hYnMoKVxuICAgIC5kbFNoaWZ0VG8odGhpcy5tLnQsIHIpXG4gIHIuZGl2UmVtVG8odGhpcy5tLCBudWxsLCByKVxuICBpZiAoeC5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgdGhpcy5tLnN1YlRvKHIsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIHgvUiBtb2QgbVxuZnVuY3Rpb24gbW9udFJldmVydCh4KSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB4LmNvcHlUbyhyKVxuICB0aGlzLnJlZHVjZShyKVxuICByZXR1cm4gclxufVxuXG4vLyB4ID0geC9SIG1vZCBtIChIQUMgMTQuMzIpXG5mdW5jdGlvbiBtb250UmVkdWNlKHgpIHtcbiAgd2hpbGUgKHgudCA8PSB0aGlzLm10MikgLy8gcGFkIHggc28gYW0gaGFzIGVub3VnaCByb29tIGxhdGVyXG4gICAgeFt4LnQrK10gPSAwXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tLnQ7ICsraSkge1xuICAgIC8vIGZhc3RlciB3YXkgb2YgY2FsY3VsYXRpbmcgdTAgPSB4W2ldKm1wIG1vZCBEVlxuICAgIHZhciBqID0geFtpXSAmIDB4N2ZmZlxuICAgIHZhciB1MCA9IChqICogdGhpcy5tcGwgKyAoKChqICogdGhpcy5tcGggKyAoeFtpXSA+PiAxNSkgKiB0aGlzLm1wbCkgJiB0aGlzLnVtKSA8PCAxNSkpICYgeC5ETVxuICAgIC8vIHVzZSBhbSB0byBjb21iaW5lIHRoZSBtdWx0aXBseS1zaGlmdC1hZGQgaW50byBvbmUgY2FsbFxuICAgIGogPSBpICsgdGhpcy5tLnRcbiAgICB4W2pdICs9IHRoaXMubS5hbSgwLCB1MCwgeCwgaSwgMCwgdGhpcy5tLnQpXG4gICAgLy8gcHJvcGFnYXRlIGNhcnJ5XG4gICAgd2hpbGUgKHhbal0gPj0geC5EVikge1xuICAgICAgeFtqXSAtPSB4LkRWXG4gICAgICB4Wysral0rK1xuICAgIH1cbiAgfVxuICB4LmNsYW1wKClcbiAgeC5kclNoaWZ0VG8odGhpcy5tLnQsIHgpXG4gIGlmICh4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHguc3ViVG8odGhpcy5tLCB4KVxufVxuXG4vLyByID0gXCJ4XjIvUiBtb2QgbVwiOyB4ICE9IHJcbmZ1bmN0aW9uIG1vbnRTcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocilcbiAgdGhpcy5yZWR1Y2Uocilcbn1cblxuLy8gciA9IFwieHkvUiBtb2QgbVwiOyB4LHkgIT0gclxuZnVuY3Rpb24gbW9udE11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpXG4gIHRoaXMucmVkdWNlKHIpXG59XG5cbk1vbnRnb21lcnkucHJvdG90eXBlLmNvbnZlcnQgPSBtb250Q29udmVydFxuTW9udGdvbWVyeS5wcm90b3R5cGUucmV2ZXJ0ID0gbW9udFJldmVydFxuTW9udGdvbWVyeS5wcm90b3R5cGUucmVkdWNlID0gbW9udFJlZHVjZVxuTW9udGdvbWVyeS5wcm90b3R5cGUubXVsVG8gPSBtb250TXVsVG9cbk1vbnRnb21lcnkucHJvdG90eXBlLnNxclRvID0gbW9udFNxclRvXG5cbi8vIChwcm90ZWN0ZWQpIHRydWUgaWZmIHRoaXMgaXMgZXZlblxuZnVuY3Rpb24gYm5wSXNFdmVuKCkge1xuICByZXR1cm4gKCh0aGlzLnQgPiAwKSA/ICh0aGlzWzBdICYgMSkgOiB0aGlzLnMpID09IDBcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpc15lLCBlIDwgMl4zMiwgZG9pbmcgc3FyIGFuZCBtdWwgd2l0aCBcInJcIiAoSEFDIDE0Ljc5KVxuZnVuY3Rpb24gYm5wRXhwKGUsIHopIHtcbiAgaWYgKGUgPiAweGZmZmZmZmZmIHx8IGUgPCAxKSByZXR1cm4gQmlnSW50ZWdlci5PTkVcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpLFxuICAgIHIyID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICBnID0gei5jb252ZXJ0KHRoaXMpLFxuICAgIGkgPSBuYml0cyhlKSAtIDFcbiAgZy5jb3B5VG8ocilcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgei5zcXJUbyhyLCByMilcbiAgICBpZiAoKGUgJiAoMSA8PCBpKSkgPiAwKSB6Lm11bFRvKHIyLCBnLCByKVxuICAgIGVsc2Uge1xuICAgICAgdmFyIHQgPSByXG4gICAgICByID0gcjJcbiAgICAgIHIyID0gdFxuICAgIH1cbiAgfVxuICByZXR1cm4gei5yZXZlcnQocilcbn1cblxuLy8gKHB1YmxpYykgdGhpc15lICUgbSwgMCA8PSBlIDwgMl4zMlxuZnVuY3Rpb24gYm5Nb2RQb3dJbnQoZSwgbSkge1xuICB2YXIgelxuICBpZiAoZSA8IDI1NiB8fCBtLmlzRXZlbigpKSB6ID0gbmV3IENsYXNzaWMobSlcbiAgZWxzZSB6ID0gbmV3IE1vbnRnb21lcnkobSlcbiAgcmV0dXJuIHRoaXMuZXhwKGUsIHopXG59XG5cbi8vIHByb3RlY3RlZFxucHJvdG8uY29weVRvID0gYm5wQ29weVRvXG5wcm90by5mcm9tSW50ID0gYm5wRnJvbUludFxucHJvdG8uZnJvbVN0cmluZyA9IGJucEZyb21TdHJpbmdcbnByb3RvLmNsYW1wID0gYm5wQ2xhbXBcbnByb3RvLmRsU2hpZnRUbyA9IGJucERMU2hpZnRUb1xucHJvdG8uZHJTaGlmdFRvID0gYm5wRFJTaGlmdFRvXG5wcm90by5sU2hpZnRUbyA9IGJucExTaGlmdFRvXG5wcm90by5yU2hpZnRUbyA9IGJucFJTaGlmdFRvXG5wcm90by5zdWJUbyA9IGJucFN1YlRvXG5wcm90by5tdWx0aXBseVRvID0gYm5wTXVsdGlwbHlUb1xucHJvdG8uc3F1YXJlVG8gPSBibnBTcXVhcmVUb1xucHJvdG8uZGl2UmVtVG8gPSBibnBEaXZSZW1Ub1xucHJvdG8uaW52RGlnaXQgPSBibnBJbnZEaWdpdFxucHJvdG8uaXNFdmVuID0gYm5wSXNFdmVuXG5wcm90by5leHAgPSBibnBFeHBcblxuLy8gcHVibGljXG5wcm90by50b1N0cmluZyA9IGJuVG9TdHJpbmdcbnByb3RvLm5lZ2F0ZSA9IGJuTmVnYXRlXG5wcm90by5hYnMgPSBibkFic1xucHJvdG8uY29tcGFyZVRvID0gYm5Db21wYXJlVG9cbnByb3RvLmJpdExlbmd0aCA9IGJuQml0TGVuZ3RoXG5wcm90by5ieXRlTGVuZ3RoID0gYm5CeXRlTGVuZ3RoXG5wcm90by5tb2QgPSBibk1vZFxucHJvdG8ubW9kUG93SW50ID0gYm5Nb2RQb3dJbnRcblxuLy8gKHB1YmxpYylcbmZ1bmN0aW9uIGJuQ2xvbmUoKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmNvcHlUbyhyKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgaW50ZWdlclxuZnVuY3Rpb24gYm5JbnRWYWx1ZSgpIHtcbiAgaWYgKHRoaXMucyA8IDApIHtcbiAgICBpZiAodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdIC0gdGhpcy5EVlxuICAgIGVsc2UgaWYgKHRoaXMudCA9PSAwKSByZXR1cm4gLTFcbiAgfSBlbHNlIGlmICh0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXNbMF1cbiAgZWxzZSBpZiAodGhpcy50ID09IDApIHJldHVybiAwXG4gIC8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyXG4gIHJldHVybiAoKHRoaXNbMV0gJiAoKDEgPDwgKDMyIC0gdGhpcy5EQikpIC0gMSkpIDw8IHRoaXMuREIpIHwgdGhpc1swXVxufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgYnl0ZVxuZnVuY3Rpb24gYm5CeXRlVmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMjQpID4+IDI0XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBzaG9ydCAoYXNzdW1lcyBEQj49MTYpXG5mdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMTYpID4+IDE2XG59XG5cbi8vIChwcm90ZWN0ZWQpIHJldHVybiB4IHMudC4gcl54IDwgRFZcbmZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yICogdGhpcy5EQiAvIE1hdGgubG9nKHIpKVxufVxuXG4vLyAocHVibGljKSAwIGlmIHRoaXMgPT0gMCwgMSBpZiB0aGlzID4gMFxuZnVuY3Rpb24gYm5TaWdOdW0oKSB7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gLTFcbiAgZWxzZSBpZiAodGhpcy50IDw9IDAgfHwgKHRoaXMudCA9PSAxICYmIHRoaXNbMF0gPD0gMCkpIHJldHVybiAwXG4gIGVsc2UgcmV0dXJuIDFcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmdcbmZ1bmN0aW9uIGJucFRvUmFkaXgoYikge1xuICBpZiAoYiA9PSBudWxsKSBiID0gMTBcbiAgaWYgKHRoaXMuc2lnbnVtKCkgPT0gMCB8fCBiIDwgMiB8fCBiID4gMzYpIHJldHVybiBcIjBcIlxuICB2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKVxuICB2YXIgYSA9IE1hdGgucG93KGIsIGNzKVxuICB2YXIgZCA9IG5idihhKSxcbiAgICB5ID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICB6ID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICByID0gXCJcIlxuICB0aGlzLmRpdlJlbVRvKGQsIHksIHopXG4gIHdoaWxlICh5LnNpZ251bSgpID4gMCkge1xuICAgIHIgPSAoYSArIHouaW50VmFsdWUoKSlcbiAgICAgIC50b1N0cmluZyhiKVxuICAgICAgLnN1YnN0cigxKSArIHJcbiAgICB5LmRpdlJlbVRvKGQsIHksIHopXG4gIH1cbiAgcmV0dXJuIHouaW50VmFsdWUoKVxuICAgIC50b1N0cmluZyhiKSArIHJcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCBmcm9tIHJhZGl4IHN0cmluZ1xuZnVuY3Rpb24gYm5wRnJvbVJhZGl4KHMsIGIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHNlbGYuZnJvbUludCgwKVxuICBpZiAoYiA9PSBudWxsKSBiID0gMTBcbiAgdmFyIGNzID0gc2VsZi5jaHVua1NpemUoYilcbiAgdmFyIGQgPSBNYXRoLnBvdyhiLCBjcyksXG4gICAgbWkgPSBmYWxzZSxcbiAgICBqID0gMCxcbiAgICB3ID0gMFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgeCA9IGludEF0KHMsIGkpXG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBpZiAocy5jaGFyQXQoaSkgPT0gXCItXCIgJiYgc2VsZi5zaWdudW0oKSA9PSAwKSBtaSA9IHRydWVcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIHcgPSBiICogdyArIHhcbiAgICBpZiAoKytqID49IGNzKSB7XG4gICAgICBzZWxmLmRNdWx0aXBseShkKVxuICAgICAgc2VsZi5kQWRkT2Zmc2V0KHcsIDApXG4gICAgICBqID0gMFxuICAgICAgdyA9IDBcbiAgICB9XG4gIH1cbiAgaWYgKGogPiAwKSB7XG4gICAgc2VsZi5kTXVsdGlwbHkoTWF0aC5wb3coYiwgaikpXG4gICAgc2VsZi5kQWRkT2Zmc2V0KHcsIDApXG4gIH1cbiAgaWYgKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8oc2VsZiwgc2VsZilcbn1cblxuLy8gKHByb3RlY3RlZCkgYWx0ZXJuYXRlIGNvbnN0cnVjdG9yXG5mdW5jdGlvbiBibnBGcm9tTnVtYmVyKGEsIGIsIGMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmIChcIm51bWJlclwiID09IHR5cGVvZiBiKSB7XG4gICAgLy8gbmV3IEJpZ0ludGVnZXIoaW50LGludCxSTkcpXG4gICAgaWYgKGEgPCAyKSBzZWxmLmZyb21JbnQoMSlcbiAgICBlbHNlIHtcbiAgICAgIHNlbGYuZnJvbU51bWJlcihhLCBjKVxuICAgICAgaWYgKCFzZWxmLnRlc3RCaXQoYSAtIDEpKSAvLyBmb3JjZSBNU0Igc2V0XG4gICAgICAgIHNlbGYuYml0d2lzZVRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhIC0gMSksIG9wX29yLCBzZWxmKVxuICAgICAgaWYgKHNlbGYuaXNFdmVuKCkpIHNlbGYuZEFkZE9mZnNldCgxLCAwKTsgLy8gZm9yY2Ugb2RkXG4gICAgICB3aGlsZSAoIXNlbGYuaXNQcm9iYWJsZVByaW1lKGIpKSB7XG4gICAgICAgIHNlbGYuZEFkZE9mZnNldCgyLCAwKVxuICAgICAgICBpZiAoc2VsZi5iaXRMZW5ndGgoKSA+IGEpIHNlbGYuc3ViVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEgLSAxKSwgc2VsZilcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gbmV3IEJpZ0ludGVnZXIoaW50LFJORylcbiAgICB2YXIgeCA9IG5ldyBBcnJheSgpLFxuICAgICAgdCA9IGEgJiA3XG4gICAgeC5sZW5ndGggPSAoYSA+PiAzKSArIDFcbiAgICBiLm5leHRCeXRlcyh4KVxuICAgIGlmICh0ID4gMCkgeFswXSAmPSAoKDEgPDwgdCkgLSAxKVxuICAgIGVsc2UgeFswXSA9IDBcbiAgICBzZWxmLmZyb21TdHJpbmcoeCwgMjU2KVxuICB9XG59XG5cbi8vIChwdWJsaWMpIGNvbnZlcnQgdG8gYmlnZW5kaWFuIGJ5dGUgYXJyYXlcbmZ1bmN0aW9uIGJuVG9CeXRlQXJyYXkoKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgaSA9IHNlbGYudCxcbiAgICByID0gbmV3IEFycmF5KClcbiAgclswXSA9IHNlbGYuc1xuICB2YXIgcCA9IHNlbGYuREIgLSAoaSAqIHNlbGYuREIpICUgOCxcbiAgICBkLCBrID0gMFxuICBpZiAoaS0tID4gMCkge1xuICAgIGlmIChwIDwgc2VsZi5EQiAmJiAoZCA9IHNlbGZbaV0gPj4gcCkgIT0gKHNlbGYucyAmIHNlbGYuRE0pID4+IHApXG4gICAgICByW2srK10gPSBkIHwgKHNlbGYucyA8PCAoc2VsZi5EQiAtIHApKVxuICAgIHdoaWxlIChpID49IDApIHtcbiAgICAgIGlmIChwIDwgOCkge1xuICAgICAgICBkID0gKHNlbGZbaV0gJiAoKDEgPDwgcCkgLSAxKSkgPDwgKDggLSBwKVxuICAgICAgICBkIHw9IHNlbGZbLS1pXSA+PiAocCArPSBzZWxmLkRCIC0gOClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGQgPSAoc2VsZltpXSA+PiAocCAtPSA4KSkgJiAweGZmXG4gICAgICAgIGlmIChwIDw9IDApIHtcbiAgICAgICAgICBwICs9IHNlbGYuREJcbiAgICAgICAgICAtLWlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKChkICYgMHg4MCkgIT0gMCkgZCB8PSAtMjU2XG4gICAgICBpZiAoayA9PT0gMCAmJiAoc2VsZi5zICYgMHg4MCkgIT0gKGQgJiAweDgwKSkrK2tcbiAgICAgIGlmIChrID4gMCB8fCBkICE9IHNlbGYucykgcltrKytdID0gZFxuICAgIH1cbiAgfVxuICByZXR1cm4gclxufVxuXG5mdW5jdGlvbiBibkVxdWFscyhhKSB7XG4gIHJldHVybiAodGhpcy5jb21wYXJlVG8oYSkgPT0gMClcbn1cblxuZnVuY3Rpb24gYm5NaW4oYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpIDwgMCkgPyB0aGlzIDogYVxufVxuXG5mdW5jdGlvbiBibk1heChhKSB7XG4gIHJldHVybiAodGhpcy5jb21wYXJlVG8oYSkgPiAwKSA/IHRoaXMgOiBhXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIG9wIGEgKGJpdHdpc2UpXG5mdW5jdGlvbiBibnBCaXR3aXNlVG8oYSwgb3AsIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBpLCBmLCBtID0gTWF0aC5taW4oYS50LCBzZWxmLnQpXG4gIGZvciAoaSA9IDA7IGkgPCBtOyArK2kpIHJbaV0gPSBvcChzZWxmW2ldLCBhW2ldKVxuICBpZiAoYS50IDwgc2VsZi50KSB7XG4gICAgZiA9IGEucyAmIHNlbGYuRE1cbiAgICBmb3IgKGkgPSBtOyBpIDwgc2VsZi50OyArK2kpIHJbaV0gPSBvcChzZWxmW2ldLCBmKVxuICAgIHIudCA9IHNlbGYudFxuICB9IGVsc2Uge1xuICAgIGYgPSBzZWxmLnMgJiBzZWxmLkRNXG4gICAgZm9yIChpID0gbTsgaSA8IGEudDsgKytpKSByW2ldID0gb3AoZiwgYVtpXSlcbiAgICByLnQgPSBhLnRcbiAgfVxuICByLnMgPSBvcChzZWxmLnMsIGEucylcbiAgci5jbGFtcCgpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgJiBhXG5mdW5jdGlvbiBvcF9hbmQoeCwgeSkge1xuICByZXR1cm4geCAmIHlcbn1cblxuZnVuY3Rpb24gYm5BbmQoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfYW5kLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzIHwgYVxuZnVuY3Rpb24gb3Bfb3IoeCwgeSkge1xuICByZXR1cm4geCB8IHlcbn1cblxuZnVuY3Rpb24gYm5PcihhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF9vciwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBeIGFcbmZ1bmN0aW9uIG9wX3hvcih4LCB5KSB7XG4gIHJldHVybiB4IF4geVxufVxuXG5mdW5jdGlvbiBiblhvcihhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF94b3IsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgJiB+YVxuZnVuY3Rpb24gb3BfYW5kbm90KHgsIHkpIHtcbiAgcmV0dXJuIHggJiB+eVxufVxuXG5mdW5jdGlvbiBibkFuZE5vdChhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF9hbmRub3QsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIH50aGlzXG5mdW5jdGlvbiBibk5vdCgpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSB0aGlzLkRNICYgfnRoaXNbaV1cbiAgci50ID0gdGhpcy50XG4gIHIucyA9IH50aGlzLnNcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyA8PCBuXG5mdW5jdGlvbiBiblNoaWZ0TGVmdChuKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICBpZiAobiA8IDApIHRoaXMuclNoaWZ0VG8oLW4sIHIpXG4gIGVsc2UgdGhpcy5sU2hpZnRUbyhuLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzID4+IG5cbmZ1bmN0aW9uIGJuU2hpZnRSaWdodChuKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICBpZiAobiA8IDApIHRoaXMubFNoaWZ0VG8oLW4sIHIpXG4gIGVsc2UgdGhpcy5yU2hpZnRUbyhuLCByKVxuICByZXR1cm4gclxufVxuXG4vLyByZXR1cm4gaW5kZXggb2YgbG93ZXN0IDEtYml0IGluIHgsIHggPCAyXjMxXG5mdW5jdGlvbiBsYml0KHgpIHtcbiAgaWYgKHggPT0gMCkgcmV0dXJuIC0xXG4gIHZhciByID0gMFxuICBpZiAoKHggJiAweGZmZmYpID09IDApIHtcbiAgICB4ID4+PSAxNlxuICAgIHIgKz0gMTZcbiAgfVxuICBpZiAoKHggJiAweGZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gOFxuICAgIHIgKz0gOFxuICB9XG4gIGlmICgoeCAmIDB4ZikgPT0gMCkge1xuICAgIHggPj49IDRcbiAgICByICs9IDRcbiAgfVxuICBpZiAoKHggJiAzKSA9PSAwKSB7XG4gICAgeCA+Pj0gMlxuICAgIHIgKz0gMlxuICB9XG4gIGlmICgoeCAmIDEpID09IDApKytyXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHJldHVybnMgaW5kZXggb2YgbG93ZXN0IDEtYml0IChvciAtMSBpZiBub25lKVxuZnVuY3Rpb24gYm5HZXRMb3dlc3RTZXRCaXQoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpXG4gICAgaWYgKHRoaXNbaV0gIT0gMCkgcmV0dXJuIGkgKiB0aGlzLkRCICsgbGJpdCh0aGlzW2ldKVxuICBpZiAodGhpcy5zIDwgMCkgcmV0dXJuIHRoaXMudCAqIHRoaXMuREJcbiAgcmV0dXJuIC0xXG59XG5cbi8vIHJldHVybiBudW1iZXIgb2YgMSBiaXRzIGluIHhcbmZ1bmN0aW9uIGNiaXQoeCkge1xuICB2YXIgciA9IDBcbiAgd2hpbGUgKHggIT0gMCkge1xuICAgIHggJj0geCAtIDFcbiAgICArK3JcbiAgfVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSByZXR1cm4gbnVtYmVyIG9mIHNldCBiaXRzXG5mdW5jdGlvbiBibkJpdENvdW50KCkge1xuICB2YXIgciA9IDAsXG4gICAgeCA9IHRoaXMucyAmIHRoaXMuRE1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSkgciArPSBjYml0KHRoaXNbaV0gXiB4KVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldFxuZnVuY3Rpb24gYm5UZXN0Qml0KG4pIHtcbiAgdmFyIGogPSBNYXRoLmZsb29yKG4gLyB0aGlzLkRCKVxuICBpZiAoaiA+PSB0aGlzLnQpIHJldHVybiAodGhpcy5zICE9IDApXG4gIHJldHVybiAoKHRoaXNbal0gJiAoMSA8PCAobiAlIHRoaXMuREIpKSkgIT0gMClcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyBvcCAoMTw8bilcbmZ1bmN0aW9uIGJucENoYW5nZUJpdChuLCBvcCkge1xuICB2YXIgciA9IEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChuKVxuICB0aGlzLmJpdHdpc2VUbyhyLCBvcCwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyB8ICgxPDxuKVxuZnVuY3Rpb24gYm5TZXRCaXQobikge1xuICByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobiwgb3Bfb3IpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgJiB+KDE8PG4pXG5mdW5jdGlvbiBibkNsZWFyQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX2FuZG5vdClcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBeICgxPDxuKVxuZnVuY3Rpb24gYm5GbGlwQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX3hvcilcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgKyBhXG5mdW5jdGlvbiBibnBBZGRUbyhhLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIHZhciBpID0gMCxcbiAgICBjID0gMCxcbiAgICBtID0gTWF0aC5taW4oYS50LCBzZWxmLnQpXG4gIHdoaWxlIChpIDwgbSkge1xuICAgIGMgKz0gc2VsZltpXSArIGFbaV1cbiAgICByW2krK10gPSBjICYgc2VsZi5ETVxuICAgIGMgPj49IHNlbGYuREJcbiAgfVxuICBpZiAoYS50IDwgc2VsZi50KSB7XG4gICAgYyArPSBhLnNcbiAgICB3aGlsZSAoaSA8IHNlbGYudCkge1xuICAgICAgYyArPSBzZWxmW2ldXG4gICAgICByW2krK10gPSBjICYgc2VsZi5ETVxuICAgICAgYyA+Pj0gc2VsZi5EQlxuICAgIH1cbiAgICBjICs9IHNlbGYuc1xuICB9IGVsc2Uge1xuICAgIGMgKz0gc2VsZi5zXG4gICAgd2hpbGUgKGkgPCBhLnQpIHtcbiAgICAgIGMgKz0gYVtpXVxuICAgICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICAgIGMgPj49IHNlbGYuREJcbiAgICB9XG4gICAgYyArPSBhLnNcbiAgfVxuICByLnMgPSAoYyA8IDApID8gLTEgOiAwXG4gIGlmIChjID4gMCkgcltpKytdID0gY1xuICBlbHNlIGlmIChjIDwgLTEpIHJbaSsrXSA9IHNlbGYuRFYgKyBjXG4gIHIudCA9IGlcbiAgci5jbGFtcCgpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgKyBhXG5mdW5jdGlvbiBibkFkZChhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmFkZFRvKGEsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgLSBhXG5mdW5jdGlvbiBiblN1YnRyYWN0KGEpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMuc3ViVG8oYSwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAqIGFcbmZ1bmN0aW9uIGJuTXVsdGlwbHkoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5tdWx0aXBseVRvKGEsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXNeMlxuZnVuY3Rpb24gYm5TcXVhcmUoKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLnNxdWFyZVRvKHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgLyBhXG5mdW5jdGlvbiBibkRpdmlkZShhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmRpdlJlbVRvKGEsIHIsIG51bGwpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgJSBhXG5mdW5jdGlvbiBiblJlbWFpbmRlcihhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmRpdlJlbVRvKGEsIG51bGwsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIFt0aGlzL2EsdGhpcyVhXVxuZnVuY3Rpb24gYm5EaXZpZGVBbmRSZW1haW5kZXIoYSkge1xuICB2YXIgcSA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5kaXZSZW1UbyhhLCBxLCByKVxuICByZXR1cm4gbmV3IEFycmF5KHEsIHIpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgKj0gbiwgdGhpcyA+PSAwLCAxIDwgbiA8IERWXG5mdW5jdGlvbiBibnBETXVsdGlwbHkobikge1xuICB0aGlzW3RoaXMudF0gPSB0aGlzLmFtKDAsIG4gLSAxLCB0aGlzLCAwLCAwLCB0aGlzLnQpXG4gICsrdGhpcy50XG4gIHRoaXMuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzICs9IG4gPDwgdyB3b3JkcywgdGhpcyA+PSAwXG5mdW5jdGlvbiBibnBEQWRkT2Zmc2V0KG4sIHcpIHtcbiAgaWYgKG4gPT0gMCkgcmV0dXJuXG4gIHdoaWxlICh0aGlzLnQgPD0gdykgdGhpc1t0aGlzLnQrK10gPSAwXG4gIHRoaXNbd10gKz0gblxuICB3aGlsZSAodGhpc1t3XSA+PSB0aGlzLkRWKSB7XG4gICAgdGhpc1t3XSAtPSB0aGlzLkRWXG4gICAgaWYgKCsrdyA+PSB0aGlzLnQpIHRoaXNbdGhpcy50KytdID0gMFxuICAgICsrdGhpc1t3XVxuICB9XG59XG5cbi8vIEEgXCJudWxsXCIgcmVkdWNlclxuZnVuY3Rpb24gTnVsbEV4cCgpIHt9XG5cbmZ1bmN0aW9uIG5Ob3AoeCkge1xuICByZXR1cm4geFxufVxuXG5mdW5jdGlvbiBuTXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcilcbn1cblxuZnVuY3Rpb24gblNxclRvKHgsIHIpIHtcbiAgeC5zcXVhcmVUbyhyKVxufVxuXG5OdWxsRXhwLnByb3RvdHlwZS5jb252ZXJ0ID0gbk5vcFxuTnVsbEV4cC5wcm90b3R5cGUucmV2ZXJ0ID0gbk5vcFxuTnVsbEV4cC5wcm90b3R5cGUubXVsVG8gPSBuTXVsVG9cbk51bGxFeHAucHJvdG90eXBlLnNxclRvID0gblNxclRvXG5cbi8vIChwdWJsaWMpIHRoaXNeZVxuZnVuY3Rpb24gYm5Qb3coZSkge1xuICByZXR1cm4gdGhpcy5leHAoZSwgbmV3IE51bGxFeHAoKSlcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IGxvd2VyIG4gd29yZHMgb2YgXCJ0aGlzICogYVwiLCBhLnQgPD0gblxuLy8gXCJ0aGlzXCIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLlxuZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGEsIG4sIHIpIHtcbiAgdmFyIGkgPSBNYXRoLm1pbih0aGlzLnQgKyBhLnQsIG4pXG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgci50ID0gaVxuICB3aGlsZSAoaSA+IDApIHJbLS1pXSA9IDBcbiAgdmFyIGpcbiAgZm9yIChqID0gci50IC0gdGhpcy50OyBpIDwgajsgKytpKSByW2kgKyB0aGlzLnRdID0gdGhpcy5hbSgwLCBhW2ldLCByLCBpLCAwLCB0aGlzLnQpXG4gIGZvciAoaiA9IE1hdGgubWluKGEudCwgbik7IGkgPCBqOyArK2kpIHRoaXMuYW0oMCwgYVtpXSwgciwgaSwgMCwgbiAtIGkpXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gXCJ0aGlzICogYVwiIHdpdGhvdXQgbG93ZXIgbiB3b3JkcywgbiA+IDBcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbmZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhhLCBuLCByKSB7XG4gIC0tblxuICB2YXIgaSA9IHIudCA9IHRoaXMudCArIGEudCAtIG5cbiAgci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMFxuICB3aGlsZSAoLS1pID49IDApIHJbaV0gPSAwXG4gIGZvciAoaSA9IE1hdGgubWF4KG4gLSB0aGlzLnQsIDApOyBpIDwgYS50OyArK2kpXG4gICAgclt0aGlzLnQgKyBpIC0gbl0gPSB0aGlzLmFtKG4gLSBpLCBhW2ldLCByLCAwLCAwLCB0aGlzLnQgKyBpIC0gbilcbiAgci5jbGFtcCgpXG4gIHIuZHJTaGlmdFRvKDEsIHIpXG59XG5cbi8vIEJhcnJldHQgbW9kdWxhciByZWR1Y3Rpb25cbmZ1bmN0aW9uIEJhcnJldHQobSkge1xuICAvLyBzZXR1cCBCYXJyZXR0XG4gIHRoaXMucjIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMucTMgPSBuZXcgQmlnSW50ZWdlcigpXG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbygyICogbS50LCB0aGlzLnIyKVxuICB0aGlzLm11ID0gdGhpcy5yMi5kaXZpZGUobSlcbiAgdGhpcy5tID0gbVxufVxuXG5mdW5jdGlvbiBiYXJyZXR0Q29udmVydCh4KSB7XG4gIGlmICh4LnMgPCAwIHx8IHgudCA+IDIgKiB0aGlzLm0udCkgcmV0dXJuIHgubW9kKHRoaXMubSlcbiAgZWxzZSBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA8IDApIHJldHVybiB4XG4gIGVsc2Uge1xuICAgIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICAgIHguY29weVRvKHIpXG4gICAgdGhpcy5yZWR1Y2UocilcbiAgICByZXR1cm4gclxuICB9XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoeCkge1xuICByZXR1cm4geFxufVxuXG4vLyB4ID0geCBtb2QgbSAoSEFDIDE0LjQyKVxuZnVuY3Rpb24gYmFycmV0dFJlZHVjZSh4KSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB4LmRyU2hpZnRUbyhzZWxmLm0udCAtIDEsIHNlbGYucjIpXG4gIGlmICh4LnQgPiBzZWxmLm0udCArIDEpIHtcbiAgICB4LnQgPSBzZWxmLm0udCArIDFcbiAgICB4LmNsYW1wKClcbiAgfVxuICBzZWxmLm11Lm11bHRpcGx5VXBwZXJUbyhzZWxmLnIyLCBzZWxmLm0udCArIDEsIHNlbGYucTMpXG4gIHNlbGYubS5tdWx0aXBseUxvd2VyVG8oc2VsZi5xMywgc2VsZi5tLnQgKyAxLCBzZWxmLnIyKVxuICB3aGlsZSAoeC5jb21wYXJlVG8oc2VsZi5yMikgPCAwKSB4LmRBZGRPZmZzZXQoMSwgc2VsZi5tLnQgKyAxKVxuICB4LnN1YlRvKHNlbGYucjIsIHgpXG4gIHdoaWxlICh4LmNvbXBhcmVUbyhzZWxmLm0pID49IDApIHguc3ViVG8oc2VsZi5tLCB4KVxufVxuXG4vLyByID0geF4yIG1vZCBtOyB4ICE9IHJcbmZ1bmN0aW9uIGJhcnJldHRTcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocilcbiAgdGhpcy5yZWR1Y2Uocilcbn1cblxuLy8gciA9IHgqeSBtb2QgbTsgeCx5ICE9IHJcbmZ1bmN0aW9uIGJhcnJldHRNdWxUbyh4LCB5LCByKSB7XG4gIHgubXVsdGlwbHlUbyh5LCByKVxuICB0aGlzLnJlZHVjZShyKVxufVxuXG5CYXJyZXR0LnByb3RvdHlwZS5jb252ZXJ0ID0gYmFycmV0dENvbnZlcnRcbkJhcnJldHQucHJvdG90eXBlLnJldmVydCA9IGJhcnJldHRSZXZlcnRcbkJhcnJldHQucHJvdG90eXBlLnJlZHVjZSA9IGJhcnJldHRSZWR1Y2VcbkJhcnJldHQucHJvdG90eXBlLm11bFRvID0gYmFycmV0dE11bFRvXG5CYXJyZXR0LnByb3RvdHlwZS5zcXJUbyA9IGJhcnJldHRTcXJUb1xuXG4vLyAocHVibGljKSB0aGlzXmUgJSBtIChIQUMgMTQuODUpXG5mdW5jdGlvbiBibk1vZFBvdyhlLCBtKSB7XG4gIHZhciBpID0gZS5iaXRMZW5ndGgoKSxcbiAgICBrLCByID0gbmJ2KDEpLFxuICAgIHpcbiAgaWYgKGkgPD0gMCkgcmV0dXJuIHJcbiAgZWxzZSBpZiAoaSA8IDE4KSBrID0gMVxuICBlbHNlIGlmIChpIDwgNDgpIGsgPSAzXG4gIGVsc2UgaWYgKGkgPCAxNDQpIGsgPSA0XG4gIGVsc2UgaWYgKGkgPCA3NjgpIGsgPSA1XG4gIGVsc2UgayA9IDZcbiAgaWYgKGkgPCA4KVxuICAgIHogPSBuZXcgQ2xhc3NpYyhtKVxuICBlbHNlIGlmIChtLmlzRXZlbigpKVxuICAgIHogPSBuZXcgQmFycmV0dChtKVxuICBlbHNlXG4gICAgeiA9IG5ldyBNb250Z29tZXJ5KG0pXG5cbiAgLy8gcHJlY29tcHV0YXRpb25cbiAgdmFyIGcgPSBuZXcgQXJyYXkoKSxcbiAgICBuID0gMyxcbiAgICBrMSA9IGsgLSAxLFxuICAgIGttID0gKDEgPDwgaykgLSAxXG4gIGdbMV0gPSB6LmNvbnZlcnQodGhpcylcbiAgaWYgKGsgPiAxKSB7XG4gICAgdmFyIGcyID0gbmV3IEJpZ0ludGVnZXIoKVxuICAgIHouc3FyVG8oZ1sxXSwgZzIpXG4gICAgd2hpbGUgKG4gPD0ga20pIHtcbiAgICAgIGdbbl0gPSBuZXcgQmlnSW50ZWdlcigpXG4gICAgICB6Lm11bFRvKGcyLCBnW24gLSAyXSwgZ1tuXSlcbiAgICAgIG4gKz0gMlxuICAgIH1cbiAgfVxuXG4gIHZhciBqID0gZS50IC0gMSxcbiAgICB3LCBpczEgPSB0cnVlLFxuICAgIHIyID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICB0XG4gIGkgPSBuYml0cyhlW2pdKSAtIDFcbiAgd2hpbGUgKGogPj0gMCkge1xuICAgIGlmIChpID49IGsxKSB3ID0gKGVbal0gPj4gKGkgLSBrMSkpICYga21cbiAgICBlbHNlIHtcbiAgICAgIHcgPSAoZVtqXSAmICgoMSA8PCAoaSArIDEpKSAtIDEpKSA8PCAoazEgLSBpKVxuICAgICAgaWYgKGogPiAwKSB3IHw9IGVbaiAtIDFdID4+ICh0aGlzLkRCICsgaSAtIGsxKVxuICAgIH1cblxuICAgIG4gPSBrXG4gICAgd2hpbGUgKCh3ICYgMSkgPT0gMCkge1xuICAgICAgdyA+Pj0gMVxuICAgICAgLS1uXG4gICAgfVxuICAgIGlmICgoaSAtPSBuKSA8IDApIHtcbiAgICAgIGkgKz0gdGhpcy5EQlxuICAgICAgLS1qXG4gICAgfVxuICAgIGlmIChpczEpIHsgLy8gcmV0ID09IDEsIGRvbid0IGJvdGhlciBzcXVhcmluZyBvciBtdWx0aXBseWluZyBpdFxuICAgICAgZ1t3XS5jb3B5VG8ocilcbiAgICAgIGlzMSA9IGZhbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChuID4gMSkge1xuICAgICAgICB6LnNxclRvKHIsIHIyKVxuICAgICAgICB6LnNxclRvKHIyLCByKVxuICAgICAgICBuIC09IDJcbiAgICAgIH1cbiAgICAgIGlmIChuID4gMCkgei5zcXJUbyhyLCByMilcbiAgICAgIGVsc2Uge1xuICAgICAgICB0ID0gclxuICAgICAgICByID0gcjJcbiAgICAgICAgcjIgPSB0XG4gICAgICB9XG4gICAgICB6Lm11bFRvKHIyLCBnW3ddLCByKVxuICAgIH1cblxuICAgIHdoaWxlIChqID49IDAgJiYgKGVbal0gJiAoMSA8PCBpKSkgPT0gMCkge1xuICAgICAgei5zcXJUbyhyLCByMilcbiAgICAgIHQgPSByXG4gICAgICByID0gcjJcbiAgICAgIHIyID0gdFxuICAgICAgaWYgKC0taSA8IDApIHtcbiAgICAgICAgaSA9IHRoaXMuREIgLSAxXG4gICAgICAgIC0talxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gei5yZXZlcnQocilcbn1cblxuLy8gKHB1YmxpYykgZ2NkKHRoaXMsYSkgKEhBQyAxNC41NClcbmZ1bmN0aW9uIGJuR0NEKGEpIHtcbiAgdmFyIHggPSAodGhpcy5zIDwgMCkgPyB0aGlzLm5lZ2F0ZSgpIDogdGhpcy5jbG9uZSgpXG4gIHZhciB5ID0gKGEucyA8IDApID8gYS5uZWdhdGUoKSA6IGEuY2xvbmUoKVxuICBpZiAoeC5jb21wYXJlVG8oeSkgPCAwKSB7XG4gICAgdmFyIHQgPSB4XG4gICAgeCA9IHlcbiAgICB5ID0gdFxuICB9XG4gIHZhciBpID0geC5nZXRMb3dlc3RTZXRCaXQoKSxcbiAgICBnID0geS5nZXRMb3dlc3RTZXRCaXQoKVxuICBpZiAoZyA8IDApIHJldHVybiB4XG4gIGlmIChpIDwgZykgZyA9IGlcbiAgaWYgKGcgPiAwKSB7XG4gICAgeC5yU2hpZnRUbyhnLCB4KVxuICAgIHkuclNoaWZ0VG8oZywgeSlcbiAgfVxuICB3aGlsZSAoeC5zaWdudW0oKSA+IDApIHtcbiAgICBpZiAoKGkgPSB4LmdldExvd2VzdFNldEJpdCgpKSA+IDApIHguclNoaWZ0VG8oaSwgeClcbiAgICBpZiAoKGkgPSB5LmdldExvd2VzdFNldEJpdCgpKSA+IDApIHkuclNoaWZ0VG8oaSwgeSlcbiAgICBpZiAoeC5jb21wYXJlVG8oeSkgPj0gMCkge1xuICAgICAgeC5zdWJUbyh5LCB4KVxuICAgICAgeC5yU2hpZnRUbygxLCB4KVxuICAgIH0gZWxzZSB7XG4gICAgICB5LnN1YlRvKHgsIHkpXG4gICAgICB5LnJTaGlmdFRvKDEsIHkpXG4gICAgfVxuICB9XG4gIGlmIChnID4gMCkgeS5sU2hpZnRUbyhnLCB5KVxuICByZXR1cm4geVxufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzICUgbiwgbiA8IDJeMjZcbmZ1bmN0aW9uIGJucE1vZEludChuKSB7XG4gIGlmIChuIDw9IDApIHJldHVybiAwXG4gIHZhciBkID0gdGhpcy5EViAlIG4sXG4gICAgciA9ICh0aGlzLnMgPCAwKSA/IG4gLSAxIDogMFxuICBpZiAodGhpcy50ID4gMClcbiAgICBpZiAoZCA9PSAwKSByID0gdGhpc1swXSAlIG5cbiAgICBlbHNlXG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHIgPSAoZCAqIHIgKyB0aGlzW2ldKSAlIG5cbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgMS90aGlzICUgbSAoSEFDIDE0LjYxKVxuZnVuY3Rpb24gYm5Nb2RJbnZlcnNlKG0pIHtcbiAgdmFyIGFjID0gbS5pc0V2ZW4oKVxuICBpZiAodGhpcy5zaWdudW0oKSA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKCdkaXZpc2lvbiBieSB6ZXJvJylcbiAgaWYgKCh0aGlzLmlzRXZlbigpICYmIGFjKSB8fCBtLnNpZ251bSgpID09IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk9cbiAgdmFyIHUgPSBtLmNsb25lKCksXG4gICAgdiA9IHRoaXMuY2xvbmUoKVxuICB2YXIgYSA9IG5idigxKSxcbiAgICBiID0gbmJ2KDApLFxuICAgIGMgPSBuYnYoMCksXG4gICAgZCA9IG5idigxKVxuICB3aGlsZSAodS5zaWdudW0oKSAhPSAwKSB7XG4gICAgd2hpbGUgKHUuaXNFdmVuKCkpIHtcbiAgICAgIHUuclNoaWZ0VG8oMSwgdSlcbiAgICAgIGlmIChhYykge1xuICAgICAgICBpZiAoIWEuaXNFdmVuKCkgfHwgIWIuaXNFdmVuKCkpIHtcbiAgICAgICAgICBhLmFkZFRvKHRoaXMsIGEpXG4gICAgICAgICAgYi5zdWJUbyhtLCBiKVxuICAgICAgICB9XG4gICAgICAgIGEuclNoaWZ0VG8oMSwgYSlcbiAgICAgIH0gZWxzZSBpZiAoIWIuaXNFdmVuKCkpIGIuc3ViVG8obSwgYilcbiAgICAgIGIuclNoaWZ0VG8oMSwgYilcbiAgICB9XG4gICAgd2hpbGUgKHYuaXNFdmVuKCkpIHtcbiAgICAgIHYuclNoaWZ0VG8oMSwgdilcbiAgICAgIGlmIChhYykge1xuICAgICAgICBpZiAoIWMuaXNFdmVuKCkgfHwgIWQuaXNFdmVuKCkpIHtcbiAgICAgICAgICBjLmFkZFRvKHRoaXMsIGMpXG4gICAgICAgICAgZC5zdWJUbyhtLCBkKVxuICAgICAgICB9XG4gICAgICAgIGMuclNoaWZ0VG8oMSwgYylcbiAgICAgIH0gZWxzZSBpZiAoIWQuaXNFdmVuKCkpIGQuc3ViVG8obSwgZClcbiAgICAgIGQuclNoaWZ0VG8oMSwgZClcbiAgICB9XG4gICAgaWYgKHUuY29tcGFyZVRvKHYpID49IDApIHtcbiAgICAgIHUuc3ViVG8odiwgdSlcbiAgICAgIGlmIChhYykgYS5zdWJUbyhjLCBhKVxuICAgICAgYi5zdWJUbyhkLCBiKVxuICAgIH0gZWxzZSB7XG4gICAgICB2LnN1YlRvKHUsIHYpXG4gICAgICBpZiAoYWMpIGMuc3ViVG8oYSwgYylcbiAgICAgIGQuc3ViVG8oYiwgZClcbiAgICB9XG4gIH1cbiAgaWYgKHYuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPXG4gIHdoaWxlIChkLmNvbXBhcmVUbyhtKSA+PSAwKSBkLnN1YlRvKG0sIGQpXG4gIHdoaWxlIChkLnNpZ251bSgpIDwgMCkgZC5hZGRUbyhtLCBkKVxuICByZXR1cm4gZFxufVxuXG52YXIgbG93cHJpbWVzID0gW1xuICAyLCAzLCA1LCA3LCAxMSwgMTMsIDE3LCAxOSwgMjMsIDI5LCAzMSwgMzcsIDQxLCA0MywgNDcsIDUzLCA1OSwgNjEsIDY3LCA3MSxcbiAgNzMsIDc5LCA4MywgODksIDk3LCAxMDEsIDEwMywgMTA3LCAxMDksIDExMywgMTI3LCAxMzEsIDEzNywgMTM5LCAxNDksIDE1MSxcbiAgMTU3LCAxNjMsIDE2NywgMTczLCAxNzksIDE4MSwgMTkxLCAxOTMsIDE5NywgMTk5LCAyMTEsIDIyMywgMjI3LCAyMjksIDIzMyxcbiAgMjM5LCAyNDEsIDI1MSwgMjU3LCAyNjMsIDI2OSwgMjcxLCAyNzcsIDI4MSwgMjgzLCAyOTMsIDMwNywgMzExLCAzMTMsIDMxNyxcbiAgMzMxLCAzMzcsIDM0NywgMzQ5LCAzNTMsIDM1OSwgMzY3LCAzNzMsIDM3OSwgMzgzLCAzODksIDM5NywgNDAxLCA0MDksIDQxOSxcbiAgNDIxLCA0MzEsIDQzMywgNDM5LCA0NDMsIDQ0OSwgNDU3LCA0NjEsIDQ2MywgNDY3LCA0NzksIDQ4NywgNDkxLCA0OTksIDUwMyxcbiAgNTA5LCA1MjEsIDUyMywgNTQxLCA1NDcsIDU1NywgNTYzLCA1NjksIDU3MSwgNTc3LCA1ODcsIDU5MywgNTk5LCA2MDEsIDYwNyxcbiAgNjEzLCA2MTcsIDYxOSwgNjMxLCA2NDEsIDY0MywgNjQ3LCA2NTMsIDY1OSwgNjYxLCA2NzMsIDY3NywgNjgzLCA2OTEsIDcwMSxcbiAgNzA5LCA3MTksIDcyNywgNzMzLCA3MzksIDc0MywgNzUxLCA3NTcsIDc2MSwgNzY5LCA3NzMsIDc4NywgNzk3LCA4MDksIDgxMSxcbiAgODIxLCA4MjMsIDgyNywgODI5LCA4MzksIDg1MywgODU3LCA4NTksIDg2MywgODc3LCA4ODEsIDg4MywgODg3LCA5MDcsIDkxMSxcbiAgOTE5LCA5MjksIDkzNywgOTQxLCA5NDcsIDk1MywgOTY3LCA5NzEsIDk3NywgOTgzLCA5OTEsIDk5N1xuXVxuXG52YXIgbHBsaW0gPSAoMSA8PCAyNikgLyBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aCAtIDFdXG5cbi8vIChwdWJsaWMpIHRlc3QgcHJpbWFsaXR5IHdpdGggY2VydGFpbnR5ID49IDEtLjVedFxuZnVuY3Rpb24gYm5Jc1Byb2JhYmxlUHJpbWUodCkge1xuICB2YXIgaSwgeCA9IHRoaXMuYWJzKClcbiAgaWYgKHgudCA9PSAxICYmIHhbMF0gPD0gbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGggLSAxXSkge1xuICAgIGZvciAoaSA9IDA7IGkgPCBsb3dwcmltZXMubGVuZ3RoOyArK2kpXG4gICAgICBpZiAoeFswXSA9PSBsb3dwcmltZXNbaV0pIHJldHVybiB0cnVlXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgaWYgKHguaXNFdmVuKCkpIHJldHVybiBmYWxzZVxuICBpID0gMVxuICB3aGlsZSAoaSA8IGxvd3ByaW1lcy5sZW5ndGgpIHtcbiAgICB2YXIgbSA9IGxvd3ByaW1lc1tpXSxcbiAgICAgIGogPSBpICsgMVxuICAgIHdoaWxlIChqIDwgbG93cHJpbWVzLmxlbmd0aCAmJiBtIDwgbHBsaW0pIG0gKj0gbG93cHJpbWVzW2orK11cbiAgICBtID0geC5tb2RJbnQobSlcbiAgICB3aGlsZSAoaSA8IGopIGlmIChtICUgbG93cHJpbWVzW2krK10gPT0gMCkgcmV0dXJuIGZhbHNlXG4gIH1cbiAgcmV0dXJuIHgubWlsbGVyUmFiaW4odClcbn1cblxuLy8gKHByb3RlY3RlZCkgdHJ1ZSBpZiBwcm9iYWJseSBwcmltZSAoSEFDIDQuMjQsIE1pbGxlci1SYWJpbilcbmZ1bmN0aW9uIGJucE1pbGxlclJhYmluKHQpIHtcbiAgdmFyIG4xID0gdGhpcy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSlcbiAgdmFyIGsgPSBuMS5nZXRMb3dlc3RTZXRCaXQoKVxuICBpZiAoayA8PSAwKSByZXR1cm4gZmFsc2VcbiAgdmFyIHIgPSBuMS5zaGlmdFJpZ2h0KGspXG4gIHQgPSAodCArIDEpID4+IDFcbiAgaWYgKHQgPiBsb3dwcmltZXMubGVuZ3RoKSB0ID0gbG93cHJpbWVzLmxlbmd0aFxuICB2YXIgYSA9IG5ldyBCaWdJbnRlZ2VyKG51bGwpXG4gIHZhciBqLCBiYXNlcyA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdDsgKytpKSB7XG4gICAgZm9yICg7Oykge1xuICAgICAgaiA9IGxvd3ByaW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBsb3dwcmltZXMubGVuZ3RoKV1cbiAgICAgIGlmIChiYXNlcy5pbmRleE9mKGopID09IC0xKSBicmVha1xuICAgIH1cbiAgICBiYXNlcy5wdXNoKGopXG4gICAgYS5mcm9tSW50KGopXG4gICAgdmFyIHkgPSBhLm1vZFBvdyhyLCB0aGlzKVxuICAgIGlmICh5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkge1xuICAgICAgdmFyIGogPSAxXG4gICAgICB3aGlsZSAoaisrIDwgayAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkge1xuICAgICAgICB5ID0geS5tb2RQb3dJbnQoMiwgdGhpcylcbiAgICAgICAgaWYgKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICAgIGlmICh5LmNvbXBhcmVUbyhuMSkgIT0gMCkgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbi8vIHByb3RlY3RlZFxucHJvdG8uY2h1bmtTaXplID0gYm5wQ2h1bmtTaXplXG5wcm90by50b1JhZGl4ID0gYm5wVG9SYWRpeFxucHJvdG8uZnJvbVJhZGl4ID0gYm5wRnJvbVJhZGl4XG5wcm90by5mcm9tTnVtYmVyID0gYm5wRnJvbU51bWJlclxucHJvdG8uYml0d2lzZVRvID0gYm5wQml0d2lzZVRvXG5wcm90by5jaGFuZ2VCaXQgPSBibnBDaGFuZ2VCaXRcbnByb3RvLmFkZFRvID0gYm5wQWRkVG9cbnByb3RvLmRNdWx0aXBseSA9IGJucERNdWx0aXBseVxucHJvdG8uZEFkZE9mZnNldCA9IGJucERBZGRPZmZzZXRcbnByb3RvLm11bHRpcGx5TG93ZXJUbyA9IGJucE11bHRpcGx5TG93ZXJUb1xucHJvdG8ubXVsdGlwbHlVcHBlclRvID0gYm5wTXVsdGlwbHlVcHBlclRvXG5wcm90by5tb2RJbnQgPSBibnBNb2RJbnRcbnByb3RvLm1pbGxlclJhYmluID0gYm5wTWlsbGVyUmFiaW5cblxuLy8gcHVibGljXG5wcm90by5jbG9uZSA9IGJuQ2xvbmVcbnByb3RvLmludFZhbHVlID0gYm5JbnRWYWx1ZVxucHJvdG8uYnl0ZVZhbHVlID0gYm5CeXRlVmFsdWVcbnByb3RvLnNob3J0VmFsdWUgPSBiblNob3J0VmFsdWVcbnByb3RvLnNpZ251bSA9IGJuU2lnTnVtXG5wcm90by50b0J5dGVBcnJheSA9IGJuVG9CeXRlQXJyYXlcbnByb3RvLmVxdWFscyA9IGJuRXF1YWxzXG5wcm90by5taW4gPSBibk1pblxucHJvdG8ubWF4ID0gYm5NYXhcbnByb3RvLmFuZCA9IGJuQW5kXG5wcm90by5vciA9IGJuT3JcbnByb3RvLnhvciA9IGJuWG9yXG5wcm90by5hbmROb3QgPSBibkFuZE5vdFxucHJvdG8ubm90ID0gYm5Ob3RcbnByb3RvLnNoaWZ0TGVmdCA9IGJuU2hpZnRMZWZ0XG5wcm90by5zaGlmdFJpZ2h0ID0gYm5TaGlmdFJpZ2h0XG5wcm90by5nZXRMb3dlc3RTZXRCaXQgPSBibkdldExvd2VzdFNldEJpdFxucHJvdG8uYml0Q291bnQgPSBibkJpdENvdW50XG5wcm90by50ZXN0Qml0ID0gYm5UZXN0Qml0XG5wcm90by5zZXRCaXQgPSBiblNldEJpdFxucHJvdG8uY2xlYXJCaXQgPSBibkNsZWFyQml0XG5wcm90by5mbGlwQml0ID0gYm5GbGlwQml0XG5wcm90by5hZGQgPSBibkFkZFxucHJvdG8uc3VidHJhY3QgPSBiblN1YnRyYWN0XG5wcm90by5tdWx0aXBseSA9IGJuTXVsdGlwbHlcbnByb3RvLmRpdmlkZSA9IGJuRGl2aWRlXG5wcm90by5yZW1haW5kZXIgPSBiblJlbWFpbmRlclxucHJvdG8uZGl2aWRlQW5kUmVtYWluZGVyID0gYm5EaXZpZGVBbmRSZW1haW5kZXJcbnByb3RvLm1vZFBvdyA9IGJuTW9kUG93XG5wcm90by5tb2RJbnZlcnNlID0gYm5Nb2RJbnZlcnNlXG5wcm90by5wb3cgPSBiblBvd1xucHJvdG8uZ2NkID0gYm5HQ0RcbnByb3RvLmlzUHJvYmFibGVQcmltZSA9IGJuSXNQcm9iYWJsZVByaW1lXG5cbi8vIEpTQk4tc3BlY2lmaWMgZXh0ZW5zaW9uXG5wcm90by5zcXVhcmUgPSBiblNxdWFyZVxuXG4vLyBjb25zdGFudHNcbkJpZ0ludGVnZXIuWkVSTyA9IG5idigwKVxuQmlnSW50ZWdlci5PTkUgPSBuYnYoMSlcbkJpZ0ludGVnZXIudmFsdWVPZiA9IG5idlxuXG5tb2R1bGUuZXhwb3J0cyA9IEJpZ0ludGVnZXJcbiIsIi8vIEZJWE1FOiBLaW5kIG9mIGEgd2VpcmQgd2F5IHRvIHRocm93IGV4Y2VwdGlvbnMsIGNvbnNpZGVyIHJlbW92aW5nXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0JylcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9iaWdpJylcblxuLyoqXG4gKiBUdXJucyBhIGJ5dGUgYXJyYXkgaW50byBhIGJpZyBpbnRlZ2VyLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBpbnRlcnByZXQgYSBieXRlIGFycmF5IGFzIGEgYmlnIGludGVnZXIgaW4gYmlnXG4gKiBlbmRpYW4gbm90YXRpb24uXG4gKi9cbkJpZ0ludGVnZXIuZnJvbUJ5dGVBcnJheVVuc2lnbmVkID0gZnVuY3Rpb24oYnl0ZUFycmF5KSB7XG4gIC8vIEJpZ0ludGVnZXIgZXhwZWN0cyBhIERFUiBpbnRlZ2VyIGNvbmZvcm1hbnQgYnl0ZSBhcnJheVxuICBpZiAoYnl0ZUFycmF5WzBdICYgMHg4MCkge1xuICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihbMF0uY29uY2F0KGJ5dGVBcnJheSkpXG4gIH1cblxuICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoYnl0ZUFycmF5KVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBieXRlIGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBiaWcgaW50ZWdlci5cbiAqXG4gKiBUaGlzIHJldHVybnMgdGhlIGFic29sdXRlIG9mIHRoZSBjb250YWluZWQgdmFsdWUgaW4gYmlnIGVuZGlhblxuICogZm9ybS4gQSB2YWx1ZSBvZiB6ZXJvIHJlc3VsdHMgaW4gYW4gZW1wdHkgYXJyYXkuXG4gKi9cbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5VW5zaWduZWQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IHRoaXMudG9CeXRlQXJyYXkoKVxuICByZXR1cm4gYnl0ZUFycmF5WzBdID09PSAwID8gYnl0ZUFycmF5LnNsaWNlKDEpIDogYnl0ZUFycmF5XG59XG5cbkJpZ0ludGVnZXIuZnJvbURFUkludGVnZXIgPSBmdW5jdGlvbihieXRlQXJyYXkpIHtcbiAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGJ5dGVBcnJheSlcbn1cblxuLypcbiAqIENvbnZlcnRzIEJpZ0ludGVnZXIgdG8gYSBERVIgaW50ZWdlciByZXByZXNlbnRhdGlvbi5cbiAqXG4gKiBUaGUgZm9ybWF0IGZvciB0aGlzIHZhbHVlIHVzZXMgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0IGFzIGEgc2lnblxuICogYml0LiAgSWYgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0IGlzIGFscmVhZHkgc2V0IGFuZCB0aGUgaW50ZWdlciBpc1xuICogcG9zaXRpdmUsIGEgMHgwMCBpcyBwcmVwZW5kZWQuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICAwID0+ICAgICAweDAwXG4gKiAgICAgIDEgPT4gICAgIDB4MDFcbiAqICAgICAtMSA9PiAgICAgMHhmZlxuICogICAgMTI3ID0+ICAgICAweDdmXG4gKiAgIC0xMjcgPT4gICAgIDB4ODFcbiAqICAgIDEyOCA9PiAgIDB4MDA4MFxuICogICAtMTI4ID0+ICAgICAweDgwXG4gKiAgICAyNTUgPT4gICAweDAwZmZcbiAqICAgLTI1NSA9PiAgIDB4ZmYwMVxuICogIDE2MzAwID0+ICAgMHgzZmFjXG4gKiAtMTYzMDAgPT4gICAweGMwNTRcbiAqICA2MjMwMCA9PiAweDAwZjM1Y1xuICogLTYyMzAwID0+IDB4ZmYwY2E0XG4qL1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9ERVJJbnRlZ2VyID0gQmlnSW50ZWdlci5wcm90b3R5cGUudG9CeXRlQXJyYXlcblxuQmlnSW50ZWdlci5mcm9tQnVmZmVyID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIC8vIEJpZ0ludGVnZXIgZXhwZWN0cyBhIERFUiBpbnRlZ2VyIGNvbmZvcm1hbnQgYnl0ZSBhcnJheVxuICBpZiAoYnVmZmVyWzBdICYgMHg4MCkge1xuICAgIHZhciBieXRlQXJyYXkgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChidWZmZXIpXG5cbiAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoWzBdLmNvbmNhdChieXRlQXJyYXkpKVxuICB9XG5cbiAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGJ1ZmZlcilcbn1cblxuQmlnSW50ZWdlci5mcm9tSGV4ID0gZnVuY3Rpb24oaGV4KSB7XG4gIGlmIChoZXggPT09ICcnKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPXG5cbiAgYXNzZXJ0LmVxdWFsKGhleCwgaGV4Lm1hdGNoKC9eW0EtRmEtZjAtOV0rLyksICdJbnZhbGlkIGhleCBzdHJpbmcnKVxuICBhc3NlcnQuZXF1YWwoaGV4Lmxlbmd0aCAlIDIsIDAsICdJbmNvbXBsZXRlIGhleCcpXG4gIHJldHVybiBuZXcgQmlnSW50ZWdlcihoZXgsIDE2KVxufVxuXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J1ZmZlciA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IHRoaXMudG9CeXRlQXJyYXlVbnNpZ25lZCgpXG4gIHZhciB6ZXJvcyA9IFtdXG5cbiAgdmFyIHBhZGRpbmcgPSBzaXplIC0gYnl0ZUFycmF5Lmxlbmd0aFxuICB3aGlsZSAoemVyb3MubGVuZ3RoIDwgcGFkZGluZykgemVyb3MucHVzaCgwKVxuXG4gIHJldHVybiBuZXcgQnVmZmVyKHplcm9zLmNvbmNhdChieXRlQXJyYXkpKVxufVxuXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgcmV0dXJuIHRoaXMudG9CdWZmZXIoc2l6ZSkudG9TdHJpbmcoJ2hleCcpXG59XG4iLCJ2YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoMzApXG5cbi8vYWRkb25zXG5yZXF1aXJlKDMxKVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJpZ0ludGVnZXIiLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwiYnVnc1wiOiB7XG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vY3J5cHRvY29pbmpzL2JpZ2kvaXNzdWVzXCJcbiAgfSxcbiAgXCJidW5kbGVEZXBlbmRlbmNpZXNcIjogZmFsc2UsXG4gIFwiZGVwZW5kZW5jaWVzXCI6IHt9LFxuICBcImRlcHJlY2F0ZWRcIjogZmFsc2UsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJCaWcgaW50ZWdlcnMuXCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImNvdmVyYWxsc1wiOiBcIl4yLjExLjJcIixcbiAgICBcImlzdGFuYnVsXCI6IFwiXjAuMy41XCIsXG4gICAgXCJqc2hpbnRcIjogXCJeMi41LjFcIixcbiAgICBcIm1vY2hhXCI6IFwiXjIuMS4wXCIsXG4gICAgXCJtb2NoaWZ5XCI6IFwiXjIuMS4wXCJcbiAgfSxcbiAgXCJob21lcGFnZVwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG9jb2luanMvYmlnaSNyZWFkbWVcIixcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJjcnlwdG9ncmFwaHlcIixcbiAgICBcIm1hdGhcIixcbiAgICBcImJpdGNvaW5cIixcbiAgICBcImFyYml0cmFyeVwiLFxuICAgIFwicHJlY2lzaW9uXCIsXG4gICAgXCJhcml0aG1ldGljXCIsXG4gICAgXCJiaWdcIixcbiAgICBcImludGVnZXJcIixcbiAgICBcImludFwiLFxuICAgIFwibnVtYmVyXCIsXG4gICAgXCJiaWdpbnRlZ2VyXCIsXG4gICAgXCJiaWdpbnRcIixcbiAgICBcImJpZ251bWJlclwiLFxuICAgIFwiZGVjaW1hbFwiLFxuICAgIFwiZmxvYXRcIlxuICBdLFxuICBcIm1haW5cIjogXCIuL2xpYi9pbmRleC5qc1wiLFxuICBcIm5hbWVcIjogXCJiaWdpXCIsXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ1cmxcIjogXCJnaXQraHR0cHM6Ly9naXRodWIuY29tL2NyeXB0b2NvaW5qcy9iaWdpLmdpdFwiLFxuICAgIFwidHlwZVwiOiBcImdpdFwiXG4gIH0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJicm93c2VyLXRlc3RcIjogXCJtb2NoaWZ5IC0td2QgLVIgc3BlY1wiLFxuICAgIFwiY292ZXJhZ2VcIjogXCJpc3RhbmJ1bCBjb3ZlciAuL25vZGVfbW9kdWxlcy8uYmluL19tb2NoYSAtLSAtLXJlcG9ydGVyIGxpc3QgdGVzdC8qLmpzXCIsXG4gICAgXCJjb3ZlcmFsbHNcIjogXCJucG0gcnVuLXNjcmlwdCBjb3ZlcmFnZSAmJiBub2RlIC4vbm9kZV9tb2R1bGVzLy5iaW4vY292ZXJhbGxzIDwgY292ZXJhZ2UvbGNvdi5pbmZvXCIsXG4gICAgXCJqc2hpbnRcIjogXCJqc2hpbnQgLS1jb25maWcganNoaW50Lmpzb24gbGliLyouanMgOyB0cnVlXCIsXG4gICAgXCJ0ZXN0XCI6IFwiX21vY2hhIC0tIHRlc3QvKi5qc1wiLFxuICAgIFwidW5pdFwiOiBcIm1vY2hhXCJcbiAgfSxcbiAgXCJ0ZXN0bGluZ1wiOiB7XG4gICAgXCJmaWxlc1wiOiBcInRlc3QvKi5qc1wiLFxuICAgIFwiaGFybmVzc1wiOiBcIm1vY2hhXCIsXG4gICAgXCJicm93c2Vyc1wiOiBbXG4gICAgICBcImllLzkuLmxhdGVzdFwiLFxuICAgICAgXCJmaXJlZm94L2xhdGVzdFwiLFxuICAgICAgXCJjaHJvbWUvbGF0ZXN0XCIsXG4gICAgICBcInNhZmFyaS82LjAuLmxhdGVzdFwiLFxuICAgICAgXCJpcGhvbmUvNi4wLi5sYXRlc3RcIixcbiAgICAgIFwiYW5kcm9pZC1icm93c2VyLzQuMi4ubGF0ZXN0XCJcbiAgICBdXG4gIH0sXG4gIFwidmVyc2lvblwiOiBcIjEuNC4yXCJcbn0iLCIiLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG4ndXNlIHN0cmljdCdcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuLypcbiAqIEV4cG9ydCBrTWF4TGVuZ3RoIGFmdGVyIHR5cGVkIGFycmF5IHN1cHBvcnQgaXMgZGV0ZXJtaW5lZC5cbiAqL1xuZXhwb3J0cy5rTWF4TGVuZ3RoID0ga01heExlbmd0aCgpXG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuX19wcm90b19fID0ge19fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsIGZvbzogZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfX1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoa01heExlbmd0aCgpIDwgbGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoJylcbiAgfVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICBpZiAodGhhdCA9PT0gbnVsbCkge1xuICAgICAgdGhhdCA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICAgIH1cbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKHRoaXMsIGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuLy8gVE9ETzogTGVnYWN5LCBub3QgbmVlZGVkIGFueW1vcmUuIFJlbW92ZSBpbiBuZXh0IG1ham9yIHZlcnNpb24uXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gZnJvbSAodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIHJldHVybiBmcm9tT2JqZWN0KHRoYXQsIHZhbHVlKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKG51bGwsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbmlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICBCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG4gIEJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAmJlxuICAgICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gICAgLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgICAgdmFsdWU6IG51bGwsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG5lZ2F0aXZlJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAodGhhdCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2MobnVsbCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlICh0aGF0LCBzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplIDwgMCA/IDAgOiBjaGVja2VkKHNpemUpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7XG4gICAgICB0aGF0W2ldID0gMFxuICAgIH1cbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJlbmNvZGluZ1wiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgZW5jb2RpbmcnKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSB0aGF0LndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICB0aGF0ID0gdGhhdC5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyICh0aGF0LCBhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGFycmF5LmJ5dGVMZW5ndGggLy8gdGhpcyB0aHJvd3MgaWYgYGFycmF5YCBpcyBub3QgYSB2YWxpZCBBcnJheUJ1ZmZlclxuXG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdvZmZzZXRcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ2xlbmd0aFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldClcbiAgfSBlbHNlIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gYXJyYXlcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgdGhhdCA9IGZyb21BcnJheUxpa2UodGhhdCwgYXJyYXkpXG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAodGhhdCwgb2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuKVxuXG4gICAgaWYgKHRoYXQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdGhhdFxuICAgIH1cblxuICAgIG9iai5jb3B5KHRoYXQsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gdGhhdFxuICB9XG5cbiAgaWYgKG9iaikge1xuICAgIGlmICgodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICBvYmouYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHx8ICdsZW5ndGgnIGluIG9iaikge1xuICAgICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBpc25hbihvYmoubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIDApXG4gICAgICB9XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmopXG4gICAgfVxuXG4gICAgaWYgKG9iai50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iai5kYXRhKSkge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqLmRhdGEpXG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LicpXG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoKClgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnbGF0aW4xJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IHN0cmluZyBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHN0cmluZyA9ICcnICsgc3RyaW5nXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICAvLyBObyBuZWVkIHRvIHZlcmlmeSB0aGF0IFwidGhpcy5sZW5ndGggPD0gTUFYX1VJTlQzMlwiIHNpbmNlIGl0J3MgYSByZWFkLW9ubHlcbiAgLy8gcHJvcGVydHkgb2YgYSB0eXBlZCBhcnJheS5cblxuICAvLyBUaGlzIGJlaGF2ZXMgbmVpdGhlciBsaWtlIFN0cmluZyBub3IgVWludDhBcnJheSBpbiB0aGF0IHdlIHNldCBzdGFydC9lbmRcbiAgLy8gdG8gdGhlaXIgdXBwZXIvbG93ZXIgYm91bmRzIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgb3V0IG9mIHJhbmdlLlxuICAvLyB1bmRlZmluZWQgaXMgaGFuZGxlZCBzcGVjaWFsbHkgYXMgcGVyIEVDTUEtMjYyIDZ0aCBFZGl0aW9uLFxuICAvLyBTZWN0aW9uIDEzLjMuMy43IFJ1bnRpbWUgU2VtYW50aWNzOiBLZXllZEJpbmRpbmdJbml0aWFsaXphdGlvbi5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQgfHwgc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgLy8gUmV0dXJuIGVhcmx5IGlmIHN0YXJ0ID4gdGhpcy5sZW5ndGguIERvbmUgaGVyZSB0byBwcmV2ZW50IHBvdGVudGlhbCB1aW50MzJcbiAgLy8gY29lcmNpb24gZmFpbCBiZWxvdy5cbiAgaWYgKHN0YXJ0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoZW5kIDw9IDApIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIEZvcmNlIGNvZXJzaW9uIHRvIHVpbnQzMi4gVGhpcyB3aWxsIGFsc28gY29lcmNlIGZhbHNleS9OYU4gdmFsdWVzIHRvIDAuXG4gIGVuZCA+Pj49IDBcbiAgc3RhcnQgPj4+PSAwXG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbi8vIFRoZSBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIGFuZCBgaXMtYnVmZmVyYCAoaW4gU2FmYXJpIDUtNykgdG8gZGV0ZWN0XG4vLyBCdWZmZXIgaW5zdGFuY2VzLlxuQnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXIgPSB0cnVlXG5cbmZ1bmN0aW9uIHN3YXAgKGIsIG4sIG0pIHtcbiAgdmFyIGkgPSBiW25dXG4gIGJbbl0gPSBiW21dXG4gIGJbbV0gPSBpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2ID0gZnVuY3Rpb24gc3dhcDE2ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSAyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMSlcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAzMiA9IGZ1bmN0aW9uIHN3YXAzMiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMzItYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDMpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDIpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwNjQgPSBmdW5jdGlvbiBzd2FwNjQgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDggIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDY0LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDgpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyA3KVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyA2KVxuICAgIHN3YXAodGhpcywgaSArIDIsIGkgKyA1KVxuICAgIHN3YXAodGhpcywgaSArIDMsIGkgKyA0KVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIH1cblxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHRhcmdldCA/IHRhcmdldC5sZW5ndGggOiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc1N0YXJ0ID0gMFxuICB9XG4gIGlmICh0aGlzRW5kID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzRW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgZW5kID4gdGFyZ2V0Lmxlbmd0aCB8fCB0aGlzU3RhcnQgPCAwIHx8IHRoaXNFbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kICYmIHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cbiAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICBzdGFydCA+Pj49IDBcbiAgZW5kID4+Pj0gMFxuICB0aGlzU3RhcnQgPj4+PSAwXG4gIHRoaXNFbmQgPj4+PSAwXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCkgcmV0dXJuIDBcblxuICB2YXIgeCA9IHRoaXNFbmQgLSB0aGlzU3RhcnRcbiAgdmFyIHkgPSBlbmQgLSBzdGFydFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcblxuICB2YXIgdGhpc0NvcHkgPSB0aGlzLnNsaWNlKHRoaXNTdGFydCwgdGhpc0VuZClcbiAgdmFyIHRhcmdldENvcHkgPSB0YXJnZXQuc2xpY2Uoc3RhcnQsIGVuZClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKHRoaXNDb3B5W2ldICE9PSB0YXJnZXRDb3B5W2ldKSB7XG4gICAgICB4ID0gdGhpc0NvcHlbaV1cbiAgICAgIHkgPSB0YXJnZXRDb3B5W2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuLy8gRmluZHMgZWl0aGVyIHRoZSBmaXJzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPj0gYGJ5dGVPZmZzZXRgLFxuLy8gT1IgdGhlIGxhc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0IDw9IGBieXRlT2Zmc2V0YC5cbi8vXG4vLyBBcmd1bWVudHM6XG4vLyAtIGJ1ZmZlciAtIGEgQnVmZmVyIHRvIHNlYXJjaFxuLy8gLSB2YWwgLSBhIHN0cmluZywgQnVmZmVyLCBvciBudW1iZXJcbi8vIC0gYnl0ZU9mZnNldCAtIGFuIGluZGV4IGludG8gYGJ1ZmZlcmA7IHdpbGwgYmUgY2xhbXBlZCB0byBhbiBpbnQzMlxuLy8gLSBlbmNvZGluZyAtIGFuIG9wdGlvbmFsIGVuY29kaW5nLCByZWxldmFudCBpcyB2YWwgaXMgYSBzdHJpbmdcbi8vIC0gZGlyIC0gdHJ1ZSBmb3IgaW5kZXhPZiwgZmFsc2UgZm9yIGxhc3RJbmRleE9mXG5mdW5jdGlvbiBiaWRpcmVjdGlvbmFsSW5kZXhPZiAoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgLy8gRW1wdHkgYnVmZmVyIG1lYW5zIG5vIG1hdGNoXG4gIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldFxuICBpZiAodHlwZW9mIGJ5dGVPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBieXRlT2Zmc2V0XG4gICAgYnl0ZU9mZnNldCA9IDBcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0ID4gMHg3ZmZmZmZmZikge1xuICAgIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IC0weDgwMDAwMDAwKSB7XG4gICAgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIH1cbiAgYnl0ZU9mZnNldCA9ICtieXRlT2Zmc2V0ICAvLyBDb2VyY2UgdG8gTnVtYmVyLlxuICBpZiAoaXNOYU4oYnl0ZU9mZnNldCkpIHtcbiAgICAvLyBieXRlT2Zmc2V0OiBpdCBpdCdzIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBcImZvb1wiLCBldGMsIHNlYXJjaCB3aG9sZSBidWZmZXJcbiAgICBieXRlT2Zmc2V0ID0gZGlyID8gMCA6IChidWZmZXIubGVuZ3RoIC0gMSlcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0OiBuZWdhdGl2ZSBvZmZzZXRzIHN0YXJ0IGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gIGlmIChieXRlT2Zmc2V0IDwgMCkgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggKyBieXRlT2Zmc2V0XG4gIGlmIChieXRlT2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICBpZiAoZGlyKSByZXR1cm4gLTFcbiAgICBlbHNlIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoIC0gMVxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAwKSB7XG4gICAgaWYgKGRpcikgYnl0ZU9mZnNldCA9IDBcbiAgICBlbHNlIHJldHVybiAtMVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIHZhbFxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWwgPSBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2VhcmNoIGVpdGhlciBpbmRleE9mIChpZiBkaXIgaXMgdHJ1ZSkgb3IgbGFzdEluZGV4T2ZcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWwpKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcvYnVmZmVyIGFsd2F5cyBmYWlsc1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDB4RkYgLy8gU2VhcmNoIGZvciBhIGJ5dGUgdmFsdWUgWzAtMjU1XVxuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJlxuICAgICAgICB0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGRpcikge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCBbIHZhbCBdLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICB2YXIgaW5kZXhTaXplID0gMVxuICB2YXIgYXJyTGVuZ3RoID0gYXJyLmxlbmd0aFxuICB2YXIgdmFsTGVuZ3RoID0gdmFsLmxlbmd0aFxuXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICBpZiAoZW5jb2RpbmcgPT09ICd1Y3MyJyB8fCBlbmNvZGluZyA9PT0gJ3Vjcy0yJyB8fFxuICAgICAgICBlbmNvZGluZyA9PT0gJ3V0ZjE2bGUnIHx8IGVuY29kaW5nID09PSAndXRmLTE2bGUnKSB7XG4gICAgICBpZiAoYXJyLmxlbmd0aCA8IDIgfHwgdmFsLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9XG4gICAgICBpbmRleFNpemUgPSAyXG4gICAgICBhcnJMZW5ndGggLz0gMlxuICAgICAgdmFsTGVuZ3RoIC89IDJcbiAgICAgIGJ5dGVPZmZzZXQgLz0gMlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWQgKGJ1ZiwgaSkge1xuICAgIGlmIChpbmRleFNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBidWZbaV1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSAqIGluZGV4U2l6ZSlcbiAgICB9XG4gIH1cblxuICB2YXIgaVxuICBpZiAoZGlyKSB7XG4gICAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHJlYWQoYXJyLCBpKSA9PT0gcmVhZCh2YWwsIGZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4KSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbExlbmd0aCkgcmV0dXJuIGZvdW5kSW5kZXggKiBpbmRleFNpemVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGJ5dGVPZmZzZXQgKyB2YWxMZW5ndGggPiBhcnJMZW5ndGgpIGJ5dGVPZmZzZXQgPSBhcnJMZW5ndGggLSB2YWxMZW5ndGhcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGZvdW5kID0gdHJ1ZVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWxMZW5ndGg7IGorKykge1xuICAgICAgICBpZiAocmVhZChhcnIsIGkgKyBqKSAhPT0gcmVhZCh2YWwsIGopKSB7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIHRydWUpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbiBsYXN0SW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKGlzTmFOKHBhcnNlZCkpIHJldHVybiBpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBsYXRpbjFXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0J1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkJ1xuICAgIClcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gbGF0aW4xU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZClcbiAgICBuZXdCdWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47ICsraSkge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSAtIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSArIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbChcbiAgICAgIHRhcmdldCxcbiAgICAgIHRoaXMuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgbGVuKSxcbiAgICAgIHRhcmdldFN0YXJ0XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBVc2FnZTpcbi8vICAgIGJ1ZmZlci5maWxsKG51bWJlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoYnVmZmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChzdHJpbmdbLCBvZmZzZXRbLCBlbmRdXVssIGVuY29kaW5nXSlcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCwgZW5jb2RpbmcpIHtcbiAgLy8gSGFuZGxlIHN0cmluZyBjYXNlczpcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHR5cGVvZiBzdGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gc3RhcnRcbiAgICAgIHN0YXJ0ID0gMFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbmQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuZFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBjb2RlID0gdmFsLmNoYXJDb2RlQXQoMClcbiAgICAgIGlmIChjb2RlIDwgMjU2KSB7XG4gICAgICAgIHZhbCA9IGNvZGVcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAyNTVcbiAgfVxuXG4gIC8vIEludmFsaWQgcmFuZ2VzIGFyZSBub3Qgc2V0IHRvIGEgZGVmYXVsdCwgc28gY2FuIHJhbmdlIGNoZWNrIGVhcmx5LlxuICBpZiAoc3RhcnQgPCAwIHx8IHRoaXMubGVuZ3RoIDwgc3RhcnQgfHwgdGhpcy5sZW5ndGggPCBlbmQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IHRoaXMubGVuZ3RoIDogZW5kID4+PiAwXG5cbiAgaWYgKCF2YWwpIHZhbCA9IDBcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICB0aGlzW2ldID0gdmFsXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IEJ1ZmZlci5pc0J1ZmZlcih2YWwpXG4gICAgICA/IHZhbFxuICAgICAgOiB1dGY4VG9CeXRlcyhuZXcgQnVmZmVyKHZhbCwgZW5jb2RpbmcpLnRvU3RyaW5nKCkpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGZvciAoaSA9IDA7IGkgPCBlbmQgLSBzdGFydDsgKytpKSB7XG4gICAgICB0aGlzW2kgKyBzdGFydF0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGlzbmFuICh2YWwpIHtcbiAgcmV0dXJuIHZhbCAhPT0gdmFsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoMzUpLkJ1ZmZlcjtcblxudmFyIGlzQnVmZmVyRW5jb2RpbmcgPSBCdWZmZXIuaXNFbmNvZGluZ1xuICB8fCBmdW5jdGlvbihlbmNvZGluZykge1xuICAgICAgIHN3aXRjaCAoZW5jb2RpbmcgJiYgZW5jb2RpbmcudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgY2FzZSAnaGV4JzogY2FzZSAndXRmOCc6IGNhc2UgJ3V0Zi04JzogY2FzZSAnYXNjaWknOiBjYXNlICdiaW5hcnknOiBjYXNlICdiYXNlNjQnOiBjYXNlICd1Y3MyJzogY2FzZSAndWNzLTInOiBjYXNlICd1dGYxNmxlJzogY2FzZSAndXRmLTE2bGUnOiBjYXNlICdyYXcnOiByZXR1cm4gdHJ1ZTtcbiAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBmYWxzZTtcbiAgICAgICB9XG4gICAgIH1cblxuXG5mdW5jdGlvbiBhc3NlcnRFbmNvZGluZyhlbmNvZGluZykge1xuICBpZiAoZW5jb2RpbmcgJiYgIWlzQnVmZmVyRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB9XG59XG5cbi8vIFN0cmluZ0RlY29kZXIgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIGZvciBlZmZpY2llbnRseSBzcGxpdHRpbmcgYSBzZXJpZXMgb2Zcbi8vIGJ1ZmZlcnMgaW50byBhIHNlcmllcyBvZiBKUyBzdHJpbmdzIHdpdGhvdXQgYnJlYWtpbmcgYXBhcnQgbXVsdGktYnl0ZVxuLy8gY2hhcmFjdGVycy4gQ0VTVS04IGlzIGhhbmRsZWQgYXMgcGFydCBvZiB0aGUgVVRGLTggZW5jb2RpbmcuXG4vL1xuLy8gQFRPRE8gSGFuZGxpbmcgYWxsIGVuY29kaW5ncyBpbnNpZGUgYSBzaW5nbGUgb2JqZWN0IG1ha2VzIGl0IHZlcnkgZGlmZmljdWx0XG4vLyB0byByZWFzb24gYWJvdXQgdGhpcyBjb2RlLCBzbyBpdCBzaG91bGQgYmUgc3BsaXQgdXAgaW4gdGhlIGZ1dHVyZS5cbi8vIEBUT0RPIFRoZXJlIHNob3VsZCBiZSBhIHV0Zjgtc3RyaWN0IGVuY29kaW5nIHRoYXQgcmVqZWN0cyBpbnZhbGlkIFVURi04IGNvZGVcbi8vIHBvaW50cyBhcyB1c2VkIGJ5IENFU1UtOC5cbnZhciBTdHJpbmdEZWNvZGVyID0gZXhwb3J0cy5TdHJpbmdEZWNvZGVyID0gZnVuY3Rpb24oZW5jb2RpbmcpIHtcbiAgdGhpcy5lbmNvZGluZyA9IChlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXS8sICcnKTtcbiAgYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpO1xuICBzd2l0Y2ggKHRoaXMuZW5jb2RpbmcpIHtcbiAgICBjYXNlICd1dGY4JzpcbiAgICAgIC8vIENFU1UtOCByZXByZXNlbnRzIGVhY2ggb2YgU3Vycm9nYXRlIFBhaXIgYnkgMy1ieXRlc1xuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgLy8gVVRGLTE2IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAyLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAyO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXI7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgLy8gQmFzZS02NCBzdG9yZXMgMyBieXRlcyBpbiA0IGNoYXJzLCBhbmQgcGFkcyB0aGUgcmVtYWluZGVyLlxuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aGlzLndyaXRlID0gcGFzc1Rocm91Z2hXcml0ZTtcbiAgICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEVub3VnaCBzcGFjZSB0byBzdG9yZSBhbGwgYnl0ZXMgb2YgYSBzaW5nbGUgY2hhcmFjdGVyLiBVVEYtOCBuZWVkcyA0XG4gIC8vIGJ5dGVzLCBidXQgQ0VTVS04IG1heSByZXF1aXJlIHVwIHRvIDYgKDMgYnl0ZXMgcGVyIHN1cnJvZ2F0ZSkuXG4gIHRoaXMuY2hhckJ1ZmZlciA9IG5ldyBCdWZmZXIoNik7XG4gIC8vIE51bWJlciBvZiBieXRlcyByZWNlaXZlZCBmb3IgdGhlIGN1cnJlbnQgaW5jb21wbGV0ZSBtdWx0aS1ieXRlIGNoYXJhY3Rlci5cbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSAwO1xuICAvLyBOdW1iZXIgb2YgYnl0ZXMgZXhwZWN0ZWQgZm9yIHRoZSBjdXJyZW50IGluY29tcGxldGUgbXVsdGktYnl0ZSBjaGFyYWN0ZXIuXG4gIHRoaXMuY2hhckxlbmd0aCA9IDA7XG59O1xuXG5cbi8vIHdyaXRlIGRlY29kZXMgdGhlIGdpdmVuIGJ1ZmZlciBhbmQgcmV0dXJucyBpdCBhcyBKUyBzdHJpbmcgdGhhdCBpc1xuLy8gZ3VhcmFudGVlZCB0byBub3QgY29udGFpbiBhbnkgcGFydGlhbCBtdWx0aS1ieXRlIGNoYXJhY3RlcnMuIEFueSBwYXJ0aWFsXG4vLyBjaGFyYWN0ZXIgZm91bmQgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIGlzIGJ1ZmZlcmVkIHVwLCBhbmQgd2lsbCBiZVxuLy8gcmV0dXJuZWQgd2hlbiBjYWxsaW5nIHdyaXRlIGFnYWluIHdpdGggdGhlIHJlbWFpbmluZyBieXRlcy5cbi8vXG4vLyBOb3RlOiBDb252ZXJ0aW5nIGEgQnVmZmVyIGNvbnRhaW5pbmcgYW4gb3JwaGFuIHN1cnJvZ2F0ZSB0byBhIFN0cmluZ1xuLy8gY3VycmVudGx5IHdvcmtzLCBidXQgY29udmVydGluZyBhIFN0cmluZyB0byBhIEJ1ZmZlciAodmlhIGBuZXcgQnVmZmVyYCwgb3Jcbi8vIEJ1ZmZlciN3cml0ZSkgd2lsbCByZXBsYWNlIGluY29tcGxldGUgc3Vycm9nYXRlcyB3aXRoIHRoZSB1bmljb2RlXG4vLyByZXBsYWNlbWVudCBjaGFyYWN0ZXIuIFNlZSBodHRwczovL2NvZGVyZXZpZXcuY2hyb21pdW0ub3JnLzEyMTE3MzAwOS8gLlxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIGNoYXJTdHIgPSAnJztcbiAgLy8gaWYgb3VyIGxhc3Qgd3JpdGUgZW5kZWQgd2l0aCBhbiBpbmNvbXBsZXRlIG11bHRpYnl0ZSBjaGFyYWN0ZXJcbiAgd2hpbGUgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGRldGVybWluZSBob3cgbWFueSByZW1haW5pbmcgYnl0ZXMgdGhpcyBidWZmZXIgaGFzIHRvIG9mZmVyIGZvciB0aGlzIGNoYXJcbiAgICB2YXIgYXZhaWxhYmxlID0gKGJ1ZmZlci5sZW5ndGggPj0gdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQpID9cbiAgICAgICAgdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQgOlxuICAgICAgICBidWZmZXIubGVuZ3RoO1xuXG4gICAgLy8gYWRkIHRoZSBuZXcgYnl0ZXMgdG8gdGhlIGNoYXIgYnVmZmVyXG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCB0aGlzLmNoYXJSZWNlaXZlZCwgMCwgYXZhaWxhYmxlKTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCArPSBhdmFpbGFibGU7XG5cbiAgICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQgPCB0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAgIC8vIHN0aWxsIG5vdCBlbm91Z2ggY2hhcnMgaW4gdGhpcyBidWZmZXI/IHdhaXQgZm9yIG1vcmUgLi4uXG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGJ5dGVzIGJlbG9uZ2luZyB0byB0aGUgY3VycmVudCBjaGFyYWN0ZXIgZnJvbSB0aGUgYnVmZmVyXG4gICAgYnVmZmVyID0gYnVmZmVyLnNsaWNlKGF2YWlsYWJsZSwgYnVmZmVyLmxlbmd0aCk7XG5cbiAgICAvLyBnZXQgdGhlIGNoYXJhY3RlciB0aGF0IHdhcyBzcGxpdFxuICAgIGNoYXJTdHIgPSB0aGlzLmNoYXJCdWZmZXIuc2xpY2UoMCwgdGhpcy5jaGFyTGVuZ3RoKS50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcblxuICAgIC8vIENFU1UtODogbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgICB2YXIgY2hhckNvZGUgPSBjaGFyU3RyLmNoYXJDb2RlQXQoY2hhclN0ci5sZW5ndGggLSAxKTtcbiAgICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoICs9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICAgIGNoYXJTdHIgPSAnJztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0aGlzLmNoYXJSZWNlaXZlZCA9IHRoaXMuY2hhckxlbmd0aCA9IDA7XG5cbiAgICAvLyBpZiB0aGVyZSBhcmUgbm8gbW9yZSBieXRlcyBpbiB0aGlzIGJ1ZmZlciwganVzdCBlbWl0IG91ciBjaGFyXG4gICAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBjaGFyU3RyO1xuICAgIH1cbiAgICBicmVhaztcbiAgfVxuXG4gIC8vIGRldGVybWluZSBhbmQgc2V0IGNoYXJMZW5ndGggLyBjaGFyUmVjZWl2ZWRcbiAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpO1xuXG4gIHZhciBlbmQgPSBidWZmZXIubGVuZ3RoO1xuICBpZiAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gYnVmZmVyIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlciBieXRlcyB3ZSBnb3RcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCwgZW5kKTtcbiAgICBlbmQgLT0gdGhpcy5jaGFyUmVjZWl2ZWQ7XG4gIH1cblxuICBjaGFyU3RyICs9IGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCBlbmQpO1xuXG4gIHZhciBlbmQgPSBjaGFyU3RyLmxlbmd0aCAtIDE7XG4gIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChlbmQpO1xuICAvLyBDRVNVLTg6IGxlYWQgc3Vycm9nYXRlIChEODAwLURCRkYpIGlzIGFsc28gdGhlIGluY29tcGxldGUgY2hhcmFjdGVyXG4gIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgdmFyIHNpemUgPSB0aGlzLnN1cnJvZ2F0ZVNpemU7XG4gICAgdGhpcy5jaGFyTGVuZ3RoICs9IHNpemU7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gc2l6ZTtcbiAgICB0aGlzLmNoYXJCdWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIHNpemUsIDAsIHNpemUpO1xuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgMCwgMCwgc2l6ZSk7XG4gICAgcmV0dXJuIGNoYXJTdHIuc3Vic3RyaW5nKDAsIGVuZCk7XG4gIH1cblxuICAvLyBvciBqdXN0IGVtaXQgdGhlIGNoYXJTdHJcbiAgcmV0dXJuIGNoYXJTdHI7XG59O1xuXG4vLyBkZXRlY3RJbmNvbXBsZXRlQ2hhciBkZXRlcm1pbmVzIGlmIHRoZXJlIGlzIGFuIGluY29tcGxldGUgVVRGLTggY2hhcmFjdGVyIGF0XG4vLyB0aGUgZW5kIG9mIHRoZSBnaXZlbiBidWZmZXIuIElmIHNvLCBpdCBzZXRzIHRoaXMuY2hhckxlbmd0aCB0byB0aGUgYnl0ZVxuLy8gbGVuZ3RoIHRoYXQgY2hhcmFjdGVyLCBhbmQgc2V0cyB0aGlzLmNoYXJSZWNlaXZlZCB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzXG4vLyB0aGF0IGFyZSBhdmFpbGFibGUgZm9yIHRoaXMgY2hhcmFjdGVyLlxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IGJ5dGVzIHdlIGhhdmUgdG8gY2hlY2sgYXQgdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlclxuICB2YXIgaSA9IChidWZmZXIubGVuZ3RoID49IDMpID8gMyA6IGJ1ZmZlci5sZW5ndGg7XG5cbiAgLy8gRmlndXJlIG91dCBpZiBvbmUgb2YgdGhlIGxhc3QgaSBieXRlcyBvZiBvdXIgYnVmZmVyIGFubm91bmNlcyBhblxuICAvLyBpbmNvbXBsZXRlIGNoYXIuXG4gIGZvciAoOyBpID4gMDsgaS0tKSB7XG4gICAgdmFyIGMgPSBidWZmZXJbYnVmZmVyLmxlbmd0aCAtIGldO1xuXG4gICAgLy8gU2VlIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTgjRGVzY3JpcHRpb25cblxuICAgIC8vIDExMFhYWFhYXG4gICAgaWYgKGkgPT0gMSAmJiBjID4+IDUgPT0gMHgwNikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMjtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTBYWFhYXG4gICAgaWYgKGkgPD0gMiAmJiBjID4+IDQgPT0gMHgwRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMztcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTEwWFhYXG4gICAgaWYgKGkgPD0gMyAmJiBjID4+IDMgPT0gMHgxRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGk7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBpZiAoYnVmZmVyICYmIGJ1ZmZlci5sZW5ndGgpXG4gICAgcmVzID0gdGhpcy53cml0ZShidWZmZXIpO1xuXG4gIGlmICh0aGlzLmNoYXJSZWNlaXZlZCkge1xuICAgIHZhciBjciA9IHRoaXMuY2hhclJlY2VpdmVkO1xuICAgIHZhciBidWYgPSB0aGlzLmNoYXJCdWZmZXI7XG4gICAgdmFyIGVuYyA9IHRoaXMuZW5jb2Rpbmc7XG4gICAgcmVzICs9IGJ1Zi5zbGljZSgwLCBjcikudG9TdHJpbmcoZW5jKTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcikge1xuICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAyO1xuICB0aGlzLmNoYXJMZW5ndGggPSB0aGlzLmNoYXJSZWNlaXZlZCA/IDIgOiAwO1xufVxuXG5mdW5jdGlvbiBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpIHtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBidWZmZXIubGVuZ3RoICUgMztcbiAgdGhpcy5jaGFyTGVuZ3RoID0gdGhpcy5jaGFyUmVjZWl2ZWQgPyAzIDogMDtcbn1cbiIsInZhciBiYXNleCA9IHJlcXVpcmUoMjgpXG52YXIgQUxQSEFCRVQgPSAnMTIzNDU2Nzg5QUJDREVGR0hKS0xNTlBRUlNUVVZXWFlaYWJjZGVmZ2hpamttbm9wcXJzdHV2d3h5eidcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNleChBTFBIQUJFVClcbiIsIi8qXHJcbiBDb3B5cmlnaHQgMjAxMy0yMDE0IERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcblxyXG4gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcclxuIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cclxuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG5cclxuIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcclxuIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcclxuIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxyXG4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxyXG4gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEBsaWNlbnNlIGJ5dGVidWZmZXIuanMgKGMpIDIwMTUgRGFuaWVsIFdpcnR6IDxkY29kZUBkY29kZS5pbz5cclxuICogQmFja2luZyBidWZmZXI6IEFycmF5QnVmZmVyLCBBY2Nlc3NvcjogVWludDhBcnJheVxyXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wXHJcbiAqIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vYnl0ZWJ1ZmZlci5qcyBmb3IgZGV0YWlsc1xyXG4gKi9cclxuKGZ1bmN0aW9uKGdsb2JhbCwgZmFjdG9yeSkge1xyXG5cclxuICAgIC8qIEFNRCAqLyBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmVbXCJhbWRcIl0pXHJcbiAgICAgICAgZGVmaW5lKFtcImxvbmdcIl0sIGZhY3RvcnkpO1xyXG4gICAgLyogQ29tbW9uSlMgKi8gZWxzZSBpZiAodHlwZW9mIHJlcXVpcmUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiBtb2R1bGUgJiYgbW9kdWxlW1wiZXhwb3J0c1wiXSlcclxuICAgICAgICBtb2R1bGVbJ2V4cG9ydHMnXSA9IChmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgdmFyIExvbmc7IHRyeSB7IExvbmcgPSByZXF1aXJlKDY4KTsgfSBjYXRjaCAoZSkge31cclxuICAgICAgICAgICAgcmV0dXJuIGZhY3RvcnkoTG9uZyk7XHJcbiAgICAgICAgfSkoKTtcclxuICAgIC8qIEdsb2JhbCAqLyBlbHNlXHJcbiAgICAgICAgKGdsb2JhbFtcImRjb2RlSU9cIl0gPSBnbG9iYWxbXCJkY29kZUlPXCJdIHx8IHt9KVtcIkJ5dGVCdWZmZXJcIl0gPSBmYWN0b3J5KGdsb2JhbFtcImRjb2RlSU9cIl1bXCJMb25nXCJdKTtcclxuXHJcbn0pKHRoaXMsIGZ1bmN0aW9uKExvbmcpIHtcclxuICAgIFwidXNlIHN0cmljdFwiO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBCeXRlQnVmZmVyLlxyXG4gICAgICogQGNsYXNzIFRoZSBzd2lzcyBhcm15IGtuaWZlIGZvciBiaW5hcnkgZGF0YSBpbiBKYXZhU2NyaXB0LlxyXG4gICAgICogQGV4cG9ydHMgQnl0ZUJ1ZmZlclxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGNhcGFjaXR5IEluaXRpYWwgY2FwYWNpdHkuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfQ0FQQUNJVFl9LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbm9Bc3NlcnQgV2hldGhlciB0byBza2lwIGFzc2VydGlvbnMgb2Ygb2Zmc2V0cyBhbmQgdmFsdWVzLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlR9LlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICB2YXIgQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGNhcGFjaXR5LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBjYXBhY2l0eSA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIGNhcGFjaXR5ID0gQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZO1xyXG4gICAgICAgIGlmICh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTjtcclxuICAgICAgICBpZiAodHlwZW9mIG5vQXNzZXJ0ID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgbm9Bc3NlcnQgPSBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlQ7XHJcbiAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBjYXBhY2l0eSA9IGNhcGFjaXR5IHwgMDtcclxuICAgICAgICAgICAgaWYgKGNhcGFjaXR5IDwgMClcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIGNhcGFjaXR5XCIpO1xyXG4gICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSAhIWxpdHRsZUVuZGlhbjtcclxuICAgICAgICAgICAgbm9Bc3NlcnQgPSAhIW5vQXNzZXJ0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQmFja2luZyBBcnJheUJ1ZmZlci5cclxuICAgICAgICAgKiBAdHlwZSB7IUFycmF5QnVmZmVyfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmJ1ZmZlciA9IGNhcGFjaXR5ID09PSAwID8gRU1QVFlfQlVGRkVSIDogbmV3IEFycmF5QnVmZmVyKGNhcGFjaXR5KTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVWludDhBcnJheSB1dGlsaXplZCB0byBtYW5pcHVsYXRlIHRoZSBiYWNraW5nIGJ1ZmZlci4gQmVjb21lcyBgbnVsbGAgaWYgdGhlIGJhY2tpbmcgYnVmZmVyIGhhcyBhIGNhcGFjaXR5IG9mIGAwYC5cclxuICAgICAgICAgKiBAdHlwZSB7P1VpbnQ4QXJyYXl9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMudmlldyA9IGNhcGFjaXR5ID09PSAwID8gbnVsbCA6IG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyKTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQWJzb2x1dGUgcmVhZC93cml0ZSBvZmZzZXQuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICogQHNlZSBCeXRlQnVmZmVyI2ZsaXBcclxuICAgICAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjY2xlYXJcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLm9mZnNldCA9IDA7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE1hcmtlZCBvZmZzZXQuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICogQHNlZSBCeXRlQnVmZmVyI21hcmtcclxuICAgICAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjcmVzZXRcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLm1hcmtlZE9mZnNldCA9IC0xO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBBYnNvbHV0ZSBsaW1pdCBvZiB0aGUgY29udGFpbmVkIGRhdGEuIFNldCB0byB0aGUgYmFja2luZyBidWZmZXIncyBjYXBhY2l0eSB1cG9uIGFsbG9jYXRpb24uXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICogQHNlZSBCeXRlQnVmZmVyI2ZsaXBcclxuICAgICAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjY2xlYXJcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmxpbWl0ID0gY2FwYWNpdHk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlciwgZGVmYXVsdHMgdG8gYGZhbHNlYCBmb3IgYmlnIGVuZGlhbi5cclxuICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5saXR0bGVFbmRpYW4gPSBsaXR0bGVFbmRpYW47XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcywgZGVmYXVsdHMgdG8gYGZhbHNlYC5cclxuICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5ub0Fzc2VydCA9IG5vQXNzZXJ0O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEJ5dGVCdWZmZXIgdmVyc2lvbi5cclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5WRVJTSU9OID0gXCI1LjAuMVwiO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTGl0dGxlIGVuZGlhbiBjb25zdGFudCB0aGF0IGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgaXRzIGJvb2xlYW4gdmFsdWUuIEV2YWx1YXRlcyB0byBgdHJ1ZWAuXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4gPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQmlnIGVuZGlhbiBjb25zdGFudCB0aGF0IGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgaXRzIGJvb2xlYW4gdmFsdWUuIEV2YWx1YXRlcyB0byBgZmFsc2VgLlxyXG4gICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5CSUdfRU5ESUFOID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZhdWx0IGluaXRpYWwgY2FwYWNpdHkgb2YgYDE2YC5cclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuREVGQVVMVF9DQVBBQ0lUWSA9IDE2O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmYXVsdCBlbmRpYW5lc3Mgb2YgYGZhbHNlYCBmb3IgYmlnIGVuZGlhbi5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOID0gQnl0ZUJ1ZmZlci5CSUdfRU5ESUFOO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmYXVsdCBubyBhc3NlcnRpb25zIGZsYWcgb2YgYGZhbHNlYC5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlQgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEEgYExvbmdgIGNsYXNzIGZvciByZXByZXNlbnRpbmcgYSA2NC1iaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyIHZhbHVlLiBNYXkgYmUgYG51bGxgIGlmIExvbmcuanMgaGFzIG5vdCBiZWVuIGxvYWRlZFxyXG4gICAgICogIGFuZCBpbnQ2NCBzdXBwb3J0IGlzIG5vdCBhdmFpbGFibGUuXHJcbiAgICAgKiBAdHlwZSB7P0xvbmd9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vbG9uZy5qc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkxvbmcgPSBMb25nIHx8IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAYWxpYXMgQnl0ZUJ1ZmZlci5wcm90b3R5cGVcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgQnl0ZUJ1ZmZlclByb3RvdHlwZSA9IEJ5dGVCdWZmZXIucHJvdG90eXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW4gaW5kaWNhdG9yIHVzZWQgdG8gcmVsaWFibHkgZGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBhIEJ5dGVCdWZmZXIgb3Igbm90LlxyXG4gICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuX19pc0J5dGVCdWZmZXJfXztcclxuXHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnl0ZUJ1ZmZlclByb3RvdHlwZSwgXCJfX2lzQnl0ZUJ1ZmZlcl9fXCIsIHtcclxuICAgICAgICB2YWx1ZTogdHJ1ZSxcclxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlXHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBoZWxwZXJzXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7IUFycmF5QnVmZmVyfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBFTVBUWV9CVUZGRVIgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdHJpbmcuZnJvbUNoYXJDb2RlIHJlZmVyZW5jZSBmb3IgY29tcGlsZS10aW1lIHJlbmFtaW5nLlxyXG4gICAgICogQHR5cGUge2Z1bmN0aW9uKC4uLm51bWJlcik6c3RyaW5nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBzdHJpbmdGcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIHNvdXJjZSBmdW5jdGlvbiBmb3IgYSBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcyBTdHJpbmcgdG8gcmVhZCBmcm9tXHJcbiAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb24oKTpudW1iZXJ8bnVsbH0gU291cmNlIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjaGFyIGNvZGUgcmVzcGVjdGl2ZWx5IGBudWxsYCBpZiB0aGVyZSBhcmVcclxuICAgICAqICBubyBtb3JlIGNoYXJhY3RlcnMgbGVmdC5cclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgdGhlIGFyZ3VtZW50IGlzIGludmFsaWRcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBzdHJpbmdTb3VyY2Uocykge1xyXG4gICAgICAgIHZhciBpPTA7IHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGkgPCBzLmxlbmd0aCA/IHMuY2hhckNvZGVBdChpKyspIDogbnVsbDtcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIGRlc3RpbmF0aW9uIGZ1bmN0aW9uIGZvciBhIHN0cmluZy5cclxuICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbihudW1iZXI9KTp1bmRlZmluZWR8c3RyaW5nfSBEZXN0aW5hdGlvbiBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggdGhlIG5leHQgY2hhciBjb2RlLlxyXG4gICAgICogIFJldHVybnMgdGhlIGZpbmFsIHN0cmluZyB3aGVuIGNhbGxlZCB3aXRob3V0IGFyZ3VtZW50cy5cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBzdHJpbmdEZXN0aW5hdGlvbigpIHtcclxuICAgICAgICB2YXIgY3MgPSBbXSwgcHMgPSBbXTsgcmV0dXJuIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcclxuICAgICAgICAgICAgICAgIHJldHVybiBwcy5qb2luKCcnKStzdHJpbmdGcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjcyk7XHJcbiAgICAgICAgICAgIGlmIChjcy5sZW5ndGggKyBhcmd1bWVudHMubGVuZ3RoID4gMTAyNClcclxuICAgICAgICAgICAgICAgIHBzLnB1c2goc3RyaW5nRnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY3MpKSxcclxuICAgICAgICAgICAgICAgICAgICBjcy5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgYWNjZXNzb3IgdHlwZS5cclxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gYEJ1ZmZlcmAgdW5kZXIgbm9kZS5qcywgYFVpbnQ4QXJyYXlgIHJlc3BlY3RpdmVseSBgRGF0YVZpZXdgIGluIHRoZSBicm93c2VyIChjbGFzc2VzKVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmFjY2Vzc29yID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBBbGxvY2F0ZXMgYSBuZXcgQnl0ZUJ1ZmZlciBiYWNrZWQgYnkgYSBidWZmZXIgb2YgdGhlIHNwZWNpZmllZCBjYXBhY2l0eS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gY2FwYWNpdHkgSW5pdGlhbCBjYXBhY2l0eS4gRGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9DQVBBQ0lUWX0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0Fzc2VydCBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuYWxsb2NhdGUgPSBmdW5jdGlvbihjYXBhY2l0eSwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQnl0ZUJ1ZmZlcihjYXBhY2l0eSwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uY2F0ZW5hdGVzIG11bHRpcGxlIEJ5dGVCdWZmZXJzIGludG8gb25lLlxyXG4gICAgICogQHBhcmFtIHshQXJyYXkuPCFCeXRlQnVmZmVyfCFBcnJheUJ1ZmZlcnwhVWludDhBcnJheXxzdHJpbmc+fSBidWZmZXJzIEJ1ZmZlcnMgdG8gY29uY2F0ZW5hdGVcclxuICAgICAqIEBwYXJhbSB7KHN0cmluZ3xib29sZWFuKT19IGVuY29kaW5nIFN0cmluZyBlbmNvZGluZyBpZiBgYnVmZmVyc2AgY29udGFpbnMgYSBzdHJpbmcgKFwiYmFzZTY0XCIsIFwiaGV4XCIsIFwiYmluYXJ5XCIsXHJcbiAgICAgKiAgZGVmYXVsdHMgdG8gXCJ1dGY4XCIpXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlciBmb3IgdGhlIHJlc3VsdGluZyBCeXRlQnVmZmVyLiBEZWZhdWx0c1xyXG4gICAgICogIHRvIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcyBmb3IgdGhlIHJlc3VsdGluZyBCeXRlQnVmZmVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBDb25jYXRlbmF0ZWQgQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uKGJ1ZmZlcnMsIGVuY29kaW5nLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Jvb2xlYW4nIHx8IHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgbm9Bc3NlcnQgPSBsaXR0bGVFbmRpYW47XHJcbiAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IGVuY29kaW5nO1xyXG4gICAgICAgICAgICBlbmNvZGluZyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNhcGFjaXR5ID0gMDtcclxuICAgICAgICBmb3IgKHZhciBpPTAsIGs9YnVmZmVycy5sZW5ndGgsIGxlbmd0aDsgaTxrOyArK2kpIHtcclxuICAgICAgICAgICAgaWYgKCFCeXRlQnVmZmVyLmlzQnl0ZUJ1ZmZlcihidWZmZXJzW2ldKSlcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcnNbaV0gPSBCeXRlQnVmZmVyLndyYXAoYnVmZmVyc1tpXSwgZW5jb2RpbmcpO1xyXG4gICAgICAgICAgICBsZW5ndGggPSBidWZmZXJzW2ldLmxpbWl0IC0gYnVmZmVyc1tpXS5vZmZzZXQ7XHJcbiAgICAgICAgICAgIGlmIChsZW5ndGggPiAwKSBjYXBhY2l0eSArPSBsZW5ndGg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjYXBhY2l0eSA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBCeXRlQnVmZmVyKDAsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpO1xyXG4gICAgICAgIHZhciBiYiA9IG5ldyBCeXRlQnVmZmVyKGNhcGFjaXR5LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSxcclxuICAgICAgICAgICAgYmk7XHJcbiAgICAgICAgaT0wOyB3aGlsZSAoaTxrKSB7XHJcbiAgICAgICAgICAgIGJpID0gYnVmZmVyc1tpKytdO1xyXG4gICAgICAgICAgICBsZW5ndGggPSBiaS5saW1pdCAtIGJpLm9mZnNldDtcclxuICAgICAgICAgICAgaWYgKGxlbmd0aCA8PSAwKSBjb250aW51ZTtcclxuICAgICAgICAgICAgYmIudmlldy5zZXQoYmkudmlldy5zdWJhcnJheShiaS5vZmZzZXQsIGJpLmxpbWl0KSwgYmIub2Zmc2V0KTtcclxuICAgICAgICAgICAgYmIub2Zmc2V0ICs9IGxlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgYmIubGltaXQgPSBiYi5vZmZzZXQ7XHJcbiAgICAgICAgYmIub2Zmc2V0ID0gMDtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB0eXBlIGlzIGEgQnl0ZUJ1ZmZlci5cclxuICAgICAqIEBwYXJhbSB7Kn0gYmIgQnl0ZUJ1ZmZlciB0byB0ZXN0XHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIGl0IGlzIGEgQnl0ZUJ1ZmZlciwgb3RoZXJ3aXNlIGBmYWxzZWBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5pc0J5dGVCdWZmZXIgPSBmdW5jdGlvbihiYikge1xyXG4gICAgICAgIHJldHVybiAoYmIgJiYgYmJbXCJfX2lzQnl0ZUJ1ZmZlcl9fXCJdKSA9PT0gdHJ1ZTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGJhY2tpbmcgYnVmZmVyIHR5cGUuXHJcbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IGBCdWZmZXJgIHVuZGVyIG5vZGUuanMsIGBBcnJheUJ1ZmZlcmAgaW4gdGhlIGJyb3dzZXIgKGNsYXNzZXMpXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIudHlwZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBBcnJheUJ1ZmZlcjtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFdyYXBzIGEgYnVmZmVyIG9yIGEgc3RyaW5nLiBTZXRzIHRoZSBhbGxvY2F0ZWQgQnl0ZUJ1ZmZlcidzIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gdG8gYDBgIGFuZCBpdHNcclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0gdG8gdGhlIGxlbmd0aCBvZiB0aGUgd3JhcHBlZCBkYXRhLlxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcnwhQXJyYXlCdWZmZXJ8IVVpbnQ4QXJyYXl8c3RyaW5nfCFBcnJheS48bnVtYmVyPn0gYnVmZmVyIEFueXRoaW5nIHRoYXQgY2FuIGJlIHdyYXBwZWRcclxuICAgICAqIEBwYXJhbSB7KHN0cmluZ3xib29sZWFuKT19IGVuY29kaW5nIFN0cmluZyBlbmNvZGluZyBpZiBgYnVmZmVyYCBpcyBhIHN0cmluZyAoXCJiYXNlNjRcIiwgXCJoZXhcIiwgXCJiaW5hcnlcIiwgZGVmYXVsdHMgdG9cclxuICAgICAqICBcInV0ZjhcIilcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcy4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQSBCeXRlQnVmZmVyIHdyYXBwaW5nIGBidWZmZXJgXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIud3JhcCA9IGZ1bmN0aW9uKGJ1ZmZlciwgZW5jb2RpbmcsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBub0Fzc2VydCA9IGxpdHRsZUVuZGlhbjtcclxuICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gZW5jb2Rpbmc7XHJcbiAgICAgICAgICAgIGVuY29kaW5nID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHlwZW9mIGJ1ZmZlciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgICAgICBlbmNvZGluZyA9IFwidXRmOFwiO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiYmFzZTY0XCI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbUJhc2U2NChidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiaGV4XCI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbUhleChidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiYmluYXJ5XCI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbUJpbmFyeShidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwidXRmOFwiOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21VVEY4KGJ1ZmZlciwgbGl0dGxlRW5kaWFuKTtcclxuICAgICAgICAgICAgICAgIGNhc2UgXCJkZWJ1Z1wiOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21EZWJ1ZyhidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiVW5zdXBwb3J0ZWQgZW5jb2Rpbmc6IFwiK2VuY29kaW5nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYnVmZmVyID09PSBudWxsIHx8IHR5cGVvZiBidWZmZXIgIT09ICdvYmplY3QnKVxyXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJ1ZmZlclwiKTtcclxuICAgICAgICB2YXIgYmI7XHJcbiAgICAgICAgaWYgKEJ5dGVCdWZmZXIuaXNCeXRlQnVmZmVyKGJ1ZmZlcikpIHtcclxuICAgICAgICAgICAgYmIgPSBCeXRlQnVmZmVyUHJvdG90eXBlLmNsb25lLmNhbGwoYnVmZmVyKTtcclxuICAgICAgICAgICAgYmIubWFya2VkT2Zmc2V0ID0gLTE7XHJcbiAgICAgICAgICAgIHJldHVybiBiYjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsgLy8gRXh0cmFjdCBBcnJheUJ1ZmZlciBmcm9tIFVpbnQ4QXJyYXlcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcigwLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KTtcclxuICAgICAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiAwKSB7IC8vIEF2b2lkIHJlZmVyZW5jZXMgdG8gbW9yZSB0aGFuIG9uZSBFTVBUWV9CVUZGRVJcclxuICAgICAgICAgICAgICAgIGJiLmJ1ZmZlciA9IGJ1ZmZlci5idWZmZXI7XHJcbiAgICAgICAgICAgICAgICBiYi5vZmZzZXQgPSBidWZmZXIuYnl0ZU9mZnNldDtcclxuICAgICAgICAgICAgICAgIGJiLmxpbWl0ID0gYnVmZmVyLmJ5dGVPZmZzZXQgKyBidWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgICAgICAgICAgICAgIGJiLnZpZXcgPSBuZXcgVWludDhBcnJheShidWZmZXIuYnVmZmVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAoYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsgLy8gUmV1c2UgQXJyYXlCdWZmZXJcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcigwLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KTtcclxuICAgICAgICAgICAgaWYgKGJ1ZmZlci5ieXRlTGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgYmIuYnVmZmVyID0gYnVmZmVyO1xyXG4gICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgIGJiLmxpbWl0ID0gYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICBiYi52aWV3ID0gYnVmZmVyLmJ5dGVMZW5ndGggPiAwID8gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSA6IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChidWZmZXIpID09PSBcIltvYmplY3QgQXJyYXldXCIpIHsgLy8gQ3JlYXRlIGZyb20gb2N0ZXRzXHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoYnVmZmVyLmxlbmd0aCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCk7XHJcbiAgICAgICAgICAgIGJiLmxpbWl0ID0gYnVmZmVyLmxlbmd0aDtcclxuICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpPGJ1ZmZlci5sZW5ndGg7ICsraSlcclxuICAgICAgICAgICAgICAgIGJiLnZpZXdbaV0gPSBidWZmZXJbaV07XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYnVmZmVyXCIpOyAvLyBPdGhlcndpc2UgZmFpbFxyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgdGhlIGFycmF5IGFzIGEgYml0c2V0LlxyXG4gICAgICogQHBhcmFtIHtBcnJheTxib29sZWFuPn0gdmFsdWUgQXJyYXkgb2YgYm9vbGVhbnMgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGBsZW5ndGhgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVCaXRTZXQgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgQXJyYXkpKVxyXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBCaXRTZXQ6IE5vdCBhbiBhcnJheVwiKTtcclxuICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgICBiaXRzID0gdmFsdWUubGVuZ3RoLFxyXG4gICAgICAgICAgYnl0ZXMgPSAoYml0cyA+PiAzKSxcclxuICAgICAgICAgIGJpdCA9IDAsXHJcbiAgICAgICAgICBrO1xyXG5cclxuICAgICAgb2Zmc2V0ICs9IHRoaXMud3JpdGVWYXJpbnQzMihiaXRzLG9mZnNldCk7XHJcblxyXG4gICAgICB3aGlsZShieXRlcy0tKSB7XHJcbiAgICAgICAgayA9ICghIXZhbHVlW2JpdCsrXSAmIDEpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDEpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDIpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDMpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDQpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDUpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDYpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDcpO1xyXG4gICAgICAgIHRoaXMud3JpdGVCeXRlKGssb2Zmc2V0KyspO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZihiaXQgPCBiaXRzKSB7XHJcbiAgICAgICAgdmFyIG0gPSAwOyBrID0gMDtcclxuICAgICAgICB3aGlsZShiaXQgPCBiaXRzKSBrID0gayB8ICgoISF2YWx1ZVtiaXQrK10gJiAxKSA8PCAobSsrKSk7XHJcbiAgICAgICAgdGhpcy53cml0ZUJ5dGUoayxvZmZzZXQrKyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBvZmZzZXQgLSBzdGFydDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgQml0U2V0IGFzIGFuIGFycmF5IG9mIGJvb2xlYW5zLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYGxlbmd0aGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtBcnJheTxib29sZWFuPlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRCaXRTZXQgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuXHJcbiAgICAgIHZhciByZXQgPSB0aGlzLnJlYWRWYXJpbnQzMihvZmZzZXQpLFxyXG4gICAgICAgICAgYml0cyA9IHJldC52YWx1ZSxcclxuICAgICAgICAgIGJ5dGVzID0gKGJpdHMgPj4gMyksXHJcbiAgICAgICAgICBiaXQgPSAwLFxyXG4gICAgICAgICAgdmFsdWUgPSBbXSxcclxuICAgICAgICAgIGs7XHJcblxyXG4gICAgICBvZmZzZXQgKz0gcmV0Lmxlbmd0aDtcclxuXHJcbiAgICAgIHdoaWxlKGJ5dGVzLS0pIHtcclxuICAgICAgICBrID0gdGhpcy5yZWFkQnl0ZShvZmZzZXQrKyk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4MDEpO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDAyKTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHgwNCk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4MDgpO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDEwKTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHgyMCk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4NDApO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDgwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYoYml0IDwgYml0cykge1xyXG4gICAgICAgIHZhciBtID0gMDtcclxuICAgICAgICBrID0gdGhpcy5yZWFkQnl0ZShvZmZzZXQrKyk7XHJcbiAgICAgICAgd2hpbGUoYml0IDwgYml0cykgdmFsdWVbYml0KytdID0gISEoKGsgPj4gKG0rKykpICYgMSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBieXRlcyB0byByZWFkXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgbGVuZ3RoYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRCeXRlcyA9IGZ1bmN0aW9uKGxlbmd0aCwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgbGVuZ3RoID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrbGVuZ3RoK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzbGljZSA9IHRoaXMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBsZW5ndGgpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gbGVuZ3RoO1xuICAgICAgICByZXR1cm4gc2xpY2U7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgcGF5bG9hZCBvZiBieXRlcy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNhcHBlbmR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFCeXRlQnVmZmVyfCFBcnJheUJ1ZmZlcnwhVWludDhBcnJheXxzdHJpbmd9IHNvdXJjZSBEYXRhIHRvIHdyaXRlLiBJZiBgc291cmNlYCBpcyBhIEJ5dGVCdWZmZXIsIGl0cyBvZmZzZXRzXHJcbiAgICAgKiAgd2lsbCBiZSBtb2RpZmllZCBhY2NvcmRpbmcgdG8gdGhlIHBlcmZvcm1lZCByZWFkIG9wZXJhdGlvbi5cclxuICAgICAqIEBwYXJhbSB7KHN0cmluZ3xudW1iZXIpPX0gZW5jb2RpbmcgRW5jb2RpbmcgaWYgYGRhdGFgIGlzIGEgc3RyaW5nIChcImJhc2U2NFwiLCBcImhleFwiLCBcImJpbmFyeVwiLCBkZWZhdWx0cyB0byBcInV0ZjhcIilcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlQnl0ZXMgPSBCeXRlQnVmZmVyUHJvdG90eXBlLmFwcGVuZDtcclxuXHJcbiAgICAvLyB0eXBlcy9pbnRzL2ludDhcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiA4Yml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgIHZhciBjYXBhY2l0eTAgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkwKVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MCAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MCA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSAxO1xuICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0XSA9IHZhbHVlO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIDhiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVJbnQ4fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUJ5dGUgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50ODtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGFuIDhiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMSA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzErXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy52aWV3W29mZnNldF07XHJcbiAgICAgICAgaWYgKCh2YWx1ZSAmIDB4ODApID09PSAweDgwKSB2YWx1ZSA9IC0oMHhGRiAtIHZhbHVlICsgMSk7IC8vIENhc3QgdG8gc2lnbmVkXHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAxO1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gOGJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkSW50OH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEJ5dGUgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQ4O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIDhiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50OCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICB2YXIgY2FwYWNpdHkxID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MSlcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTEgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTEgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gMTtcbiAgICAgICAgdGhpcy52aWV3W29mZnNldF0gPSB2YWx1ZTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDE7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiA4Yml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVVaW50OH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVSW50OCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50ODtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGFuIDhiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMSA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzErXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy52aWV3W29mZnNldF07XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAxO1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gOGJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRVaW50OH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVJbnQ4ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDg7XHJcblxyXG4gICAgLy8gdHlwZXMvaW50cy9pbnQxNlxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMTZiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgb3IgYHZhbHVlYCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDE2ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSB8PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICB2YXIgY2FwYWNpdHkyID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MilcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTIgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTIgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gMjtcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgJiAweEZGMDApID4+PiA4O1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIHZhbHVlICYgMHgwMEZGO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXRdICAgPSAodmFsdWUgJiAweEZGMDApID4+PiA4O1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gIHZhbHVlICYgMHgwMEZGO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDI7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDE2Yml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlSW50MTZ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgb3IgYHZhbHVlYCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVNob3J0ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDE2O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAxNmJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDIgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisyK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IDA7XHJcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQgIF07XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgODtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDg7XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICgodmFsdWUgJiAweDgwMDApID09PSAweDgwMDApIHZhbHVlID0gLSgweEZGRkYgLSB2YWx1ZSArIDEpOyAvLyBDYXN0IHRvIHNpZ25lZFxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMjtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMTZiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZEludDE2fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFNob3J0ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50MTY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAxNmJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIG9yIGB2YWx1ZWAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50MTYgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgdmFyIGNhcGFjaXR5MyA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTMpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkzICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkzIDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDI7XG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKHZhbHVlICYgMHhGRjAwKSA+Pj4gODtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICB2YWx1ZSAmIDB4MDBGRjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0XSAgID0gKHZhbHVlICYgMHhGRjAwKSA+Pj4gODtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9ICB2YWx1ZSAmIDB4MDBGRjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAyO1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAxNmJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlVWludDE2fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIG9yIGB2YWx1ZWAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVSW50MTYgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDE2O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAxNmJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDIgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisyK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IDA7XHJcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQgIF07XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgODtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDg7XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMjtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMTZiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkVWludDE2fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVJbnQxNiA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQxNjtcclxuXHJcbiAgICAvLyB0eXBlcy9pbnRzL2ludDMyXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAzMmJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDMyID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSB8PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSA0O1xuICAgICAgICB2YXIgY2FwYWNpdHk0ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5NClcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTQgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTQgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gNDtcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKHZhbHVlID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9ICh2YWx1ZSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIHZhbHVlICAgICAgICAgJiAweEZGO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKHZhbHVlID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICB2YWx1ZSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlSW50MzJ9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDMyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIis0K1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IDA7XHJcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8IDE2O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQgIF07XG4gICAgICAgICAgICB2YWx1ZSArPSB0aGlzLnZpZXdbb2Zmc2V0KzNdIDw8IDI0ID4+PiAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAxNjtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgIDg7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgdmFsdWUgKz0gdGhpcy52aWV3W29mZnNldCAgXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZSB8PSAwOyAvLyBDYXN0IHRvIHNpZ25lZFxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gNDtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMzJiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZEludDMyfS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDMyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMzJiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVpbnQzMiA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSA0O1xuICAgICAgICB2YXIgY2FwYWNpdHk1ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5NSlcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTUgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTUgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gNDtcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKHZhbHVlID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9ICh2YWx1ZSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIHZhbHVlICAgICAgICAgJiAweEZGO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKHZhbHVlID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICB2YWx1ZSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVVaW50MzJ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVSW50MzIgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDMyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIis0K1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IDA7XHJcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8IDE2O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQgIF07XG4gICAgICAgICAgICB2YWx1ZSArPSB0aGlzLnZpZXdbb2Zmc2V0KzNdIDw8IDI0ID4+PiAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAxNjtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgIDg7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgdmFsdWUgKz0gdGhpcy52aWV3W29mZnNldCAgXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDMyYml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZFVpbnQzMn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVSW50MzIgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVaW50MzI7XHJcblxyXG4gICAgLy8gdHlwZXMvaW50cy9pbnQ2NFxyXG5cclxuICAgIGlmIChMb25nKSB7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdyaXRlcyBhIDY0Yml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQ2NCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghKHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgTG9uZykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlciBvciBMb25nKVwiKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICBvZmZzZXQgKz0gODtcbiAgICAgICAgICAgIHZhciBjYXBhY2l0eTYgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5NilcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHk2ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHk2IDogb2Zmc2V0KTtcbiAgICAgICAgICAgIG9mZnNldCAtPSA4O1xuICAgICAgICAgICAgdmFyIGxvID0gdmFsdWUubG93LFxyXG4gICAgICAgICAgICAgICAgaGkgPSB2YWx1ZS5oaWdoO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAobG8gPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChsbyA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGxvID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgbG8gICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKGhpID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAoaGkgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChoaSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIGhpICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAoaGkgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChoaSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGhpID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAgaGkgICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gKGxvID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAobG8gPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChsbyA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gIGxvICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXcml0ZXMgYSA2NGJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZUludDY0fS5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlTG9uZyA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQ2NDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSA2NGJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDY0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDggPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrOCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBsbyA9IDAsXHJcbiAgICAgICAgICAgICAgICBoaSA9IDA7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICAgICAgbG8gID0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQgIF07XG4gICAgICAgICAgICAgICAgbG8gKz0gdGhpcy52aWV3W29mZnNldCszXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIGhpICA9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgMTY7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xuICAgICAgICAgICAgICAgIGhpICs9IHRoaXMudmlld1tvZmZzZXQrM10gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaGkgID0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQrM107XG4gICAgICAgICAgICAgICAgaGkgKz0gdGhpcy52aWV3W29mZnNldCAgXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIGxvICA9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgMTY7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAgODtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgICAgIGxvICs9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IG5ldyBMb25nKGxvLCBoaSwgZmFsc2UpO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSA2NGJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkSW50NjR9LlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkTG9uZyA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDY0O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXcml0ZXMgYSA2NGJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50NjQgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoISh2YWx1ZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIExvbmcpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIgb3IgTG9uZylcIik7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgb2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICB2YXIgY2FwYWNpdHk3ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTcpXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5NyAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5NyA6IG9mZnNldCk7XG4gICAgICAgICAgICBvZmZzZXQgLT0gODtcbiAgICAgICAgICAgIHZhciBsbyA9IHZhbHVlLmxvdyxcclxuICAgICAgICAgICAgICAgIGhpID0gdmFsdWUuaGlnaDtcclxuICAgICAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKGxvID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAobG8gPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChsbyA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIGxvICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9IChoaSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGhpID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAoaGkgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICBoaSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gKGhpID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAoaGkgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChoaSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gIGhpICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9IChsbyA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGxvID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAobG8gPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICBsbyAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA4O1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV3JpdGVzIGEgNjRiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZVVpbnQ2NH0uXHJcbiAgICAgICAgICogQGZ1bmN0aW9uXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVJbnQ2NCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50NjQ7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlYWRzIGEgNjRiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQ2NCA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA4ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzgrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgbG8gPSAwLFxyXG4gICAgICAgICAgICAgICAgaGkgPSAwO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgICAgIGxvICA9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgMTY7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xuICAgICAgICAgICAgICAgIGxvICs9IHRoaXMudmlld1tvZmZzZXQrM10gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICBoaSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgIDg7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCAgXTtcbiAgICAgICAgICAgICAgICBoaSArPSB0aGlzLnZpZXdbb2Zmc2V0KzNdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGhpICA9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgMTY7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAgODtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgICAgIGhpICs9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICBsbyAgPSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgIDg7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCszXTtcbiAgICAgICAgICAgICAgICBsbyArPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBuZXcgTG9uZyhsbywgaGksIHRydWUpO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSA2NGJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRVaW50NjR9LlxyXG4gICAgICAgICAqIEBmdW5jdGlvblxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVUludDY0ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDY0O1xyXG5cclxuICAgIH0gLy8gTG9uZ1xyXG5cclxuXHJcbiAgICAvLyB0eXBlcy9mbG9hdHMvZmxvYXQzMlxyXG5cclxuICAgIC8qXHJcbiAgICAgaWVlZTc1NCAtIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvaWVlZTc1NFxyXG5cclxuICAgICBUaGUgTUlUIExpY2Vuc2UgKE1JVClcclxuXHJcbiAgICAgQ29weXJpZ2h0IChjKSBGZXJvc3MgQWJvdWtoYWRpamVoXHJcblxyXG4gICAgIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcclxuICAgICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXHJcbiAgICAgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xyXG4gICAgIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcclxuICAgICBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcclxuICAgICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxyXG5cclxuICAgICBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxyXG4gICAgIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxyXG5cclxuICAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXHJcbiAgICAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXHJcbiAgICAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXHJcbiAgICAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxyXG4gICAgIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXHJcbiAgICAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxyXG4gICAgIFRIRSBTT0ZUV0FSRS5cclxuICAgICovXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhbiBJRUVFNzU0IGZsb2F0IGZyb20gYSBieXRlIGFycmF5LlxyXG4gICAgICogQHBhcmFtIHshQXJyYXl9IGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBpc0xFXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbUxlblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG5CeXRlc1xyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBpZWVlNzU0X3JlYWQoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xyXG4gICAgICAgIHZhciBlLCBtLFxyXG4gICAgICAgICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxyXG4gICAgICAgICAgICBlTWF4ID0gKDEgPDwgZUxlbikgLSAxLFxyXG4gICAgICAgICAgICBlQmlhcyA9IGVNYXggPj4gMSxcclxuICAgICAgICAgICAgbkJpdHMgPSAtNyxcclxuICAgICAgICAgICAgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwLFxyXG4gICAgICAgICAgICBkID0gaXNMRSA/IC0xIDogMSxcclxuICAgICAgICAgICAgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXTtcclxuXHJcbiAgICAgICAgaSArPSBkO1xyXG5cclxuICAgICAgICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKTtcclxuICAgICAgICBzID4+PSAoLW5CaXRzKTtcclxuICAgICAgICBuQml0cyArPSBlTGVuO1xyXG4gICAgICAgIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XHJcblxyXG4gICAgICAgIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpO1xyXG4gICAgICAgIGUgPj49ICgtbkJpdHMpO1xyXG4gICAgICAgIG5CaXRzICs9IG1MZW47XHJcbiAgICAgICAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cclxuXHJcbiAgICAgICAgaWYgKGUgPT09IDApIHtcclxuICAgICAgICAgICAgZSA9IDEgLSBlQmlhcztcclxuICAgICAgICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbik7XHJcbiAgICAgICAgICAgIGUgPSBlIC0gZUJpYXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIElFRUU3NTQgZmxvYXQgdG8gYSBieXRlIGFycmF5LlxyXG4gICAgICogQHBhcmFtIHshQXJyYXl9IGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGlzTEVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtTGVuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbkJ5dGVzXHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gaWVlZTc1NF93cml0ZShidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xyXG4gICAgICAgIHZhciBlLCBtLCBjLFxyXG4gICAgICAgICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxyXG4gICAgICAgICAgICBlTWF4ID0gKDEgPDwgZUxlbikgLSAxLFxyXG4gICAgICAgICAgICBlQmlhcyA9IGVNYXggPj4gMSxcclxuICAgICAgICAgICAgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApLFxyXG4gICAgICAgICAgICBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSksXHJcbiAgICAgICAgICAgIGQgPSBpc0xFID8gMSA6IC0xLFxyXG4gICAgICAgICAgICBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwO1xyXG5cclxuICAgICAgICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKTtcclxuXHJcbiAgICAgICAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcclxuICAgICAgICAgICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwO1xyXG4gICAgICAgICAgICBlID0gZU1heDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMik7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcclxuICAgICAgICAgICAgICAgIGUtLTtcclxuICAgICAgICAgICAgICAgIGMgKj0gMjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlICs9IHJ0IC8gYztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcclxuICAgICAgICAgICAgICAgIGUrKztcclxuICAgICAgICAgICAgICAgIGMgLz0gMjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XHJcbiAgICAgICAgICAgICAgICBtID0gMDtcclxuICAgICAgICAgICAgICAgIGUgPSBlTWF4O1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XHJcbiAgICAgICAgICAgICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XHJcbiAgICAgICAgICAgICAgICBlID0gZSArIGVCaWFzO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xyXG4gICAgICAgICAgICAgICAgZSA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XHJcblxyXG4gICAgICAgIGUgPSAoZSA8PCBtTGVuKSB8IG07XHJcbiAgICAgICAgZUxlbiArPSBtTGVuO1xyXG4gICAgICAgIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cclxuXHJcbiAgICAgICAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMzJiaXQgZmxvYXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUZsb2F0MzIgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYSBudW1iZXIpXCIpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDQ7XG4gICAgICAgIHZhciBjYXBhY2l0eTggPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHk4KVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5OCAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5OCA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSA0O1xuICAgICAgICBpZWVlNzU0X3dyaXRlKHRoaXMudmlldywgdmFsdWUsIG9mZnNldCwgdGhpcy5saXR0bGVFbmRpYW4sIDIzLCA0KTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IGZsb2F0LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlRmxvYXQzMn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRmxvYXQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRmxvYXQzMjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMzJiaXQgZmxvYXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEZsb2F0MzIgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA0ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrNCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSBpZWVlNzU0X3JlYWQodGhpcy52aWV3LCBvZmZzZXQsIHRoaXMubGl0dGxlRW5kaWFuLCAyMywgNCk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA0O1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCBmbG9hdC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkRmxvYXQzMn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkRmxvYXQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRGbG9hdDMyO1xyXG5cclxuICAgIC8vIHR5cGVzL2Zsb2F0cy9mbG9hdDY0XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSA2NGJpdCBmbG9hdC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRmxvYXQ2NCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhIG51bWJlcilcIik7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gODtcbiAgICAgICAgdmFyIGNhcGFjaXR5OSA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTkpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHk5ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHk5IDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDg7XG4gICAgICAgIGllZWU3NTRfd3JpdGUodGhpcy52aWV3LCB2YWx1ZSwgb2Zmc2V0LCB0aGlzLmxpdHRsZUVuZGlhbiwgNTIsIDgpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gODtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgNjRiaXQgZmxvYXQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVGbG9hdDY0fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVEb3VibGUgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRmxvYXQ2NDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgNjRiaXQgZmxvYXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEZsb2F0NjQgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA4ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrOCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSBpZWVlNzU0X3JlYWQodGhpcy52aWV3LCBvZmZzZXQsIHRoaXMubGl0dGxlRW5kaWFuLCA1MiwgOCk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA4O1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSA2NGJpdCBmbG9hdC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkRmxvYXQ2NH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkRG91YmxlID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkRmxvYXQ2NDtcclxuXHJcblxyXG4gICAgLy8gdHlwZXMvdmFyaW50cy92YXJpbnQzMlxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgYSAzMmJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5NQVhfVkFSSU5UMzJfQllURVMgPSA1O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBzdG9yZSBhIDMyYml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIGVuY29kZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkLiBDYXBwZWQgdG8ge0BsaW5rIEJ5dGVCdWZmZXIuTUFYX1ZBUklOVDMyX0JZVEVTfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmNhbGN1bGF0ZVZhcmludDMyID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICAvLyByZWY6IHNyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmNjXHJcbiAgICAgICAgdmFsdWUgPSB2YWx1ZSA+Pj4gMDtcclxuICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDEgPDwgNyApIHJldHVybiAxO1xyXG4gICAgICAgIGVsc2UgaWYgKHZhbHVlIDwgMSA8PCAxNCkgcmV0dXJuIDI7XHJcbiAgICAgICAgZWxzZSBpZiAodmFsdWUgPCAxIDw8IDIxKSByZXR1cm4gMztcclxuICAgICAgICBlbHNlIGlmICh2YWx1ZSA8IDEgPDwgMjgpIHJldHVybiA0O1xyXG4gICAgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogWmlnemFnIGVuY29kZXMgYSBzaWduZWQgMzJiaXQgaW50ZWdlciBzbyB0aGF0IGl0IGNhbiBiZSBlZmZlY3RpdmVseSB1c2VkIHdpdGggdmFyaW50IGVuY29kaW5nLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gU2lnbmVkIDMyYml0IGludGVnZXJcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFVuc2lnbmVkIHppZ3phZyBlbmNvZGVkIDMyYml0IGludGVnZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci56aWdaYWdFbmNvZGUzMiA9IGZ1bmN0aW9uKG4pIHtcclxuICAgICAgICByZXR1cm4gKCgobiB8PSAwKSA8PCAxKSBeIChuID4+IDMxKSkgPj4+IDA7IC8vIHJlZjogc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmhcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGEgemlnemFnIGVuY29kZWQgc2lnbmVkIDMyYml0IGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBVbnNpZ25lZCB6aWd6YWcgZW5jb2RlZCAzMmJpdCBpbnRlZ2VyXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgMzJiaXQgaW50ZWdlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTMyID0gZnVuY3Rpb24obikge1xyXG4gICAgICAgIHJldHVybiAoKG4gPj4+IDEpIF4gLShuICYgMSkpIHwgMDsgLy8gLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaFxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSB0aGlzIGlmIGBvZmZzZXRgIGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVmFyaW50MzIgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHNpemUgPSBCeXRlQnVmZmVyLmNhbGN1bGF0ZVZhcmludDMyKHZhbHVlKSxcclxuICAgICAgICAgICAgYjtcclxuICAgICAgICBvZmZzZXQgKz0gc2l6ZTtcbiAgICAgICAgdmFyIGNhcGFjaXR5MTAgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxMClcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTEwICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxMCA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSBzaXplO1xuICAgICAgICB2YWx1ZSA+Pj49IDA7XHJcbiAgICAgICAgd2hpbGUgKHZhbHVlID49IDB4ODApIHtcclxuICAgICAgICAgICAgYiA9ICh2YWx1ZSAmIDB4N2YpIHwgMHg4MDtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IGI7XHJcbiAgICAgICAgICAgIHZhbHVlID4+Pj0gNztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IHZhbHVlO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzaXplO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIHppZy16YWcgZW5jb2RlZCAoc2lnbmVkKSAzMmJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gdGhpcyBpZiBgb2Zmc2V0YCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVZhcmludDMyWmlnWmFnID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLndyaXRlVmFyaW50MzIoQnl0ZUJ1ZmZlci56aWdaYWdFbmNvZGUzMih2YWx1ZSksIG9mZnNldCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfCF7dmFsdWU6IG51bWJlciwgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgdmFsdWUgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgdmFsdWUgcmVhZFxyXG4gICAgICogIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIGl0J3Mgbm90IGEgdmFsaWQgdmFyaW50LiBIYXMgYSBwcm9wZXJ0eSBgdHJ1bmNhdGVkID0gdHJ1ZWAgaWYgdGhlcmUgaXMgbm90IGVub3VnaCBkYXRhIGF2YWlsYWJsZVxyXG4gICAgICogIHRvIGZ1bGx5IGRlY29kZSB0aGUgdmFyaW50LlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRWYXJpbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDEgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisxK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBjID0gMCxcclxuICAgICAgICAgICAgdmFsdWUgPSAwID4+PiAwLFxyXG4gICAgICAgICAgICBiO1xyXG4gICAgICAgIGRvIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0ICYmIG9mZnNldCA+IHRoaXMubGltaXQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBlcnIgPSBFcnJvcihcIlRydW5jYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIGVyclsndHJ1bmNhdGVkJ10gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdO1xyXG4gICAgICAgICAgICBpZiAoYyA8IDUpXHJcbiAgICAgICAgICAgICAgICB2YWx1ZSB8PSAoYiAmIDB4N2YpIDw8ICg3KmMpO1xyXG4gICAgICAgICAgICArK2M7XHJcbiAgICAgICAgfSB3aGlsZSAoKGIgJiAweDgwKSAhPT0gMCk7XHJcbiAgICAgICAgdmFsdWUgfD0gMDtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgXCJ2YWx1ZVwiOiB2YWx1ZSxcclxuICAgICAgICAgICAgXCJsZW5ndGhcIjogY1xyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSB6aWctemFnIGVuY29kZWQgKHNpZ25lZCkgMzJiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcnwhe3ZhbHVlOiBudW1iZXIsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHZhbHVlIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHZhbHVlIHJlYWRcclxuICAgICAqICBhbmQgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBpdCdzIG5vdCBhIHZhbGlkIHZhcmludFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRWYXJpbnQzMlppZ1phZyA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciB2YWwgPSB0aGlzLnJlYWRWYXJpbnQzMihvZmZzZXQpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnb2JqZWN0JylcclxuICAgICAgICAgICAgdmFsW1widmFsdWVcIl0gPSBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTMyKHZhbFtcInZhbHVlXCJdKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHZhbCA9IEJ5dGVCdWZmZXIuemlnWmFnRGVjb2RlMzIodmFsKTtcclxuICAgICAgICByZXR1cm4gdmFsO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyB0eXBlcy92YXJpbnRzL3ZhcmludDY0XHJcblxyXG4gICAgaWYgKExvbmcpIHtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgYSA2NGJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICAgICAqIEBjb25zdFxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyLk1BWF9WQVJJTlQ2NF9CWVRFUyA9IDEwO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDYWxjdWxhdGVzIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIGEgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IHZhbHVlIFZhbHVlIHRvIGVuY29kZVxyXG4gICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBieXRlcyByZXF1aXJlZC4gQ2FwcGVkIHRvIHtAbGluayBCeXRlQnVmZmVyLk1BWF9WQVJJTlQ2NF9CWVRFU31cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlci5jYWxjdWxhdGVWYXJpbnQ2NCA9IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5jY1xyXG4gICAgICAgICAgICB2YXIgcGFydDAgPSB2YWx1ZS50b0ludCgpID4+PiAwLFxyXG4gICAgICAgICAgICAgICAgcGFydDEgPSB2YWx1ZS5zaGlmdFJpZ2h0VW5zaWduZWQoMjgpLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgICAgICBwYXJ0MiA9IHZhbHVlLnNoaWZ0UmlnaHRVbnNpZ25lZCg1NikudG9JbnQoKSA+Pj4gMDtcclxuICAgICAgICAgICAgaWYgKHBhcnQyID09IDApIHtcclxuICAgICAgICAgICAgICAgIGlmIChwYXJ0MSA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnQwIDwgMSA8PCAxNClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnQwIDwgMSA8PCA3ID8gMSA6IDI7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFydDAgPCAxIDw8IDIxID8gMyA6IDQ7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0MSA8IDEgPDwgMTQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0MSA8IDEgPDwgNyA/IDUgOiA2O1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnQxIDwgMSA8PCAyMSA/IDcgOiA4O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0MiA8IDEgPDwgNyA/IDkgOiAxMDtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBaaWd6YWcgZW5jb2RlcyBhIHNpZ25lZCA2NGJpdCBpbnRlZ2VyIHNvIHRoYXQgaXQgY2FuIGJlIGVmZmVjdGl2ZWx5IHVzZWQgd2l0aCB2YXJpbnQgZW5jb2RpbmcuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IHZhbHVlIFNpZ25lZCBsb25nXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfSBVbnNpZ25lZCB6aWd6YWcgZW5jb2RlZCBsb25nXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXIuemlnWmFnRW5jb2RlNjQgPSBmdW5jdGlvbih2YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUudW5zaWduZWQgIT09IGZhbHNlKSB2YWx1ZSA9IHZhbHVlLnRvU2lnbmVkKCk7XG4gICAgICAgICAgICAvLyByZWY6IHNyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oXHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zaGlmdExlZnQoMSkueG9yKHZhbHVlLnNoaWZ0UmlnaHQoNjMpKS50b1Vuc2lnbmVkKCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVjb2RlcyBhIHppZ3phZyBlbmNvZGVkIHNpZ25lZCA2NGJpdCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfSB2YWx1ZSBVbnNpZ25lZCB6aWd6YWcgZW5jb2RlZCBsb25nIG9yIEphdmFTY3JpcHQgbnVtYmVyXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTY0ID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUsIGZhbHNlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUsIGZhbHNlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLnVuc2lnbmVkICE9PSBmYWxzZSkgdmFsdWUgPSB2YWx1ZS50b1NpZ25lZCgpO1xuICAgICAgICAgICAgLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaFxyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuc2hpZnRSaWdodFVuc2lnbmVkKDEpLnhvcih2YWx1ZS5hbmQoTG9uZy5PTkUpLnRvU2lnbmVkKCkubmVnYXRlKCkpLnRvU2lnbmVkKCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV3JpdGVzIGEgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8TG9uZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IGB0aGlzYCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuLlxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVmFyaW50NjQgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoISh2YWx1ZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIExvbmcpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIgb3IgTG9uZylcIik7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlLCBmYWxzZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlLCBmYWxzZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZS51bnNpZ25lZCAhPT0gZmFsc2UpIHZhbHVlID0gdmFsdWUudG9TaWduZWQoKTtcbiAgICAgICAgICAgIHZhciBzaXplID0gQnl0ZUJ1ZmZlci5jYWxjdWxhdGVWYXJpbnQ2NCh2YWx1ZSksXHJcbiAgICAgICAgICAgICAgICBwYXJ0MCA9IHZhbHVlLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgICAgICBwYXJ0MSA9IHZhbHVlLnNoaWZ0UmlnaHRVbnNpZ25lZCgyOCkudG9JbnQoKSA+Pj4gMCxcclxuICAgICAgICAgICAgICAgIHBhcnQyID0gdmFsdWUuc2hpZnRSaWdodFVuc2lnbmVkKDU2KS50b0ludCgpID4+PiAwO1xyXG4gICAgICAgICAgICBvZmZzZXQgKz0gc2l6ZTtcbiAgICAgICAgICAgIHZhciBjYXBhY2l0eTExID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTExKVxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTExICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxMSA6IG9mZnNldCk7XG4gICAgICAgICAgICBvZmZzZXQgLT0gc2l6ZTtcbiAgICAgICAgICAgIHN3aXRjaCAoc2l6ZSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxMDogdGhpcy52aWV3W29mZnNldCs5XSA9IChwYXJ0MiA+Pj4gIDcpICYgMHgwMTtcclxuICAgICAgICAgICAgICAgIGNhc2UgOSA6IHRoaXMudmlld1tvZmZzZXQrOF0gPSBzaXplICE9PSA5ID8gKHBhcnQyICAgICAgICkgfCAweDgwIDogKHBhcnQyICAgICAgICkgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA4IDogdGhpcy52aWV3W29mZnNldCs3XSA9IHNpemUgIT09IDggPyAocGFydDEgPj4+IDIxKSB8IDB4ODAgOiAocGFydDEgPj4+IDIxKSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDcgOiB0aGlzLnZpZXdbb2Zmc2V0KzZdID0gc2l6ZSAhPT0gNyA/IChwYXJ0MSA+Pj4gMTQpIHwgMHg4MCA6IChwYXJ0MSA+Pj4gMTQpICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgNiA6IHRoaXMudmlld1tvZmZzZXQrNV0gPSBzaXplICE9PSA2ID8gKHBhcnQxID4+PiAgNykgfCAweDgwIDogKHBhcnQxID4+PiAgNykgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1IDogdGhpcy52aWV3W29mZnNldCs0XSA9IHNpemUgIT09IDUgPyAocGFydDEgICAgICAgKSB8IDB4ODAgOiAocGFydDEgICAgICAgKSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQgOiB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gc2l6ZSAhPT0gNCA/IChwYXJ0MCA+Pj4gMjEpIHwgMHg4MCA6IChwYXJ0MCA+Pj4gMjEpICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgMyA6IHRoaXMudmlld1tvZmZzZXQrMl0gPSBzaXplICE9PSAzID8gKHBhcnQwID4+PiAxNCkgfCAweDgwIDogKHBhcnQwID4+PiAxNCkgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyIDogdGhpcy52aWV3W29mZnNldCsxXSA9IHNpemUgIT09IDIgPyAocGFydDAgPj4+ICA3KSB8IDB4ODAgOiAocGFydDAgPj4+ICA3KSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDEgOiB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gc2l6ZSAhPT0gMSA/IChwYXJ0MCAgICAgICApIHwgMHg4MCA6IChwYXJ0MCAgICAgICApICYgMHg3RjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ICs9IHNpemU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzaXplO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV3JpdGVzIGEgemlnLXphZyBlbmNvZGVkIDY0Yml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfExvbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSBgdGhpc2AgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbi5cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVZhcmludDY0WmlnWmFnID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy53cml0ZVZhcmludDY0KEJ5dGVCdWZmZXIuemlnWmFnRW5jb2RlNjQodmFsdWUpLCBvZmZzZXQpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlYWRzIGEgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuIFJlcXVpcmVzIExvbmcuanMuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfCF7dmFsdWU6IExvbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHZhbHVlIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHZhbHVlIHJlYWQgYW5kXHJcbiAgICAgICAgICogIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIGl0J3Mgbm90IGEgdmFsaWQgdmFyaW50XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFZhcmludDY0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDEgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMStcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHJlZjogc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2NcclxuICAgICAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgcGFydDAgPSAwLFxyXG4gICAgICAgICAgICAgICAgcGFydDEgPSAwLFxyXG4gICAgICAgICAgICAgICAgcGFydDIgPSAwLFxyXG4gICAgICAgICAgICAgICAgYiAgPSAwO1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDAgID0gKGIgJiAweDdGKSAgICAgIDsgaWYgKCBiICYgMHg4MCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDAgfD0gKGIgJiAweDdGKSA8PCAgNzsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDAgfD0gKGIgJiAweDdGKSA8PCAxNDsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDAgfD0gKGIgJiAweDdGKSA8PCAyMTsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDEgID0gKGIgJiAweDdGKSAgICAgIDsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDEgfD0gKGIgJiAweDdGKSA8PCAgNzsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDEgfD0gKGIgJiAweDdGKSA8PCAxNDsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDEgfD0gKGIgJiAweDdGKSA8PCAyMTsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDIgID0gKGIgJiAweDdGKSAgICAgIDsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDIgfD0gKGIgJiAweDdGKSA8PCAgNzsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIkJ1ZmZlciBvdmVycnVuXCIpOyB9fX19fX19fX19XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IExvbmcuZnJvbUJpdHMocGFydDAgfCAocGFydDEgPDwgMjgpLCAocGFydDEgPj4+IDQpIHwgKHBhcnQyKSA8PCAyNCwgZmFsc2UpO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAndmFsdWUnOiB2YWx1ZSxcclxuICAgICAgICAgICAgICAgICAgICAnbGVuZ3RoJzogb2Zmc2V0LXN0YXJ0XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSB6aWctemFnIGVuY29kZWQgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuIFJlcXVpcmVzIExvbmcuanMuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfCF7dmFsdWU6IExvbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHZhbHVlIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHZhbHVlIHJlYWQgYW5kXHJcbiAgICAgICAgICogIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIGl0J3Mgbm90IGEgdmFsaWQgdmFyaW50XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFZhcmludDY0WmlnWmFnID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciB2YWwgPSB0aGlzLnJlYWRWYXJpbnQ2NChvZmZzZXQpO1xyXG4gICAgICAgICAgICBpZiAodmFsICYmIHZhbFsndmFsdWUnXSBpbnN0YW5jZW9mIExvbmcpXHJcbiAgICAgICAgICAgICAgICB2YWxbXCJ2YWx1ZVwiXSA9IEJ5dGVCdWZmZXIuemlnWmFnRGVjb2RlNjQodmFsW1widmFsdWVcIl0pO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICB2YWwgPSBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTY0KHZhbCk7XHJcbiAgICAgICAgICAgIHJldHVybiB2YWw7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICB9IC8vIExvbmdcclxuXHJcblxyXG4gICAgLy8gdHlwZXMvc3RyaW5ncy9jc3RyaW5nXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSBOVUxMLXRlcm1pbmF0ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy4gRm9yIHRoaXMgdG8gd29yayB0aGUgc3BlY2lmaWVkIHN0cmluZyBtdXN0IG5vdCBjb250YWluIGFueSBOVUxMXHJcbiAgICAgKiAgY2hhcmFjdGVycyBpdHNlbGYuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgY29udGFpbmVkIGluIGBzdHJgICsgMSBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gdGhpcyBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVDU3RyaW5nID0gZnVuY3Rpb24oc3RyLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgdmFyIGksXHJcbiAgICAgICAgICAgIGsgPSBzdHIubGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgc3RyaW5nXCIpO1xyXG4gICAgICAgICAgICBmb3IgKGk9MDsgaTxrOyArK2kpIHtcclxuICAgICAgICAgICAgICAgIGlmIChzdHIuY2hhckNvZGVBdChpKSA9PT0gMClcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBzdHI6IENvbnRhaW5zIE5VTEwtY2hhcmFjdGVyc1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgLy8gVVRGOCBzdHJpbmdzIGRvIG5vdCBjb250YWluIHplcm8gYnl0ZXMgaW4gYmV0d2VlbiBleGNlcHQgZm9yIHRoZSB6ZXJvIGNoYXJhY3Rlciwgc286XHJcbiAgICAgICAgayA9IHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjgoc3RyaW5nU291cmNlKHN0cikpWzFdO1xyXG4gICAgICAgIG9mZnNldCArPSBrKzE7XG4gICAgICAgIHZhciBjYXBhY2l0eTEyID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MTIpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxMiAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MTIgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gaysxO1xuICAgICAgICB1dGZ4LmVuY29kZVVURjE2dG9VVEY4KHN0cmluZ1NvdXJjZShzdHIpLCBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrK10gPSBiO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IDA7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGs7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSBOVUxMLXRlcm1pbmF0ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy4gRm9yIHRoaXMgdG8gd29yayB0aGUgc3RyaW5nIHJlYWQgbXVzdCBub3QgY29udGFpbiBhbnkgTlVMTCBjaGFyYWN0ZXJzXHJcbiAgICAgKiAgaXRzZWxmLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8IXtzdHJpbmc6IHN0cmluZywgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgc3RyaW5nIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHN0cmluZ1xyXG4gICAgICogIHJlYWQgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZENTdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAxID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMStcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgICAgIHRlbXA7XHJcbiAgICAgICAgLy8gVVRGOCBzdHJpbmdzIGRvIG5vdCBjb250YWluIHplcm8gYnl0ZXMgaW4gYmV0d2VlbiBleGNlcHQgZm9yIHRoZSB6ZXJvIGNoYXJhY3RlciBpdHNlbGYsIHNvOlxyXG4gICAgICAgIHZhciBzZCwgYiA9IC0xO1xyXG4gICAgICAgIHV0ZnguZGVjb2RlVVRGOHRvVVRGMTYoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmIChiID09PSAwKSByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgaWYgKG9mZnNldCA+PSB0aGlzLmxpbWl0KVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IFRydW5jYXRlZCBkYXRhLCBcIitvZmZzZXQrXCIgPCBcIit0aGlzLmxpbWl0KTtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107XHJcbiAgICAgICAgICAgIHJldHVybiBiID09PSAwID8gbnVsbCA6IGI7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpLCBzZCA9IHN0cmluZ0Rlc3RpbmF0aW9uKCksIHRydWUpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHNkKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIFwic3RyaW5nXCI6IHNkKCksXHJcbiAgICAgICAgICAgICAgICBcImxlbmd0aFwiOiBvZmZzZXQgLSBzdGFydFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLy8gdHlwZXMvc3RyaW5ncy9pc3RyaW5nXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSBsZW5ndGggYXMgdWludDMyIHByZWZpeGVkIFVURjggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gYHRoaXNgIGlmIGBvZmZzZXRgIGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3dyaXRlVmFyaW50MzJcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUlTdHJpbmcgPSBmdW5jdGlvbihzdHIsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE5vdCBhIHN0cmluZ1wiKTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzdGFydCA9IG9mZnNldCxcclxuICAgICAgICAgICAgaztcclxuICAgICAgICBrID0gdXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgdGhpcy5ub0Fzc2VydClbMV07XHJcbiAgICAgICAgb2Zmc2V0ICs9IDQraztcbiAgICAgICAgdmFyIGNhcGFjaXR5MTMgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxMylcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTEzICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxMyA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSA0K2s7XG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9IChrID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChrID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChrID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICBrICAgICAgICAgJiAweEZGO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9IChrID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChrID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChrID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICBrICAgICAgICAgJiAweEZGO1xuICAgICAgICB9XG4gICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgIHV0ZnguZW5jb2RlVVRGMTZ0b1VURjgoc3RyaW5nU291cmNlKHN0ciksIGZ1bmN0aW9uKGIpIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IGI7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgICAgICBpZiAob2Zmc2V0ICE9PSBzdGFydCArIDQgKyBrKVxyXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogVHJ1bmNhdGVkIGRhdGEsIFwiK29mZnNldCtcIiA9PSBcIisob2Zmc2V0KzQraykpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvZmZzZXQgLSBzdGFydDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIGxlbmd0aCBhcyB1aW50MzIgcHJlZml4ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfCF7c3RyaW5nOiBzdHJpbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHN0cmluZyByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBzdHJpbmdcclxuICAgICAqICByZWFkIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3JlYWRWYXJpbnQzMlxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJU3RyaW5nID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgNCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzQrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0O1xyXG4gICAgICAgIHZhciBsZW4gPSB0aGlzLnJlYWRVaW50MzIob2Zmc2V0KTtcclxuICAgICAgICB2YXIgc3RyID0gdGhpcy5yZWFkVVRGOFN0cmluZyhsZW4sIEJ5dGVCdWZmZXIuTUVUUklDU19CWVRFUywgb2Zmc2V0ICs9IDQpO1xyXG4gICAgICAgIG9mZnNldCArPSBzdHJbJ2xlbmd0aCddO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHN0clsnc3RyaW5nJ107XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICdzdHJpbmcnOiBzdHJbJ3N0cmluZyddLFxyXG4gICAgICAgICAgICAgICAgJ2xlbmd0aCc6IG9mZnNldCAtIHN0YXJ0XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyB0eXBlcy9zdHJpbmdzL3V0ZjhzdHJpbmdcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldHJpY3MgcmVwcmVzZW50aW5nIG51bWJlciBvZiBVVEY4IGNoYXJhY3RlcnMuIEV2YWx1YXRlcyB0byBgY2AuXHJcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuTUVUUklDU19DSEFSUyA9ICdjJztcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldHJpY3MgcmVwcmVzZW50aW5nIG51bWJlciBvZiBieXRlcy4gRXZhbHVhdGVzIHRvIGBiYC5cclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5NRVRSSUNTX0JZVEVTID0gJ2InO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIFVURjggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gdGhpcyBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVVRGOFN0cmluZyA9IGZ1bmN0aW9uKHN0ciwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGs7XHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0O1xyXG4gICAgICAgIGsgPSB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpKVsxXTtcclxuICAgICAgICBvZmZzZXQgKz0gaztcbiAgICAgICAgdmFyIGNhcGFjaXR5MTQgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxNClcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTE0ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxNCA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSBrO1xuICAgICAgICB1dGZ4LmVuY29kZVVURjE2dG9VVEY4KHN0cmluZ1NvdXJjZShzdHIpLCBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrK10gPSBiO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiBVVEY4IGVuY29kZWQgc3RyaW5nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlVVRGOFN0cmluZ30uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSB0aGlzIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4uXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVTdHJpbmcgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVVRGOFN0cmluZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgdGhlIG51bWJlciBvZiBVVEY4IGNoYXJhY3RlcnMgb2YgYSBzdHJpbmcuIEphdmFTY3JpcHQgaXRzZWxmIHVzZXMgVVRGLTE2LCBzbyB0aGF0IGEgc3RyaW5nJ3NcclxuICAgICAqICBgbGVuZ3RoYCBwcm9wZXJ0eSBkb2VzIG5vdCByZWZsZWN0IGl0cyBhY3R1YWwgVVRGOCBzaXplIGlmIGl0IGNvbnRhaW5zIGNvZGUgcG9pbnRzIGxhcmdlciB0aGFuIDB4RkZGRi5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNhbGN1bGF0ZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIFVURjggY2hhcmFjdGVyc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmNhbGN1bGF0ZVVURjhDaGFycyA9IGZ1bmN0aW9uKHN0cikge1xyXG4gICAgICAgIHJldHVybiB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpKVswXTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBudW1iZXIgb2YgVVRGOCBieXRlcyBvZiBhIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNhbGN1bGF0ZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIFVURjggYnl0ZXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5jYWxjdWxhdGVVVEY4Qnl0ZXMgPSBmdW5jdGlvbihzdHIpIHtcclxuICAgICAgICByZXR1cm4gdXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSlbMV07XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIFVURjggYnl0ZXMgb2YgYSBzdHJpbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIuY2FsY3VsYXRlVVRGOEJ5dGVzfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gY2FsY3VsYXRlXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgVVRGOCBieXRlc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmNhbGN1bGF0ZVN0cmluZyA9IEJ5dGVCdWZmZXIuY2FsY3VsYXRlVVRGOEJ5dGVzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gVVRGOCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgb3IgYnl0ZXMgdG8gcmVhZC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gbWV0cmljcyBNZXRyaWNzIHNwZWNpZnlpbmcgd2hhdCBgbGVuZ3RoYCBpcyBtZWFudCB0byBjb3VudC4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5NRVRSSUNTX0NIQVJTfS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfCF7c3RyaW5nOiBzdHJpbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHN0cmluZyByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBzdHJpbmdcclxuICAgICAqICByZWFkIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVVEY4U3RyaW5nID0gZnVuY3Rpb24obGVuZ3RoLCBtZXRyaWNzLCBvZmZzZXQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIG1ldHJpY3MgPT09ICdudW1iZXInKSB7XHJcbiAgICAgICAgICAgIG9mZnNldCA9IG1ldHJpY3M7XHJcbiAgICAgICAgICAgIG1ldHJpY3MgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAodHlwZW9mIG1ldHJpY3MgPT09ICd1bmRlZmluZWQnKSBtZXRyaWNzID0gQnl0ZUJ1ZmZlci5NRVRSSUNTX0NIQVJTO1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGxlbmd0aCAhPT0gJ251bWJlcicgfHwgbGVuZ3RoICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGxlbmd0aDogXCIrbGVuZ3RoK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBsZW5ndGggfD0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaSA9IDAsXHJcbiAgICAgICAgICAgIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgICAgICBzZDtcclxuICAgICAgICBpZiAobWV0cmljcyA9PT0gQnl0ZUJ1ZmZlci5NRVRSSUNTX0NIQVJTKSB7IC8vIFRoZSBzYW1lIGZvciBub2RlIGFuZCB0aGUgYnJvd3NlclxyXG4gICAgICAgICAgICBzZCA9IHN0cmluZ0Rlc3RpbmF0aW9uKCk7XHJcbiAgICAgICAgICAgIHV0ZnguZGVjb2RlVVRGOChmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpIDwgbGVuZ3RoICYmIG9mZnNldCA8IHRoaXMubGltaXQgPyB0aGlzLnZpZXdbb2Zmc2V0KytdIDogbnVsbDtcclxuICAgICAgICAgICAgfS5iaW5kKHRoaXMpLCBmdW5jdGlvbihjcCkge1xyXG4gICAgICAgICAgICAgICAgKytpOyB1dGZ4LlVURjh0b1VURjE2KGNwLCBzZCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBpZiAoaSAhPT0gbGVuZ3RoKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IFRydW5jYXRlZCBkYXRhLCBcIitpK1wiID09IFwiK2xlbmd0aCk7XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc2QoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgXCJzdHJpbmdcIjogc2QoKSxcclxuICAgICAgICAgICAgICAgICAgICBcImxlbmd0aFwiOiBvZmZzZXQgLSBzdGFydFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAobWV0cmljcyA9PT0gQnl0ZUJ1ZmZlci5NRVRSSUNTX0JZVEVTKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIGxlbmd0aCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIitsZW5ndGgrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgayA9IG9mZnNldCArIGxlbmd0aDtcclxuICAgICAgICAgICAgdXRmeC5kZWNvZGVVVEY4dG9VVEYxNihmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQgPCBrID8gdGhpcy52aWV3W29mZnNldCsrXSA6IG51bGw7XHJcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSwgc2QgPSBzdHJpbmdEZXN0aW5hdGlvbigpLCB0aGlzLm5vQXNzZXJ0KTtcclxuICAgICAgICAgICAgaWYgKG9mZnNldCAhPT0gaylcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiBUcnVuY2F0ZWQgZGF0YSwgXCIrb2Zmc2V0K1wiID09IFwiK2spO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNkKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICdzdHJpbmcnOiBzZCgpLFxyXG4gICAgICAgICAgICAgICAgICAgICdsZW5ndGgnOiBvZmZzZXQgLSBzdGFydFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJVbnN1cHBvcnRlZCBtZXRyaWNzOiBcIittZXRyaWNzKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhbiBVVEY4IGVuY29kZWQgc3RyaW5nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRVVEY4U3RyaW5nfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyBvciBieXRlcyB0byByZWFkXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG1ldHJpY3MgTWV0cmljcyBzcGVjaWZ5aW5nIHdoYXQgYG5gIGlzIG1lYW50IHRvIGNvdW50LiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLk1FVFJJQ1NfQ0hBUlN9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8IXtzdHJpbmc6IHN0cmluZywgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgc3RyaW5nIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHN0cmluZ1xyXG4gICAgICogIHJlYWQgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFN0cmluZyA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVURjhTdHJpbmc7XHJcblxyXG4gICAgLy8gdHlwZXMvc3RyaW5ncy92c3RyaW5nXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSBsZW5ndGggYXMgdmFyaW50MzIgcHJlZml4ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSBgdGhpc2AgaWYgYG9mZnNldGAgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjd3JpdGVWYXJpbnQzMlxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVlN0cmluZyA9IGZ1bmN0aW9uKHN0ciwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgc3RyaW5nXCIpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgICAgICBrLCBsO1xyXG4gICAgICAgIGsgPSB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpLCB0aGlzLm5vQXNzZXJ0KVsxXTtcclxuICAgICAgICBsID0gQnl0ZUJ1ZmZlci5jYWxjdWxhdGVWYXJpbnQzMihrKTtcclxuICAgICAgICBvZmZzZXQgKz0gbCtrO1xuICAgICAgICB2YXIgY2FwYWNpdHkxNSA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTE1KVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MTUgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTE1IDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IGwraztcbiAgICAgICAgb2Zmc2V0ICs9IHRoaXMud3JpdGVWYXJpbnQzMihrLCBvZmZzZXQpO1xyXG4gICAgICAgIHV0ZnguZW5jb2RlVVRGMTZ0b1VURjgoc3RyaW5nU291cmNlKHN0ciksIGZ1bmN0aW9uKGIpIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IGI7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgICAgICBpZiAob2Zmc2V0ICE9PSBzdGFydCtrK2wpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiBUcnVuY2F0ZWQgZGF0YSwgXCIrb2Zmc2V0K1wiID09IFwiKyhvZmZzZXQraytsKSk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgbGVuZ3RoIGFzIHZhcmludDMyIHByZWZpeGVkIFVURjggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcmVhZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ3whe3N0cmluZzogc3RyaW5nLCBsZW5ndGg6IG51bWJlcn19IFRoZSBzdHJpbmcgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgc3RyaW5nXHJcbiAgICAgKiAgcmVhZCBhbmQgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNyZWFkVmFyaW50MzJcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVlN0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDEgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisxK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzdGFydCA9IG9mZnNldDtcclxuICAgICAgICB2YXIgbGVuID0gdGhpcy5yZWFkVmFyaW50MzIob2Zmc2V0KTtcclxuICAgICAgICB2YXIgc3RyID0gdGhpcy5yZWFkVVRGOFN0cmluZyhsZW5bJ3ZhbHVlJ10sIEJ5dGVCdWZmZXIuTUVUUklDU19CWVRFUywgb2Zmc2V0ICs9IGxlblsnbGVuZ3RoJ10pO1xyXG4gICAgICAgIG9mZnNldCArPSBzdHJbJ2xlbmd0aCddO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHN0clsnc3RyaW5nJ107XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICdzdHJpbmcnOiBzdHJbJ3N0cmluZyddLFxyXG4gICAgICAgICAgICAgICAgJ2xlbmd0aCc6IG9mZnNldCAtIHN0YXJ0XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBcHBlbmRzIHNvbWUgZGF0YSB0byB0aGlzIEJ5dGVCdWZmZXIuIFRoaXMgd2lsbCBvdmVyd3JpdGUgYW55IGNvbnRlbnRzIGJlaGluZCB0aGUgc3BlY2lmaWVkIG9mZnNldCB1cCB0byB0aGUgYXBwZW5kZWRcclxuICAgICAqICBkYXRhJ3MgbGVuZ3RoLlxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcnwhQXJyYXlCdWZmZXJ8IVVpbnQ4QXJyYXl8c3RyaW5nfSBzb3VyY2UgRGF0YSB0byBhcHBlbmQuIElmIGBzb3VyY2VgIGlzIGEgQnl0ZUJ1ZmZlciwgaXRzIG9mZnNldHNcclxuICAgICAqICB3aWxsIGJlIG1vZGlmaWVkIGFjY29yZGluZyB0byB0aGUgcGVyZm9ybWVkIHJlYWQgb3BlcmF0aW9uLlxyXG4gICAgICogQHBhcmFtIHsoc3RyaW5nfG51bWJlcik9fSBlbmNvZGluZyBFbmNvZGluZyBpZiBgZGF0YWAgaXMgYSBzdHJpbmcgKFwiYmFzZTY0XCIsIFwiaGV4XCIsIFwiYmluYXJ5XCIsIGRlZmF1bHRzIHRvIFwidXRmOFwiKVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIGFwcGVuZCBhdC4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQGV4YW1wbGUgQSByZWxhdGl2ZSBgPDAxIDAyPjAzLmFwcGVuZCg8MDQgMDU+KWAgd2lsbCByZXN1bHQgaW4gYDwwMSAwMiAwNCAwNT4sIDA0IDA1fGBcclxuICAgICAqIEBleGFtcGxlIEFuIGFic29sdXRlIGA8MDEgMDI+MDMuYXBwZW5kKDA0IDA1PiwgMSlgIHdpbGwgcmVzdWx0IGluIGA8MDEgMDQ+MDUsIDA0IDA1fGBcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbihzb3VyY2UsIGVuY29kaW5nLCBvZmZzZXQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIG9mZnNldCA9IGVuY29kaW5nO1xyXG4gICAgICAgICAgICBlbmNvZGluZyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCEoc291cmNlIGluc3RhbmNlb2YgQnl0ZUJ1ZmZlcikpXHJcbiAgICAgICAgICAgIHNvdXJjZSA9IEJ5dGVCdWZmZXIud3JhcChzb3VyY2UsIGVuY29kaW5nKTtcclxuICAgICAgICB2YXIgbGVuZ3RoID0gc291cmNlLmxpbWl0IC0gc291cmNlLm9mZnNldDtcclxuICAgICAgICBpZiAobGVuZ3RoIDw9IDApIHJldHVybiB0aGlzOyAvLyBOb3RoaW5nIHRvIGFwcGVuZFxyXG4gICAgICAgIG9mZnNldCArPSBsZW5ndGg7XG4gICAgICAgIHZhciBjYXBhY2l0eTE2ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MTYpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxNiAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MTYgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gbGVuZ3RoO1xuICAgICAgICB0aGlzLnZpZXcuc2V0KHNvdXJjZS52aWV3LnN1YmFycmF5KHNvdXJjZS5vZmZzZXQsIHNvdXJjZS5saW1pdCksIG9mZnNldCk7XHJcbiAgICAgICAgc291cmNlLm9mZnNldCArPSBsZW5ndGg7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSBsZW5ndGg7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGVuZHMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMgdG8gYW5vdGhlciBCeXRlQnVmZmVyLiBUaGlzIHdpbGwgb3ZlcndyaXRlIGFueSBjb250ZW50cyBhdCBhbmQgYWZ0ZXIgdGhlXHJcbiAgICAgICAgc3BlY2lmaWVkIG9mZnNldCB1cCB0byB0aGUgbGVuZ3RoIG9mIHRoaXMgQnl0ZUJ1ZmZlcidzIGRhdGEuXHJcbiAgICAgKiBAcGFyYW0geyFCeXRlQnVmZmVyfSB0YXJnZXQgVGFyZ2V0IEJ5dGVCdWZmZXJcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byBhcHBlbmQgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNhcHBlbmRcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5hcHBlbmRUbyA9IGZ1bmN0aW9uKHRhcmdldCwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdGFyZ2V0LmFwcGVuZCh0aGlzLCBvZmZzZXQpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgYXNzZXJ0aW9ucyBvZiBhcmd1bWVudCB0eXBlcyBhbmQgb2Zmc2V0cy4gQXNzZXJ0aW9ucyBhcmUgZW5hYmxlZCBieSBkZWZhdWx0IGJ1dCB5b3UgY2FuIG9wdCB0b1xyXG4gICAgICogIGRpc2FibGUgdGhlbSBpZiB5b3VyIGNvZGUgYWxyZWFkeSBtYWtlcyBzdXJlIHRoYXQgZXZlcnl0aGluZyBpcyB2YWxpZC5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYXNzZXJ0IGB0cnVlYCB0byBlbmFibGUgYXNzZXJ0aW9ucywgb3RoZXJ3aXNlIGBmYWxzZWBcclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmFzc2VydCA9IGZ1bmN0aW9uKGFzc2VydCkge1xyXG4gICAgICAgIHRoaXMubm9Bc3NlcnQgPSAhYXNzZXJ0O1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGNhcGFjaXR5IG9mIHRoaXMgQnl0ZUJ1ZmZlcidzIGJhY2tpbmcgYnVmZmVyLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gQ2FwYWNpdHkgb2YgdGhlIGJhY2tpbmcgYnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuY2FwYWNpdHkgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIENsZWFycyB0aGlzIEJ5dGVCdWZmZXIncyBvZmZzZXRzIGJ5IHNldHRpbmcge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSB0byBgMGAgYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fSB0byB0aGVcclxuICAgICAqICBiYWNraW5nIGJ1ZmZlcidzIGNhcGFjaXR5LiBEaXNjYXJkcyB7QGxpbmsgQnl0ZUJ1ZmZlciNtYXJrZWRPZmZzZXR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB0aGlzLm9mZnNldCA9IDA7XHJcbiAgICAgICAgdGhpcy5saW1pdCA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgdGhpcy5tYXJrZWRPZmZzZXQgPSAtMTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmVkIGluc3RhbmNlIG9mIHRoaXMgQnl0ZUJ1ZmZlciwgcHJlc2V0IHdpdGggdGhpcyBCeXRlQnVmZmVyJ3MgdmFsdWVzIGZvciB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LFxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI21hcmtlZE9mZnNldH0gYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGNvcHkgV2hldGhlciB0byBjb3B5IHRoZSBiYWNraW5nIGJ1ZmZlciBvciB0byByZXR1cm4gYW5vdGhlciB2aWV3IG9uIHRoZSBzYW1lLCBkZWZhdWx0cyB0byBgZmFsc2VgXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IENsb25lZCBpbnN0YW5jZVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oY29weSkge1xyXG4gICAgICAgIHZhciBiYiA9IG5ldyBCeXRlQnVmZmVyKDAsIHRoaXMubGl0dGxlRW5kaWFuLCB0aGlzLm5vQXNzZXJ0KTtcclxuICAgICAgICBpZiAoY29weSkge1xyXG4gICAgICAgICAgICBiYi5idWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgICAgIGJiLnZpZXcgPSBuZXcgVWludDhBcnJheShiYi5idWZmZXIpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGJiLmJ1ZmZlciA9IHRoaXMuYnVmZmVyO1xyXG4gICAgICAgICAgICBiYi52aWV3ID0gdGhpcy52aWV3O1xyXG4gICAgICAgIH1cclxuICAgICAgICBiYi5vZmZzZXQgPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBiYi5tYXJrZWRPZmZzZXQgPSB0aGlzLm1hcmtlZE9mZnNldDtcclxuICAgICAgICBiYi5saW1pdCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbXBhY3RzIHRoaXMgQnl0ZUJ1ZmZlciB0byBiZSBiYWNrZWQgYnkgYSB7QGxpbmsgQnl0ZUJ1ZmZlciNidWZmZXJ9IG9mIGl0cyBjb250ZW50cycgbGVuZ3RoLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzXHJcbiAgICAgKiAgYmV0d2VlbiB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uIFdpbGwgc2V0IGBvZmZzZXQgPSAwYCBhbmQgYGxpbWl0ID0gY2FwYWNpdHlgIGFuZFxyXG4gICAgICogIGFkYXB0IHtAbGluayBCeXRlQnVmZmVyI21hcmtlZE9mZnNldH0gdG8gdGhlIHNhbWUgcmVsYXRpdmUgcG9zaXRpb24gaWYgc2V0LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gc3RhcnQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH1cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fVxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuY29tcGFjdCA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJykgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmVnaW4gIT09ICdudW1iZXInIHx8IGJlZ2luICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJlZ2luOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGJlZ2luID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kICE9PSAnbnVtYmVyJyB8fCBlbmQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgZW5kOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGVuZCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGJlZ2luID4gZW5kIHx8IGVuZCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrYmVnaW4rXCIgPD0gXCIrZW5kK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJlZ2luID09PSAwICYmIGVuZCA9PT0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7IC8vIEFscmVhZHkgY29tcGFjdGVkXHJcbiAgICAgICAgdmFyIGxlbiA9IGVuZCAtIGJlZ2luO1xyXG4gICAgICAgIGlmIChsZW4gPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBFTVBUWV9CVUZGRVI7XHJcbiAgICAgICAgICAgIHRoaXMudmlldyA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1hcmtlZE9mZnNldCA+PSAwKSB0aGlzLm1hcmtlZE9mZnNldCAtPSBiZWdpbjtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICB0aGlzLmxpbWl0ID0gMDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIobGVuKTtcclxuICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgdmlldy5zZXQodGhpcy52aWV3LnN1YmFycmF5KGJlZ2luLCBlbmQpKTtcclxuICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcclxuICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xyXG4gICAgICAgIGlmICh0aGlzLm1hcmtlZE9mZnNldCA+PSAwKSB0aGlzLm1hcmtlZE9mZnNldCAtPSBiZWdpbjtcclxuICAgICAgICB0aGlzLm9mZnNldCA9IDA7XHJcbiAgICAgICAgdGhpcy5saW1pdCA9IGxlbjtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cy4gQ29udGVudHMgYXJlIHRoZSBieXRlcyBiZXR3ZWVuIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBCZWdpbiBvZmZzZXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBFbmQgb2Zmc2V0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IENvcHlcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKSBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYmVnaW4gPT09IGVuZClcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBCeXRlQnVmZmVyKDAsIHRoaXMubGl0dGxlRW5kaWFuLCB0aGlzLm5vQXNzZXJ0KTtcclxuICAgICAgICB2YXIgY2FwYWNpdHkgPSBlbmQgLSBiZWdpbixcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcihjYXBhY2l0eSwgdGhpcy5saXR0bGVFbmRpYW4sIHRoaXMubm9Bc3NlcnQpO1xyXG4gICAgICAgIGJiLm9mZnNldCA9IDA7XHJcbiAgICAgICAgYmIubGltaXQgPSBjYXBhY2l0eTtcclxuICAgICAgICBpZiAoYmIubWFya2VkT2Zmc2V0ID49IDApIGJiLm1hcmtlZE9mZnNldCAtPSBiZWdpbjtcclxuICAgICAgICB0aGlzLmNvcHlUbyhiYiwgMCwgYmVnaW4sIGVuZCk7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvcGllcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cyB0byBhbm90aGVyIEJ5dGVCdWZmZXIuIENvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYmV0d2VlbiB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZFxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEBwYXJhbSB7IUJ5dGVCdWZmZXJ9IHRhcmdldCBUYXJnZXQgQnl0ZUJ1ZmZlclxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSB0YXJnZXRPZmZzZXQgT2Zmc2V0IHRvIGNvcHkgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB0aGUgdGFyZ2V0J3Mge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fVxyXG4gICAgICogIGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXMgY29waWVkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IHNvdXJjZU9mZnNldCBPZmZzZXQgdG8gc3RhcnQgY29weWluZyBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGVcclxuICAgICAqICBudW1iZXIgb2YgYnl0ZXMgY29waWVkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IHNvdXJjZUxpbWl0IE9mZnNldCB0byBlbmQgY29weWluZyBmcm9tLCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH1cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmNvcHlUbyA9IGZ1bmN0aW9uKHRhcmdldCwgdGFyZ2V0T2Zmc2V0LCBzb3VyY2VPZmZzZXQsIHNvdXJjZUxpbWl0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlLFxyXG4gICAgICAgICAgICB0YXJnZXRSZWxhdGl2ZTtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKCFCeXRlQnVmZmVyLmlzQnl0ZUJ1ZmZlcih0YXJnZXQpKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB0YXJnZXQ6IE5vdCBhIEJ5dGVCdWZmZXJcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRhcmdldE9mZnNldCA9ICh0YXJnZXRSZWxhdGl2ZSA9IHR5cGVvZiB0YXJnZXRPZmZzZXQgPT09ICd1bmRlZmluZWQnKSA/IHRhcmdldC5vZmZzZXQgOiB0YXJnZXRPZmZzZXQgfCAwO1xyXG4gICAgICAgIHNvdXJjZU9mZnNldCA9IChyZWxhdGl2ZSA9IHR5cGVvZiBzb3VyY2VPZmZzZXQgPT09ICd1bmRlZmluZWQnKSA/IHRoaXMub2Zmc2V0IDogc291cmNlT2Zmc2V0IHwgMDtcclxuICAgICAgICBzb3VyY2VMaW1pdCA9IHR5cGVvZiBzb3VyY2VMaW1pdCA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLmxpbWl0IDogc291cmNlTGltaXQgfCAwO1xyXG5cclxuICAgICAgICBpZiAodGFyZ2V0T2Zmc2V0IDwgMCB8fCB0YXJnZXRPZmZzZXQgPiB0YXJnZXQuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHRhcmdldCByYW5nZTogMCA8PSBcIit0YXJnZXRPZmZzZXQrXCIgPD0gXCIrdGFyZ2V0LmJ1ZmZlci5ieXRlTGVuZ3RoKTtcclxuICAgICAgICBpZiAoc291cmNlT2Zmc2V0IDwgMCB8fCBzb3VyY2VMaW1pdCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHNvdXJjZSByYW5nZTogMCA8PSBcIitzb3VyY2VPZmZzZXQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XHJcblxyXG4gICAgICAgIHZhciBsZW4gPSBzb3VyY2VMaW1pdCAtIHNvdXJjZU9mZnNldDtcclxuICAgICAgICBpZiAobGVuID09PSAwKVxyXG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0OyAvLyBOb3RoaW5nIHRvIGNvcHlcclxuXHJcbiAgICAgICAgdGFyZ2V0LmVuc3VyZUNhcGFjaXR5KHRhcmdldE9mZnNldCArIGxlbik7XHJcblxyXG4gICAgICAgIHRhcmdldC52aWV3LnNldCh0aGlzLnZpZXcuc3ViYXJyYXkoc291cmNlT2Zmc2V0LCBzb3VyY2VMaW1pdCksIHRhcmdldE9mZnNldCk7XHJcblxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gbGVuO1xyXG4gICAgICAgIGlmICh0YXJnZXRSZWxhdGl2ZSkgdGFyZ2V0Lm9mZnNldCArPSBsZW47XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ha2VzIHN1cmUgdGhhdCB0aGlzIEJ5dGVCdWZmZXIgaXMgYmFja2VkIGJ5IGEge0BsaW5rIEJ5dGVCdWZmZXIjYnVmZmVyfSBvZiBhdCBsZWFzdCB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5LiBJZiB0aGVcclxuICAgICAqICBjdXJyZW50IGNhcGFjaXR5IGlzIGV4Y2VlZGVkLCBpdCB3aWxsIGJlIGRvdWJsZWQuIElmIGRvdWJsZSB0aGUgY3VycmVudCBjYXBhY2l0eSBpcyBsZXNzIHRoYW4gdGhlIHJlcXVpcmVkIGNhcGFjaXR5LFxyXG4gICAgICogIHRoZSByZXF1aXJlZCBjYXBhY2l0eSB3aWxsIGJlIHVzZWQgaW5zdGVhZC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjYXBhY2l0eSBSZXF1aXJlZCBjYXBhY2l0eVxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuZW5zdXJlQ2FwYWNpdHkgPSBmdW5jdGlvbihjYXBhY2l0eSkge1xyXG4gICAgICAgIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgICAgICBpZiAoY3VycmVudCA8IGNhcGFjaXR5KVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZXNpemUoKGN1cnJlbnQgKj0gMikgPiBjYXBhY2l0eSA/IGN1cnJlbnQgOiBjYXBhY2l0eSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogT3ZlcndyaXRlcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cyB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWUuIENvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYmV0d2VlblxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gdmFsdWUgQnl0ZSB2YWx1ZSB0byBmaWxsIHdpdGguIElmIGdpdmVuIGFzIGEgc3RyaW5nLCB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIHVzZWQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIEJlZ2luIG9mZnNldC4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC4gZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIEVuZCBvZmZzZXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQGV4YW1wbGUgYHNvbWVCeXRlQnVmZmVyLmNsZWFyKCkuZmlsbCgwKWAgZmlsbHMgdGhlIGVudGlyZSBiYWNraW5nIGJ1ZmZlciB3aXRoIHplcm9lc1xyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbih2YWx1ZSwgYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgYmVnaW4gPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUubGVuZ3RoID4gMClcclxuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5jaGFyQ29kZUF0KDApO1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKSBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSB8PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYmVnaW4gPj0gZW5kKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpczsgLy8gTm90aGluZyB0byBmaWxsXHJcbiAgICAgICAgd2hpbGUgKGJlZ2luIDwgZW5kKSB0aGlzLnZpZXdbYmVnaW4rK10gPSB2YWx1ZTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ID0gYmVnaW47XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFrZXMgdGhpcyBCeXRlQnVmZmVyIHJlYWR5IGZvciBhIG5ldyBzZXF1ZW5jZSBvZiB3cml0ZSBvciByZWxhdGl2ZSByZWFkIG9wZXJhdGlvbnMuIFNldHMgYGxpbWl0ID0gb2Zmc2V0YCBhbmRcclxuICAgICAqICBgb2Zmc2V0ID0gMGAuIE1ha2Ugc3VyZSBhbHdheXMgdG8gZmxpcCBhIEJ5dGVCdWZmZXIgd2hlbiBhbGwgcmVsYXRpdmUgcmVhZCBvciB3cml0ZSBvcGVyYXRpb25zIGFyZSBjb21wbGV0ZS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmZsaXAgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB0aGlzLmxpbWl0ID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogTWFya3MgYW4gb2Zmc2V0IG9uIHRoaXMgQnl0ZUJ1ZmZlciB0byBiZSB1c2VkIGxhdGVyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIG1hcmsuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjcmVzZXRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5tYXJrID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgb2Zmc2V0ID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLm9mZnNldCA6IG9mZnNldDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubWFya2VkT2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgYnl0ZSBvcmRlci5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gbGl0dGxlRW5kaWFuIGB0cnVlYCBmb3IgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLCBgZmFsc2VgIGZvciBiaWcgZW5kaWFuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5vcmRlciA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGxpdHRsZUVuZGlhbiAhPT0gJ2Jvb2xlYW4nKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBsaXR0bGVFbmRpYW46IE5vdCBhIGJvb2xlYW5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubGl0dGxlRW5kaWFuID0gISFsaXR0bGVFbmRpYW47XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3dpdGNoZXMgKHRvKSBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gRGVmYXVsdHMgdG8gYHRydWVgLCBvdGhlcndpc2UgdXNlcyBiaWcgZW5kaWFuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5MRSA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgIHRoaXMubGl0dGxlRW5kaWFuID0gdHlwZW9mIGxpdHRsZUVuZGlhbiAhPT0gJ3VuZGVmaW5lZCcgPyAhIWxpdHRsZUVuZGlhbiA6IHRydWU7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3dpdGNoZXMgKHRvKSBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBiaWdFbmRpYW4gRGVmYXVsdHMgdG8gYHRydWVgLCBvdGhlcndpc2UgdXNlcyBsaXR0bGUgZW5kaWFuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5CRSA9IGZ1bmN0aW9uKGJpZ0VuZGlhbikge1xyXG4gICAgICAgIHRoaXMubGl0dGxlRW5kaWFuID0gdHlwZW9mIGJpZ0VuZGlhbiAhPT0gJ3VuZGVmaW5lZCcgPyAhYmlnRW5kaWFuIDogZmFsc2U7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBQcmVwZW5kcyBzb21lIGRhdGEgdG8gdGhpcyBCeXRlQnVmZmVyLiBUaGlzIHdpbGwgb3ZlcndyaXRlIGFueSBjb250ZW50cyBiZWZvcmUgdGhlIHNwZWNpZmllZCBvZmZzZXQgdXAgdG8gdGhlXHJcbiAgICAgKiAgcHJlcGVuZGVkIGRhdGEncyBsZW5ndGguIElmIHRoZXJlIGlzIG5vdCBlbm91Z2ggc3BhY2UgYXZhaWxhYmxlIGJlZm9yZSB0aGUgc3BlY2lmaWVkIGBvZmZzZXRgLCB0aGUgYmFja2luZyBidWZmZXJcclxuICAgICAqICB3aWxsIGJlIHJlc2l6ZWQgYW5kIGl0cyBjb250ZW50cyBtb3ZlZCBhY2NvcmRpbmdseS5cclxuICAgICAqIEBwYXJhbSB7IUJ5dGVCdWZmZXJ8c3RyaW5nfCFBcnJheUJ1ZmZlcn0gc291cmNlIERhdGEgdG8gcHJlcGVuZC4gSWYgYHNvdXJjZWAgaXMgYSBCeXRlQnVmZmVyLCBpdHMgb2Zmc2V0IHdpbGwgYmVcclxuICAgICAqICBtb2RpZmllZCBhY2NvcmRpbmcgdG8gdGhlIHBlcmZvcm1lZCByZWFkIG9wZXJhdGlvbi5cclxuICAgICAqIEBwYXJhbSB7KHN0cmluZ3xudW1iZXIpPX0gZW5jb2RpbmcgRW5jb2RpbmcgaWYgYGRhdGFgIGlzIGEgc3RyaW5nIChcImJhc2U2NFwiLCBcImhleFwiLCBcImJpbmFyeVwiLCBkZWZhdWx0cyB0byBcInV0ZjhcIilcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byBwcmVwZW5kIGF0LiBXaWxsIHVzZSBhbmQgZGVjcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcHJlcGVuZGVkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBleGFtcGxlIEEgcmVsYXRpdmUgYDAwPDAxIDAyIDAzPi5wcmVwZW5kKDwwNCAwNT4pYCByZXN1bHRzIGluIGA8MDQgMDUgMDEgMDIgMDM+LCAwNCAwNXxgXHJcbiAgICAgKiBAZXhhbXBsZSBBbiBhYnNvbHV0ZSBgMDA8MDEgMDIgMDM+LnByZXBlbmQoPDA0IDA1PiwgMilgIHJlc3VsdHMgaW4gYDA0PDA1IDAyIDAzPiwgMDQgMDV8YFxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnByZXBlbmQgPSBmdW5jdGlvbihzb3VyY2UsIGVuY29kaW5nLCBvZmZzZXQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIG9mZnNldCA9IGVuY29kaW5nO1xyXG4gICAgICAgICAgICBlbmNvZGluZyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCEoc291cmNlIGluc3RhbmNlb2YgQnl0ZUJ1ZmZlcikpXHJcbiAgICAgICAgICAgIHNvdXJjZSA9IEJ5dGVCdWZmZXIud3JhcChzb3VyY2UsIGVuY29kaW5nKTtcclxuICAgICAgICB2YXIgbGVuID0gc291cmNlLmxpbWl0IC0gc291cmNlLm9mZnNldDtcclxuICAgICAgICBpZiAobGVuIDw9IDApIHJldHVybiB0aGlzOyAvLyBOb3RoaW5nIHRvIHByZXBlbmRcclxuICAgICAgICB2YXIgZGlmZiA9IGxlbiAtIG9mZnNldDtcclxuICAgICAgICBpZiAoZGlmZiA+IDApIHsgLy8gTm90IGVub3VnaCBzcGFjZSBiZWZvcmUgb2Zmc2V0LCBzbyByZXNpemUgKyBtb3ZlXHJcbiAgICAgICAgICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy5idWZmZXIuYnl0ZUxlbmd0aCArIGRpZmYpO1xyXG4gICAgICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgICAgIHZpZXcuc2V0KHRoaXMudmlldy5zdWJhcnJheShvZmZzZXQsIHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpLCBsZW4pO1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcclxuICAgICAgICAgICAgdGhpcy52aWV3ID0gdmlldztcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgKz0gZGlmZjtcclxuICAgICAgICAgICAgaWYgKHRoaXMubWFya2VkT2Zmc2V0ID49IDApIHRoaXMubWFya2VkT2Zmc2V0ICs9IGRpZmY7XHJcbiAgICAgICAgICAgIHRoaXMubGltaXQgKz0gZGlmZjtcclxuICAgICAgICAgICAgb2Zmc2V0ICs9IGRpZmY7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdmFyIGFycmF5VmlldyA9IG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52aWV3LnNldChzb3VyY2Uudmlldy5zdWJhcnJheShzb3VyY2Uub2Zmc2V0LCBzb3VyY2UubGltaXQpLCBvZmZzZXQgLSBsZW4pO1xyXG5cclxuICAgICAgICBzb3VyY2Uub2Zmc2V0ID0gc291cmNlLmxpbWl0O1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSlcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgLT0gbGVuO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFByZXBlbmRzIHRoaXMgQnl0ZUJ1ZmZlciB0byBhbm90aGVyIEJ5dGVCdWZmZXIuIFRoaXMgd2lsbCBvdmVyd3JpdGUgYW55IGNvbnRlbnRzIGJlZm9yZSB0aGUgc3BlY2lmaWVkIG9mZnNldCB1cCB0byB0aGVcclxuICAgICAqICBwcmVwZW5kZWQgZGF0YSdzIGxlbmd0aC4gSWYgdGhlcmUgaXMgbm90IGVub3VnaCBzcGFjZSBhdmFpbGFibGUgYmVmb3JlIHRoZSBzcGVjaWZpZWQgYG9mZnNldGAsIHRoZSBiYWNraW5nIGJ1ZmZlclxyXG4gICAgICogIHdpbGwgYmUgcmVzaXplZCBhbmQgaXRzIGNvbnRlbnRzIG1vdmVkIGFjY29yZGluZ2x5LlxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcn0gdGFyZ2V0IFRhcmdldCBCeXRlQnVmZmVyXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcHJlcGVuZCBhdC4gV2lsbCB1c2UgYW5kIGRlY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHByZXBlbmRlZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjcHJlcGVuZFxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnByZXBlbmRUbyA9IGZ1bmN0aW9uKHRhcmdldCwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdGFyZ2V0LnByZXBlbmQodGhpcywgb2Zmc2V0KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFByaW50cyBkZWJ1ZyBpbmZvcm1hdGlvbiBhYm91dCB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cy5cclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oc3RyaW5nKT19IG91dCBPdXRwdXQgZnVuY3Rpb24gdG8gY2FsbCwgZGVmYXVsdHMgdG8gY29uc29sZS5sb2dcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5wcmludERlYnVnID0gZnVuY3Rpb24ob3V0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBvdXQgIT09ICdmdW5jdGlvbicpIG91dCA9IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSk7XHJcbiAgICAgICAgb3V0KFxyXG4gICAgICAgICAgICB0aGlzLnRvU3RyaW5nKCkrXCJcXG5cIitcclxuICAgICAgICAgICAgXCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXFxuXCIrXHJcbiAgICAgICAgICAgIHRoaXMudG9EZWJ1ZygvKiBjb2x1bW5zICovIHRydWUpXHJcbiAgICAgICAgKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgcmVtYWluaW5nIHJlYWRhYmxlIGJ5dGVzLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzIGJldHdlZW4ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmRcclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0sIHNvIHRoaXMgcmV0dXJucyBgbGltaXQgLSBvZmZzZXRgLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmVtYWluaW5nIHJlYWRhYmxlIGJ5dGVzLiBNYXkgYmUgbmVnYXRpdmUgaWYgYG9mZnNldCA+IGxpbWl0YC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZW1haW5pbmcgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5saW1pdCAtIHRoaXMub2Zmc2V0O1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVzZXRzIHRoaXMgQnl0ZUJ1ZmZlcidzIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uIElmIGFuIG9mZnNldCBoYXMgYmVlbiBtYXJrZWQgdGhyb3VnaCB7QGxpbmsgQnl0ZUJ1ZmZlciNtYXJrfVxyXG4gICAgICogIGJlZm9yZSwgYG9mZnNldGAgd2lsbCBiZSBzZXQgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbWFya2VkT2Zmc2V0fSwgd2hpY2ggd2lsbCB0aGVuIGJlIGRpc2NhcmRlZC4gSWYgbm8gb2Zmc2V0IGhhcyBiZWVuXHJcbiAgICAgKiAgbWFya2VkLCBzZXRzIGBvZmZzZXQgPSAwYC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI21hcmtcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIGlmICh0aGlzLm1hcmtlZE9mZnNldCA+PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gdGhpcy5tYXJrZWRPZmZzZXQ7XHJcbiAgICAgICAgICAgIHRoaXMubWFya2VkT2Zmc2V0ID0gLTE7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJlc2l6ZXMgdGhpcyBCeXRlQnVmZmVyIHRvIGJlIGJhY2tlZCBieSBhIGJ1ZmZlciBvZiBhdCBsZWFzdCB0aGUgZ2l2ZW4gY2FwYWNpdHkuIFdpbGwgZG8gbm90aGluZyBpZiBhbHJlYWR5IHRoYXRcclxuICAgICAqICBsYXJnZSBvciBsYXJnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2FwYWNpdHkgQ2FwYWNpdHkgcmVxdWlyZWRcclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgY2FwYWNpdHlgIGlzIG5vdCBhIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYGNhcGFjaXR5IDwgMGBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbihjYXBhY2l0eSkge1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGNhcGFjaXR5ICE9PSAnbnVtYmVyJyB8fCBjYXBhY2l0eSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBjYXBhY2l0eTogXCIrY2FwYWNpdHkrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIGNhcGFjaXR5IHw9IDA7XG4gICAgICAgICAgICBpZiAoY2FwYWNpdHkgPCAwKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgY2FwYWNpdHk6IDAgPD0gXCIrY2FwYWNpdHkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5idWZmZXIuYnl0ZUxlbmd0aCA8IGNhcGFjaXR5KSB7XHJcbiAgICAgICAgICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoY2FwYWNpdHkpO1xyXG4gICAgICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgICAgIHZpZXcuc2V0KHRoaXMudmlldyk7XHJcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyO1xyXG4gICAgICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldmVyc2VzIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gc3RhcnQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH1cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fVxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmV2ZXJzZSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJykgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmVnaW4gIT09ICdudW1iZXInIHx8IGJlZ2luICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJlZ2luOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGJlZ2luID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kICE9PSAnbnVtYmVyJyB8fCBlbmQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgZW5kOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGVuZCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGJlZ2luID4gZW5kIHx8IGVuZCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrYmVnaW4rXCIgPD0gXCIrZW5kK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJlZ2luID09PSBlbmQpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzOyAvLyBOb3RoaW5nIHRvIHJldmVyc2VcclxuICAgICAgICBBcnJheS5wcm90b3R5cGUucmV2ZXJzZS5jYWxsKHRoaXMudmlldy5zdWJhcnJheShiZWdpbiwgZW5kKSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTa2lwcyB0aGUgbmV4dCBgbGVuZ3RoYCBieXRlcy4gVGhpcyB3aWxsIGp1c3QgYWR2YW5jZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgYnl0ZXMgdG8gc2tpcC4gTWF5IGFsc28gYmUgbmVnYXRpdmUgdG8gbW92ZSB0aGUgb2Zmc2V0IGJhY2suXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5za2lwID0gZnVuY3Rpb24obGVuZ3RoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBsZW5ndGggJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgbGVuZ3RoOiBcIitsZW5ndGgrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIGxlbmd0aCB8PSAwO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMub2Zmc2V0ICsgbGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgbGVuZ3RoOiAwIDw9IFwiK3RoaXMub2Zmc2V0K1wiICsgXCIrbGVuZ3RoK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTbGljZXMgdGhpcyBCeXRlQnVmZmVyIGJ5IGNyZWF0aW5nIGEgY2xvbmVkIGluc3RhbmNlIHdpdGggYG9mZnNldCA9IGJlZ2luYCBhbmQgYGxpbWl0ID0gZW5kYC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gQmVnaW4gb2Zmc2V0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgRW5kIG9mZnNldCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBDbG9uZSBvZiB0aGlzIEJ5dGVCdWZmZXIgd2l0aCBzbGljaW5nIGFwcGxpZWQsIGJhY2tlZCBieSB0aGUgc2FtZSB7QGxpbmsgQnl0ZUJ1ZmZlciNidWZmZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKSBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGJlZ2luICE9PSAnbnVtYmVyJyB8fCBiZWdpbiAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBiZWdpbjogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBiZWdpbiA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuZCAhPT0gJ251bWJlcicgfHwgZW5kICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGVuZDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBlbmQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBiZWdpbiA+IGVuZCB8fCBlbmQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK2JlZ2luK1wiIDw9IFwiK2VuZCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBiYiA9IHRoaXMuY2xvbmUoKTtcclxuICAgICAgICBiYi5vZmZzZXQgPSBiZWdpbjtcclxuICAgICAgICBiYi5saW1pdCA9IGVuZDtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgYmFja2luZyBidWZmZXIgdGhhdCBjb250YWlucyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cy4gQ29udGVudHMgYXJlIHRoZSBieXRlcyBiZXR3ZWVuXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmQge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gZm9yY2VDb3B5IElmIGB0cnVlYCByZXR1cm5zIGEgY29weSwgb3RoZXJ3aXNlIHJldHVybnMgYSB2aWV3IHJlZmVyZW5jaW5nIHRoZSBzYW1lIG1lbW9yeSBpZlxyXG4gICAgICogIHBvc3NpYmxlLiBEZWZhdWx0cyB0byBgZmFsc2VgXHJcbiAgICAgKiBAcmV0dXJucyB7IUFycmF5QnVmZmVyfSBDb250ZW50cyBhcyBhbiBBcnJheUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24oZm9yY2VDb3B5KSB7XHJcbiAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMub2Zmc2V0LFxyXG4gICAgICAgICAgICBsaW1pdCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGxpbWl0ICE9PSAnbnVtYmVyJyB8fCBsaW1pdCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBsaW1pdDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBsaW1pdCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBsaW1pdCB8fCBsaW1pdCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrb2Zmc2V0K1wiIDw9IFwiK2xpbWl0K1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgLy8gTk9URTogSXQncyBub3QgcG9zc2libGUgdG8gaGF2ZSBhbm90aGVyIEFycmF5QnVmZmVyIHJlZmVyZW5jZSB0aGUgc2FtZSBtZW1vcnkgYXMgdGhlIGJhY2tpbmcgYnVmZmVyLiBUaGlzIGlzXHJcbiAgICAgICAgLy8gcG9zc2libGUgd2l0aCBVaW50OEFycmF5I3N1YmFycmF5IG9ubHksIGJ1dCB3ZSBoYXZlIHRvIHJldHVybiBhbiBBcnJheUJ1ZmZlciBieSBjb250cmFjdC4gU286XHJcbiAgICAgICAgaWYgKCFmb3JjZUNvcHkgJiYgb2Zmc2V0ID09PSAwICYmIGxpbWl0ID09PSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5idWZmZXI7XHJcbiAgICAgICAgaWYgKG9mZnNldCA9PT0gbGltaXQpXHJcbiAgICAgICAgICAgIHJldHVybiBFTVBUWV9CVUZGRVI7XHJcbiAgICAgICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihsaW1pdCAtIG9mZnNldCk7XHJcbiAgICAgICAgbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKS5zZXQobmV3IFVpbnQ4QXJyYXkodGhpcy5idWZmZXIpLnN1YmFycmF5KG9mZnNldCwgbGltaXQpLCAwKTtcclxuICAgICAgICByZXR1cm4gYnVmZmVyO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSByYXcgYnVmZmVyIGNvbXBhY3RlZCB0byBjb250YWluIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzIGJldHdlZW5cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjdG9CdWZmZXJ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBmb3JjZUNvcHkgSWYgYHRydWVgIHJldHVybnMgYSBjb3B5LCBvdGhlcndpc2UgcmV0dXJucyBhIHZpZXcgcmVmZXJlbmNpbmcgdGhlIHNhbWUgbWVtb3J5LlxyXG4gICAgICogIERlZmF1bHRzIHRvIGBmYWxzZWBcclxuICAgICAqIEByZXR1cm5zIHshQXJyYXlCdWZmZXJ9IENvbnRlbnRzIGFzIGFuIEFycmF5QnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9BcnJheUJ1ZmZlciA9IEJ5dGVCdWZmZXJQcm90b3R5cGUudG9CdWZmZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyB0aGUgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzIHRvIGEgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmc9fSBlbmNvZGluZyBPdXRwdXQgZW5jb2RpbmcuIFJldHVybnMgYW4gaW5mb3JtYXRpdmUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlmIG9taXR0ZWQgYnV0IGFsc28gYWxsb3dzXHJcbiAgICAgKiAgZGlyZWN0IGNvbnZlcnNpb24gdG8gXCJ1dGY4XCIsIFwiaGV4XCIsIFwiYmFzZTY0XCIgYW5kIFwiYmluYXJ5XCIgZW5jb2RpbmcuIFwiZGVidWdcIiByZXR1cm5zIGEgaGV4IHJlcHJlc2VudGF0aW9uIHdpdGhcclxuICAgICAqICBoaWdobGlnaHRlZCBvZmZzZXRzLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gYmVnaW4gYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH1cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fVxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gU3RyaW5nIHJlcHJlc2VudGF0aW9uXHJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgYGVuY29kaW5nYCBpcyBpbnZhbGlkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihlbmNvZGluZywgYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICByZXR1cm4gXCJCeXRlQnVmZmVyQUIob2Zmc2V0PVwiK3RoaXMub2Zmc2V0K1wiLG1hcmtlZE9mZnNldD1cIit0aGlzLm1hcmtlZE9mZnNldCtcIixsaW1pdD1cIit0aGlzLmxpbWl0K1wiLGNhcGFjaXR5PVwiK3RoaXMuY2FwYWNpdHkoKStcIilcIjtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnbnVtYmVyJylcclxuICAgICAgICAgICAgZW5jb2RpbmcgPSBcInV0ZjhcIixcclxuICAgICAgICAgICAgYmVnaW4gPSBlbmNvZGluZyxcclxuICAgICAgICAgICAgZW5kID0gYmVnaW47XHJcbiAgICAgICAgc3dpdGNoIChlbmNvZGluZykge1xyXG4gICAgICAgICAgICBjYXNlIFwidXRmOFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9VVEY4KGJlZ2luLCBlbmQpO1xyXG4gICAgICAgICAgICBjYXNlIFwiYmFzZTY0XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0Jhc2U2NChiZWdpbiwgZW5kKTtcclxuICAgICAgICAgICAgY2FzZSBcImhleFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9IZXgoYmVnaW4sIGVuZCk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJiaW5hcnlcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQmluYXJ5KGJlZ2luLCBlbmQpO1xyXG4gICAgICAgICAgICBjYXNlIFwiZGVidWdcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvRGVidWcoKTtcclxuICAgICAgICAgICAgY2FzZSBcImNvbHVtbnNcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQ29sdW1ucygpO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJVbnN1cHBvcnRlZCBlbmNvZGluZzogXCIrZW5jb2RpbmcpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLy8gbHhpdi1lbWJlZGRhYmxlXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBseGl2LWVtYmVkZGFibGUgKGMpIDIwMTQgRGFuaWVsIFdpcnR6IDxkY29kZUBkY29kZS5pbz5cclxuICAgICAqIFJlbGVhc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjBcclxuICAgICAqIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vbHhpdiBmb3IgZGV0YWlsc1xyXG4gICAgICovXHJcbiAgICB2YXIgbHhpdiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIFwidXNlIHN0cmljdFwiO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBseGl2IG5hbWVzcGFjZS5cclxuICAgICAgICAgKiBAdHlwZSB7IU9iamVjdC48c3RyaW5nLCo+fVxyXG4gICAgICAgICAqIEBleHBvcnRzIGx4aXZcclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgbHhpdiA9IHt9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDaGFyYWN0ZXIgY29kZXMgZm9yIG91dHB1dC5cclxuICAgICAgICAgKiBAdHlwZSB7IUFycmF5LjxudW1iZXI+fVxyXG4gICAgICAgICAqIEBpbm5lclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHZhciBhb3V0ID0gW1xyXG4gICAgICAgICAgICA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LCA4MCxcclxuICAgICAgICAgICAgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsXHJcbiAgICAgICAgICAgIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCxcclxuICAgICAgICAgICAgMTE5LCAxMjAsIDEyMSwgMTIyLCA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNDMsIDQ3XHJcbiAgICAgICAgXTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2hhcmFjdGVyIGNvZGVzIGZvciBpbnB1dC5cclxuICAgICAgICAgKiBAdHlwZSB7IUFycmF5LjxudW1iZXI+fVxyXG4gICAgICAgICAqIEBpbm5lclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHZhciBhaW4gPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBpPTAsIGs9YW91dC5sZW5ndGg7IGk8azsgKytpKVxyXG4gICAgICAgICAgICBhaW5bYW91dFtpXV0gPSBpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBFbmNvZGVzIGJ5dGVzIHRvIGJhc2U2NCBjaGFyIGNvZGVzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCk6bnVtYmVyfG51bGx9IHNyYyBCeXRlcyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgYnl0ZSByZXNwZWN0aXZlbHkgYG51bGxgIGlmXHJcbiAgICAgICAgICogIHRoZXJlIGFyZSBubyBtb3JlIGJ5dGVzIGxlZnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IENoYXJhY3RlcnMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggZWFjaCBlbmNvZGVkIGNoYXJcclxuICAgICAgICAgKiAgY29kZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBseGl2LmVuY29kZSA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHZhciBiLCB0O1xyXG4gICAgICAgICAgICB3aGlsZSAoKGIgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIGRzdChhb3V0WyhiPj4yKSYweDNmXSk7XHJcbiAgICAgICAgICAgICAgICB0ID0gKGImMHgzKTw8NDtcclxuICAgICAgICAgICAgICAgIGlmICgoYiA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHQgfD0gKGI+PjQpJjB4ZjtcclxuICAgICAgICAgICAgICAgICAgICBkc3QoYW91dFsodHwoKGI+PjQpJjB4ZikpJjB4M2ZdKTtcclxuICAgICAgICAgICAgICAgICAgICB0ID0gKGImMHhmKTw8MjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKGIgPSBzcmMoKSkgIT09IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRzdChhb3V0Wyh0fCgoYj4+NikmMHgzKSkmMHgzZl0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkc3QoYW91dFtiJjB4M2ZdKTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRzdChhb3V0W3QmMHgzZl0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkc3QoNjEpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KGFvdXRbdCYweDNmXSksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KDYxKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoNjEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVjb2RlcyBiYXNlNjQgY2hhciBjb2RlcyB0byBieXRlcy5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbigpOm51bWJlcnxudWxsfSBzcmMgQ2hhcmFjdGVycyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY2hhciBjb2RlIHJlc3BlY3RpdmVseVxyXG4gICAgICAgICAqICBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBCeXRlcyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCB0aGUgbmV4dCBieXRlLlxyXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBhIGNoYXJhY3RlciBjb2RlIGlzIGludmFsaWRcclxuICAgICAgICAgKi9cclxuICAgICAgICBseGl2LmRlY29kZSA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHZhciBjLCB0MSwgdDI7XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGZhaWwoYykge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJJbGxlZ2FsIGNoYXJhY3RlciBjb2RlOiBcIitjKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB3aGlsZSAoKGMgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHQxID0gYWluW2NdO1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0MSA9PT0gJ3VuZGVmaW5lZCcpIGZhaWwoYyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoKGMgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICB0MiA9IGFpbltjXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHQyID09PSAndW5kZWZpbmVkJykgZmFpbChjKTtcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKHQxPDwyKT4+PjB8KHQyJjB4MzApPj40KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKGMgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdDEgPSBhaW5bY107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdDEgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT09IDYxKSBicmVhazsgZWxzZSBmYWlsKGMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkc3QoKCh0MiYweGYpPDw0KT4+PjB8KHQxJjB4M2MpPj4yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChjID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0MiA9IGFpbltjXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdDIgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjID09PSA2MSkgYnJlYWs7IGVsc2UgZmFpbChjKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdCgoKHQxJjB4Myk8PDYpPj4+MHx0Mik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUZXN0cyBpZiBhIHN0cmluZyBpcyB2YWxpZCBiYXNlNjQuXHJcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gdGVzdFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdmFsaWQsIG90aGVyd2lzZSBgZmFsc2VgXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbHhpdi50ZXN0ID0gZnVuY3Rpb24oc3RyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAvXig/OltBLVphLXowLTkrL117NH0pKig/OltBLVphLXowLTkrL117Mn09PXxbQS1aYS16MC05Ky9dezN9PSk/JC8udGVzdChzdHIpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiBseGl2O1xyXG4gICAgfSgpO1xyXG5cclxuICAgIC8vIGVuY29kaW5ncy9iYXNlNjRcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuY29kZXMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMgdG8gYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIE9mZnNldCB0byBiZWdpbiBhdCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEJhc2U2NCBlbmNvZGVkIHN0cmluZ1xyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYGJlZ2luYCBvciBgZW5kYCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9CYXNlNjQgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGJlZ2luID0gYmVnaW4gfCAwOyBlbmQgPSBlbmQgfCAwO1xyXG4gICAgICAgIGlmIChiZWdpbiA8IDAgfHwgZW5kID4gdGhpcy5jYXBhY2l0eSB8fCBiZWdpbiA+IGVuZClcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcImJlZ2luLCBlbmRcIik7XHJcbiAgICAgICAgdmFyIHNkOyBseGl2LmVuY29kZShmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGJlZ2luIDwgZW5kID8gdGhpcy52aWV3W2JlZ2luKytdIDogbnVsbDtcclxuICAgICAgICB9LmJpbmQodGhpcyksIHNkID0gc3RyaW5nRGVzdGluYXRpb24oKSk7XHJcbiAgICAgICAgcmV0dXJuIHNkKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZyB0byBhIEJ5dGVCdWZmZXIuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBkZWNvZGVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmZyb21CYXNlNjQgPSBmdW5jdGlvbihzdHIsIGxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwic3RyXCIpO1xyXG4gICAgICAgIHZhciBiYiA9IG5ldyBCeXRlQnVmZmVyKHN0ci5sZW5ndGgvNCozLCBsaXR0bGVFbmRpYW4pLFxyXG4gICAgICAgICAgICBpID0gMDtcclxuICAgICAgICBseGl2LmRlY29kZShzdHJpbmdTb3VyY2Uoc3RyKSwgZnVuY3Rpb24oYikge1xyXG4gICAgICAgICAgICBiYi52aWV3W2krK10gPSBiO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGJiLmxpbWl0ID0gaTtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyBhIGJpbmFyeSBzdHJpbmcgdG8gYmFzZTY0IGxpa2UgYHdpbmRvdy5idG9hYCBkb2VzLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBCaW5hcnkgc3RyaW5nXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBCYXNlNjQgZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dpbmRvdy5idG9hXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuYnRvYSA9IGZ1bmN0aW9uKHN0cikge1xyXG4gICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21CaW5hcnkoc3RyKS50b0Jhc2U2NCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY29kZXMgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gYmluYXJ5IGxpa2UgYHdpbmRvdy5hdG9iYCBkb2VzLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGI2NCBCYXNlNjQgZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEJpbmFyeSBzdHJpbmdcclxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dpbmRvdy5hdG9iXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuYXRvYiA9IGZ1bmN0aW9uKGI2NCkge1xyXG4gICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21CYXNlNjQoYjY0KS50b0JpbmFyeSgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBlbmNvZGluZ3MvYmluYXJ5XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmNvZGVzIHRoaXMgQnl0ZUJ1ZmZlciB0byBhIGJpbmFyeSBlbmNvZGVkIHN0cmluZywgdGhhdCBpcyB1c2luZyBvbmx5IGNoYXJhY3RlcnMgMHgwMC0weEZGIGFzIGJ5dGVzLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gYmVnaW4gYXQuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBPZmZzZXQgdG8gZW5kIGF0LiBEZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBCaW5hcnkgZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXQgPiBsaW1pdGBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0JpbmFyeSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgYmVnaW4gfD0gMDsgZW5kIHw9IDA7XHJcbiAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBlbmQgPiB0aGlzLmNhcGFjaXR5KCkgfHwgYmVnaW4gPiBlbmQpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJiZWdpbiwgZW5kXCIpO1xyXG4gICAgICAgIGlmIChiZWdpbiA9PT0gZW5kKVxyXG4gICAgICAgICAgICByZXR1cm4gXCJcIjtcclxuICAgICAgICB2YXIgY2hhcnMgPSBbXSxcclxuICAgICAgICAgICAgcGFydHMgPSBbXTtcclxuICAgICAgICB3aGlsZSAoYmVnaW4gPCBlbmQpIHtcclxuICAgICAgICAgICAgY2hhcnMucHVzaCh0aGlzLnZpZXdbYmVnaW4rK10pO1xyXG4gICAgICAgICAgICBpZiAoY2hhcnMubGVuZ3RoID49IDEwMjQpXHJcbiAgICAgICAgICAgICAgICBwYXJ0cy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaGFycykpLFxyXG4gICAgICAgICAgICAgICAgY2hhcnMgPSBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHBhcnRzLmpvaW4oJycpICsgU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNoYXJzKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGEgYmluYXJ5IGVuY29kZWQgc3RyaW5nLCB0aGF0IGlzIHVzaW5nIG9ubHkgY2hhcmFjdGVycyAweDAwLTB4RkYgYXMgYnl0ZXMsIHRvIGEgQnl0ZUJ1ZmZlci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGRlY29kZVxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBCeXRlQnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuZnJvbUJpbmFyeSA9IGZ1bmN0aW9uKHN0ciwgbGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxyXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJzdHJcIik7XHJcbiAgICAgICAgdmFyIGkgPSAwLFxyXG4gICAgICAgICAgICBrID0gc3RyLmxlbmd0aCxcclxuICAgICAgICAgICAgY2hhckNvZGUsXHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoaywgbGl0dGxlRW5kaWFuKTtcclxuICAgICAgICB3aGlsZSAoaTxrKSB7XHJcbiAgICAgICAgICAgIGNoYXJDb2RlID0gc3RyLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgICAgIGlmIChjaGFyQ29kZSA+IDB4ZmYpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiaWxsZWdhbCBjaGFyIGNvZGU6IFwiK2NoYXJDb2RlKTtcclxuICAgICAgICAgICAgYmIudmlld1tpKytdID0gY2hhckNvZGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJiLmxpbWl0ID0gaztcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIGVuY29kaW5ncy9kZWJ1Z1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyB0aGlzIEJ5dGVCdWZmZXIgdG8gYSBoZXggZW5jb2RlZCBzdHJpbmcgd2l0aCBtYXJrZWQgb2Zmc2V0cy4gT2Zmc2V0IHN5bWJvbHMgYXJlOlxyXG4gICAgICogKiBgPGAgOiBvZmZzZXQsXHJcbiAgICAgKiAqIGAnYCA6IG1hcmtlZE9mZnNldCxcclxuICAgICAqICogYD5gIDogbGltaXQsXHJcbiAgICAgKiAqIGB8YCA6IG9mZnNldCBhbmQgbGltaXQsXHJcbiAgICAgKiAqIGBbYCA6IG9mZnNldCBhbmQgbWFya2VkT2Zmc2V0LFxyXG4gICAgICogKiBgXWAgOiBtYXJrZWRPZmZzZXQgYW5kIGxpbWl0LFxyXG4gICAgICogKiBgIWAgOiBvZmZzZXQsIG1hcmtlZE9mZnNldCBhbmQgbGltaXRcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGNvbHVtbnMgSWYgYHRydWVgIHJldHVybnMgdHdvIGNvbHVtbnMgaGV4ICsgYXNjaWksIGRlZmF1bHRzIHRvIGBmYWxzZWBcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8IUFycmF5LjxzdHJpbmc+fSBEZWJ1ZyBzdHJpbmcgb3IgYXJyYXkgb2YgbGluZXMgaWYgYGFzQXJyYXkgPSB0cnVlYFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQGV4YW1wbGUgYD4wMCcwMSAwMjwwM2AgY29udGFpbnMgZm91ciBieXRlcyB3aXRoIGBsaW1pdD0wLCBtYXJrZWRPZmZzZXQ9MSwgb2Zmc2V0PTNgXHJcbiAgICAgKiBAZXhhbXBsZSBgMDBbMDEgMDIgMDM+YCBjb250YWlucyBmb3VyIGJ5dGVzIHdpdGggYG9mZnNldD1tYXJrZWRPZmZzZXQ9MSwgbGltaXQ9NGBcclxuICAgICAqIEBleGFtcGxlIGAwMHwwMSAwMiAwM2AgY29udGFpbnMgZm91ciBieXRlcyB3aXRoIGBvZmZzZXQ9bGltaXQ9MSwgbWFya2VkT2Zmc2V0PS0xYFxyXG4gICAgICogQGV4YW1wbGUgYHxgIGNvbnRhaW5zIHplcm8gYnl0ZXMgd2l0aCBgb2Zmc2V0PWxpbWl0PTAsIG1hcmtlZE9mZnNldD0tMWBcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0RlYnVnID0gZnVuY3Rpb24oY29sdW1ucykge1xyXG4gICAgICAgIHZhciBpID0gLTEsXHJcbiAgICAgICAgICAgIGsgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoLFxyXG4gICAgICAgICAgICBiLFxyXG4gICAgICAgICAgICBoZXggPSBcIlwiLFxyXG4gICAgICAgICAgICBhc2MgPSBcIlwiLFxyXG4gICAgICAgICAgICBvdXQgPSBcIlwiO1xyXG4gICAgICAgIHdoaWxlIChpPGspIHtcclxuICAgICAgICAgICAgaWYgKGkgIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICBiID0gdGhpcy52aWV3W2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKGIgPCAweDEwKSBoZXggKz0gXCIwXCIrYi50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaGV4ICs9IGIudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sdW1ucylcclxuICAgICAgICAgICAgICAgICAgICBhc2MgKz0gYiA+IDMyICYmIGIgPCAxMjcgPyBTdHJpbmcuZnJvbUNoYXJDb2RlKGIpIDogJy4nO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICsraTtcclxuICAgICAgICAgICAgaWYgKGNvbHVtbnMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpID4gMCAmJiBpICUgMTYgPT09IDAgJiYgaSAhPT0gaykge1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChoZXgubGVuZ3RoIDwgMyoxNiszKSBoZXggKz0gXCIgXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgb3V0ICs9IGhleCthc2MrXCJcXG5cIjtcclxuICAgICAgICAgICAgICAgICAgICBoZXggPSBhc2MgPSBcIlwiO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChpID09PSB0aGlzLm9mZnNldCAmJiBpID09PSB0aGlzLmxpbWl0KVxyXG4gICAgICAgICAgICAgICAgaGV4ICs9IGkgPT09IHRoaXMubWFya2VkT2Zmc2V0ID8gXCIhXCIgOiBcInxcIjtcclxuICAgICAgICAgICAgZWxzZSBpZiAoaSA9PT0gdGhpcy5vZmZzZXQpXHJcbiAgICAgICAgICAgICAgICBoZXggKz0gaSA9PT0gdGhpcy5tYXJrZWRPZmZzZXQgPyBcIltcIiA6IFwiPFwiO1xyXG4gICAgICAgICAgICBlbHNlIGlmIChpID09PSB0aGlzLmxpbWl0KVxyXG4gICAgICAgICAgICAgICAgaGV4ICs9IGkgPT09IHRoaXMubWFya2VkT2Zmc2V0ID8gXCJdXCIgOiBcIj5cIjtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgaGV4ICs9IGkgPT09IHRoaXMubWFya2VkT2Zmc2V0ID8gXCInXCIgOiAoY29sdW1ucyB8fCAoaSAhPT0gMCAmJiBpICE9PSBrKSA/IFwiIFwiIDogXCJcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjb2x1bW5zICYmIGhleCAhPT0gXCIgXCIpIHtcclxuICAgICAgICAgICAgd2hpbGUgKGhleC5sZW5ndGggPCAzKjE2KzMpXHJcbiAgICAgICAgICAgICAgICBoZXggKz0gXCIgXCI7XHJcbiAgICAgICAgICAgIG91dCArPSBoZXggKyBhc2MgKyBcIlxcblwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY29sdW1ucyA/IG91dCA6IGhleDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGEgaGV4IGVuY29kZWQgc3RyaW5nIHdpdGggbWFya2VkIG9mZnNldHMgdG8gYSBCeXRlQnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBEZWJ1ZyBzdHJpbmcgdG8gZGVjb2RlIChub3QgYmUgZ2VuZXJhdGVkIHdpdGggYGNvbHVtbnMgPSB0cnVlYClcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcy4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3RvRGVidWdcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5mcm9tRGVidWcgPSBmdW5jdGlvbihzdHIsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICB2YXIgayA9IHN0ci5sZW5ndGgsXHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoKChrKzEpLzMpfDAsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpO1xyXG4gICAgICAgIHZhciBpID0gMCwgaiA9IDAsIGNoLCBiLFxyXG4gICAgICAgICAgICBycyA9IGZhbHNlLCAvLyBSZXF1aXJlIHN5bWJvbCBuZXh0XHJcbiAgICAgICAgICAgIGhvID0gZmFsc2UsIGhtID0gZmFsc2UsIGhsID0gZmFsc2UsIC8vIEFscmVhZHkgaGFzIG9mZnNldCAoaG8pLCBtYXJrZWRPZmZzZXQgKGhtKSwgbGltaXQgKGhsKT9cclxuICAgICAgICAgICAgZmFpbCA9IGZhbHNlO1xyXG4gICAgICAgIHdoaWxlIChpPGspIHtcclxuICAgICAgICAgICAgc3dpdGNoIChjaCA9IHN0ci5jaGFyQXQoaSsrKSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnISc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG8gfHwgaG0gfHwgaGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaG8gPSBobSA9IGhsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gYmIubWFya2VkT2Zmc2V0ID0gYmIubGltaXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICd8JzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobyB8fCBobCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobyA9IGhsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gYmIubGltaXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdbJzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobyB8fCBobSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobyA9IGhtID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gYmIubWFya2VkT2Zmc2V0ID0gajtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnPCc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaG8gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi5vZmZzZXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICddJzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobCB8fCBobSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobCA9IGhtID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIubGltaXQgPSBiYi5tYXJrZWRPZmZzZXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICc+JzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLmxpbWl0ID0gajtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBcIidcIjpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLm1hcmtlZE9mZnNldCA9IGo7XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJyAnOlxyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGIgPSBwYXJzZUludChjaCtzdHIuY2hhckF0KGkrKyksIDE2KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihiKSB8fCBiIDwgMCB8fCBiID4gMjU1KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE5vdCBhIGRlYnVnIGVuY29kZWQgc3RyaW5nXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi52aWV3W2orK10gPSBiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZmFpbClcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBJbnZhbGlkIHN5bWJvbCBhdCBcIitpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAoIWhvIHx8ICFobClcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBNaXNzaW5nIG9mZnNldCBvciBsaW1pdFwiKTtcclxuICAgICAgICAgICAgaWYgKGo8YmIuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgZGVidWcgZW5jb2RlZCBzdHJpbmcgKGlzIGl0IGhleD8pIFwiK2orXCIgPCBcIitrKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBlbmNvZGluZ3MvaGV4XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmNvZGVzIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzIHRvIGEgaGV4IGVuY29kZWQgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gYmVnaW4gYXQuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBPZmZzZXQgdG8gZW5kIGF0LiBEZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBIZXggZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBiZWdpbiA9IHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLm9mZnNldCA6IGJlZ2luO1xyXG4gICAgICAgIGVuZCA9IHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnID8gdGhpcy5saW1pdCA6IGVuZDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgb3V0ID0gbmV3IEFycmF5KGVuZCAtIGJlZ2luKSxcclxuICAgICAgICAgICAgYjtcclxuICAgICAgICB3aGlsZSAoYmVnaW4gPCBlbmQpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tiZWdpbisrXTtcclxuICAgICAgICAgICAgaWYgKGIgPCAweDEwKVxyXG4gICAgICAgICAgICAgICAgb3V0LnB1c2goXCIwXCIsIGIudG9TdHJpbmcoMTYpKTtcclxuICAgICAgICAgICAgZWxzZSBvdXQucHVzaChiLnRvU3RyaW5nKDE2KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvdXQuam9pbignJyk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyBhIGhleCBlbmNvZGVkIHN0cmluZyB0byBhIEJ5dGVCdWZmZXIuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBkZWNvZGVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcy4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmZyb21IZXggPSBmdW5jdGlvbihzdHIsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBOb3QgYSBzdHJpbmdcIik7XHJcbiAgICAgICAgICAgIGlmIChzdHIubGVuZ3RoICUgMiAhPT0gMClcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBMZW5ndGggbm90IGEgbXVsdGlwbGUgb2YgMlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGsgPSBzdHIubGVuZ3RoLFxyXG4gICAgICAgICAgICBiYiA9IG5ldyBCeXRlQnVmZmVyKChrIC8gMikgfCAwLCBsaXR0bGVFbmRpYW4pLFxyXG4gICAgICAgICAgICBiO1xyXG4gICAgICAgIGZvciAodmFyIGk9MCwgaj0wOyBpPGs7IGkrPTIpIHtcclxuICAgICAgICAgICAgYiA9IHBhcnNlSW50KHN0ci5zdWJzdHJpbmcoaSwgaSsyKSwgMTYpO1xyXG4gICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KVxyXG4gICAgICAgICAgICAgICAgaWYgKCFpc0Zpbml0ZShiKSB8fCBiIDwgMCB8fCBiID4gMjU1KVxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBDb250YWlucyBub24taGV4IGNoYXJhY3RlcnNcIik7XHJcbiAgICAgICAgICAgIGJiLnZpZXdbaisrXSA9IGI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJiLmxpbWl0ID0gajtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIHV0ZngtZW1iZWRkYWJsZVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogdXRmeC1lbWJlZGRhYmxlIChjKSAyMDE0IERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcbiAgICAgKiBSZWxlYXNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wXHJcbiAgICAgKiBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL3V0ZnggZm9yIGRldGFpbHNcclxuICAgICAqL1xyXG4gICAgdmFyIHV0ZnggPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogdXRmeCBuYW1lc3BhY2UuXHJcbiAgICAgICAgICogQGlubmVyXHJcbiAgICAgICAgICogQHR5cGUgeyFPYmplY3QuPHN0cmluZywqPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgdXRmeCA9IHt9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBNYXhpbXVtIHZhbGlkIGNvZGUgcG9pbnQuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKiBAY29uc3RcclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4Lk1BWF9DT0RFUE9JTlQgPSAweDEwRkZGRjtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRW5jb2RlcyBVVEY4IGNvZGUgcG9pbnRzIHRvIFVURjggYnl0ZXMuXHJcbiAgICAgICAgICogQHBhcmFtIHsoIWZ1bmN0aW9uKCk6bnVtYmVyfG51bGwpIHwgbnVtYmVyfSBzcmMgQ29kZSBwb2ludHMgc291cmNlLCBlaXRoZXIgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY29kZSBwb2ludFxyXG4gICAgICAgICAqICByZXNwZWN0aXZlbHkgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBtb3JlIGNvZGUgcG9pbnRzIGxlZnQgb3IgYSBzaW5nbGUgbnVtZXJpYyBjb2RlIHBvaW50LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBCeXRlcyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCB0aGUgbmV4dCBieXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5lbmNvZGVVVEY4ID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdmFyIGNwID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzcmMgPT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICAgICAgY3AgPSBzcmMsXHJcbiAgICAgICAgICAgICAgICBzcmMgPSBmdW5jdGlvbigpIHsgcmV0dXJuIG51bGw7IH07XHJcbiAgICAgICAgICAgIHdoaWxlIChjcCAhPT0gbnVsbCB8fCAoY3AgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIGlmIChjcCA8IDB4ODApXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KGNwJjB4N0YpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY3AgPCAweDgwMClcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChjcD4+NikmMHgxRil8MHhDMCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KChjcCYweDNGKXwweDgwKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNwIDwgMHgxMDAwMClcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChjcD4+MTIpJjB4MEYpfDB4RTApLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGNwPj42KSYweDNGKXwweDgwKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKGNwJjB4M0YpfDB4ODApO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGNwPj4xOCkmMHgwNyl8MHhGMCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoY3A+PjEyKSYweDNGKXwweDgwKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChjcD4+NikmMHgzRil8MHg4MCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KChjcCYweDNGKXwweDgwKTtcclxuICAgICAgICAgICAgICAgIGNwID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlY29kZXMgVVRGOCBieXRlcyB0byBVVEY4IGNvZGUgcG9pbnRzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCk6bnVtYmVyfG51bGx9IHNyYyBCeXRlcyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgYnl0ZSByZXNwZWN0aXZlbHkgYG51bGxgIGlmIHRoZXJlXHJcbiAgICAgICAgICogIGFyZSBubyBtb3JlIGJ5dGVzIGxlZnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IENvZGUgcG9pbnRzIGRlc3RpbmF0aW9uIGFzIGEgZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIGVhY2ggZGVjb2RlZCBjb2RlIHBvaW50LlxyXG4gICAgICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGEgc3RhcnRpbmcgYnl0ZSBpcyBpbnZhbGlkIGluIFVURjhcclxuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGxhc3Qgc2VxdWVuY2UgaXMgdHJ1bmNhdGVkLiBIYXMgYW4gYXJyYXkgcHJvcGVydHkgYGJ5dGVzYCBob2xkaW5nIHRoZVxyXG4gICAgICAgICAqICByZW1haW5pbmcgYnl0ZXMuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5kZWNvZGVVVEY4ID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdmFyIGEsIGIsIGMsIGQsIGZhaWwgPSBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgICAgICBiID0gYi5zbGljZSgwLCBiLmluZGV4T2YobnVsbCkpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGVyciA9IEVycm9yKGIudG9TdHJpbmcoKSk7XHJcbiAgICAgICAgICAgICAgICBlcnIubmFtZSA9IFwiVHJ1bmNhdGVkRXJyb3JcIjtcclxuICAgICAgICAgICAgICAgIGVyclsnYnl0ZXMnXSA9IGI7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHdoaWxlICgoYSA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKChhJjB4ODApID09PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgIGRzdChhKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKChhJjB4RTApID09PSAweEMwKVxyXG4gICAgICAgICAgICAgICAgICAgICgoYiA9IHNyYygpKSA9PT0gbnVsbCkgJiYgZmFpbChbYSwgYl0pLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGEmMHgxRik8PDYpIHwgKGImMHgzRikpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKGEmMHhGMCkgPT09IDB4RTApXHJcbiAgICAgICAgICAgICAgICAgICAgKChiPXNyYygpKSA9PT0gbnVsbCB8fCAoYz1zcmMoKSkgPT09IG51bGwpICYmIGZhaWwoW2EsIGIsIGNdKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChhJjB4MEYpPDwxMikgfCAoKGImMHgzRik8PDYpIHwgKGMmMHgzRikpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKGEmMHhGOCkgPT09IDB4RjApXHJcbiAgICAgICAgICAgICAgICAgICAgKChiPXNyYygpKSA9PT0gbnVsbCB8fCAoYz1zcmMoKSkgPT09IG51bGwgfHwgKGQ9c3JjKCkpID09PSBudWxsKSAmJiBmYWlsKFthLCBiLCBjICxkXSksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoYSYweDA3KTw8MTgpIHwgKChiJjB4M0YpPDwxMikgfCAoKGMmMHgzRik8PDYpIHwgKGQmMHgzRikpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBzdGFydGluZyBieXRlOiBcIithKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENvbnZlcnRzIFVURjE2IGNoYXJhY3RlcnMgdG8gVVRGOCBjb2RlIHBvaW50cy5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbigpOm51bWJlcnxudWxsfSBzcmMgQ2hhcmFjdGVycyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY2hhciBjb2RlIHJlc3BlY3RpdmVseVxyXG4gICAgICAgICAqICBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBDb2RlIHBvaW50cyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCBlYWNoIGNvbnZlcnRlZCBjb2RlXHJcbiAgICAgICAgICogIHBvaW50LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguVVRGMTZ0b1VURjggPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB2YXIgYzEsIGMyID0gbnVsbDtcclxuICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcclxuICAgICAgICAgICAgICAgIGlmICgoYzEgPSBjMiAhPT0gbnVsbCA/IGMyIDogc3JjKCkpID09PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgaWYgKGMxID49IDB4RDgwMCAmJiBjMSA8PSAweERGRkYpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKGMyID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjMiA+PSAweERDMDAgJiYgYzIgPD0gMHhERkZGKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3QoKGMxLTB4RDgwMCkqMHg0MDArYzItMHhEQzAwKzB4MTAwMDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYzIgPSBudWxsOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGRzdChjMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGMyICE9PSBudWxsKSBkc3QoYzIpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENvbnZlcnRzIFVURjggY29kZSBwb2ludHMgdG8gVVRGMTYgY2hhcmFjdGVycy5cclxuICAgICAgICAgKiBAcGFyYW0geyghZnVuY3Rpb24oKTpudW1iZXJ8bnVsbCkgfCBudW1iZXJ9IHNyYyBDb2RlIHBvaW50cyBzb3VyY2UsIGVpdGhlciBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjb2RlIHBvaW50XHJcbiAgICAgICAgICogIHJlc3BlY3RpdmVseSBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY29kZSBwb2ludHMgbGVmdCBvciBhIHNpbmdsZSBudW1lcmljIGNvZGUgcG9pbnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IENoYXJhY3RlcnMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggZWFjaCBjb252ZXJ0ZWQgY2hhciBjb2RlLlxyXG4gICAgICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGEgY29kZSBwb2ludCBpcyBvdXQgb2YgcmFuZ2VcclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LlVURjh0b1VURjE2ID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdmFyIGNwID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzcmMgPT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICAgICAgY3AgPSBzcmMsIHNyYyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gbnVsbDsgfTtcclxuICAgICAgICAgICAgd2hpbGUgKGNwICE9PSBudWxsIHx8IChjcCA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNwIDw9IDB4RkZGRilcclxuICAgICAgICAgICAgICAgICAgICBkc3QoY3ApO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGNwIC09IDB4MTAwMDAsXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KChjcD4+MTApKzB4RDgwMCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KChjcCUweDQwMCkrMHhEQzAwKTtcclxuICAgICAgICAgICAgICAgIGNwID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENvbnZlcnRzIGFuZCBlbmNvZGVzIFVURjE2IGNoYXJhY3RlcnMgdG8gVVRGOCBieXRlcy5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbigpOm51bWJlcnxudWxsfSBzcmMgQ2hhcmFjdGVycyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY2hhciBjb2RlIHJlc3BlY3RpdmVseSBgbnVsbGBcclxuICAgICAgICAgKiAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBCeXRlcyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCB0aGUgbmV4dCBieXRlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguZW5jb2RlVVRGMTZ0b1VURjggPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB1dGZ4LlVURjE2dG9VVEY4KHNyYywgZnVuY3Rpb24oY3ApIHtcclxuICAgICAgICAgICAgICAgIHV0ZnguZW5jb2RlVVRGOChjcCwgZHN0KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVjb2RlcyBhbmQgY29udmVydHMgVVRGOCBieXRlcyB0byBVVEYxNiBjaGFyYWN0ZXJzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCk6bnVtYmVyfG51bGx9IHNyYyBCeXRlcyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgYnl0ZSByZXNwZWN0aXZlbHkgYG51bGxgIGlmIHRoZXJlXHJcbiAgICAgICAgICogIGFyZSBubyBtb3JlIGJ5dGVzIGxlZnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IENoYXJhY3RlcnMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggZWFjaCBjb252ZXJ0ZWQgY2hhciBjb2RlLlxyXG4gICAgICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGEgc3RhcnRpbmcgYnl0ZSBpcyBpbnZhbGlkIGluIFVURjhcclxuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGxhc3Qgc2VxdWVuY2UgaXMgdHJ1bmNhdGVkLiBIYXMgYW4gYXJyYXkgcHJvcGVydHkgYGJ5dGVzYCBob2xkaW5nIHRoZSByZW1haW5pbmcgYnl0ZXMuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5kZWNvZGVVVEY4dG9VVEYxNiA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHV0ZnguZGVjb2RlVVRGOChzcmMsIGZ1bmN0aW9uKGNwKSB7XHJcbiAgICAgICAgICAgICAgICB1dGZ4LlVURjh0b1VURjE2KGNwLCBkc3QpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDYWxjdWxhdGVzIHRoZSBieXRlIGxlbmd0aCBvZiBhbiBVVEY4IGNvZGUgcG9pbnQuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGNwIFVURjggY29kZSBwb2ludFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEJ5dGUgbGVuZ3RoXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5jYWxjdWxhdGVDb2RlUG9pbnQgPSBmdW5jdGlvbihjcCkge1xyXG4gICAgICAgICAgICByZXR1cm4gKGNwIDwgMHg4MCkgPyAxIDogKGNwIDwgMHg4MDApID8gMiA6IChjcCA8IDB4MTAwMDApID8gMyA6IDQ7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIFVURjggYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgVVRGOCBjb2RlIHBvaW50cy5cclxuICAgICAgICAgKiBAcGFyYW0geyghZnVuY3Rpb24oKTpudW1iZXJ8bnVsbCl9IHNyYyBDb2RlIHBvaW50cyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY29kZSBwb2ludCByZXNwZWN0aXZlbHlcclxuICAgICAgICAgKiAgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBtb3JlIGNvZGUgcG9pbnRzIGxlZnQuXHJcbiAgICAgICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG51bWJlciBvZiBVVEY4IGJ5dGVzIHJlcXVpcmVkXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5jYWxjdWxhdGVVVEY4ID0gZnVuY3Rpb24oc3JjKSB7XHJcbiAgICAgICAgICAgIHZhciBjcCwgbD0wO1xyXG4gICAgICAgICAgICB3aGlsZSAoKGNwID0gc3JjKCkpICE9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgbCArPSAoY3AgPCAweDgwKSA/IDEgOiAoY3AgPCAweDgwMCkgPyAyIDogKGNwIDwgMHgxMDAwMCkgPyAzIDogNDtcclxuICAgICAgICAgICAgcmV0dXJuIGw7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIFVURjggY29kZSBwb2ludHMgcmVzcGVjdGl2ZWx5IFVURjggYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgVVRGMTYgY2hhciBjb2Rlcy5cclxuICAgICAgICAgKiBAcGFyYW0geyghZnVuY3Rpb24oKTpudW1iZXJ8bnVsbCl9IHNyYyBDaGFyYWN0ZXJzIHNvdXJjZSBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjaGFyIGNvZGUgcmVzcGVjdGl2ZWx5XHJcbiAgICAgICAgICogIGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gVGhlIG51bWJlciBvZiBVVEY4IGNvZGUgcG9pbnRzIGF0IGluZGV4IDAgYW5kIHRoZSBudW1iZXIgb2YgVVRGOCBieXRlcyByZXF1aXJlZCBhdCBpbmRleCAxLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjggPSBmdW5jdGlvbihzcmMpIHtcclxuICAgICAgICAgICAgdmFyIG49MCwgbD0wO1xyXG4gICAgICAgICAgICB1dGZ4LlVURjE2dG9VVEY4KHNyYywgZnVuY3Rpb24oY3ApIHtcclxuICAgICAgICAgICAgICAgICsrbjsgbCArPSAoY3AgPCAweDgwKSA/IDEgOiAoY3AgPCAweDgwMCkgPyAyIDogKGNwIDwgMHgxMDAwMCkgPyAzIDogNDtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiBbbixsXTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gdXRmeDtcclxuICAgIH0oKTtcclxuXHJcbiAgICAvLyBlbmNvZGluZ3MvdXRmOFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cyBiZXR3ZWVuIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fSB0byBhbiBVVEY4IGVuY29kZWRcclxuICAgICAqICBzdHJpbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBIZXggZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXQgPiBsaW1pdGBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b1VURjggPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKSBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGJlZ2luICE9PSAnbnVtYmVyJyB8fCBiZWdpbiAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBiZWdpbjogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBiZWdpbiA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuZCAhPT0gJ251bWJlcicgfHwgZW5kICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGVuZDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBlbmQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBiZWdpbiA+IGVuZCB8fCBlbmQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK2JlZ2luK1wiIDw9IFwiK2VuZCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzZDsgdHJ5IHtcclxuICAgICAgICAgICAgdXRmeC5kZWNvZGVVVEY4dG9VVEYxNihmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBiZWdpbiA8IGVuZCA/IHRoaXMudmlld1tiZWdpbisrXSA6IG51bGw7XHJcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSwgc2QgPSBzdHJpbmdEZXN0aW5hdGlvbigpKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGlmIChiZWdpbiAhPT0gZW5kKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IFRydW5jYXRlZCBkYXRhLCBcIitiZWdpbitcIiAhPSBcIitlbmQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2QoKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGFuIFVURjggZW5jb2RlZCBzdHJpbmcgdG8gYSBCeXRlQnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gZGVjb2RlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0Fzc2VydCBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IEJ5dGVCdWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5mcm9tVVRGOCA9IGZ1bmN0aW9uKHN0ciwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xyXG4gICAgICAgIGlmICghbm9Bc3NlcnQpXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBOb3QgYSBzdHJpbmdcIik7XHJcbiAgICAgICAgdmFyIGJiID0gbmV3IEJ5dGVCdWZmZXIodXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgdHJ1ZSlbMV0sIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpLFxyXG4gICAgICAgICAgICBpID0gMDtcclxuICAgICAgICB1dGZ4LmVuY29kZVVURjE2dG9VVEY4KHN0cmluZ1NvdXJjZShzdHIpLCBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgIGJiLnZpZXdbaSsrXSA9IGI7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgYmIubGltaXQgPSBpO1xyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgcmV0dXJuIEJ5dGVCdWZmZXI7XHJcbn0pO1xyXG4iLCJ2YXIgQnVmZmVyID0gcmVxdWlyZSg5MykuQnVmZmVyXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgxMDMpLlRyYW5zZm9ybVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKDM2KS5TdHJpbmdEZWNvZGVyXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKDY1KVxuXG5mdW5jdGlvbiBDaXBoZXJCYXNlIChoYXNoTW9kZSkge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLmhhc2hNb2RlID0gdHlwZW9mIGhhc2hNb2RlID09PSAnc3RyaW5nJ1xuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHRoaXNbaGFzaE1vZGVdID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9IGVsc2Uge1xuICAgIHRoaXMuZmluYWwgPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH1cbiAgaWYgKHRoaXMuX2ZpbmFsKSB7XG4gICAgdGhpcy5fX2ZpbmFsID0gdGhpcy5fZmluYWxcbiAgICB0aGlzLl9maW5hbCA9IG51bGxcbiAgfVxuICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuICB0aGlzLl9lbmNvZGluZyA9IG51bGxcbn1cbmluaGVyaXRzKENpcGhlckJhc2UsIFRyYW5zZm9ybSlcblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBCdWZmZXIuZnJvbShkYXRhLCBpbnB1dEVuYylcbiAgfVxuXG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSByZXR1cm4gdGhpc1xuXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jKVxuICB9XG5cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7fVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuZ2V0QXV0aFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gZ2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QUFEID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYWFkIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChkYXRhLCBfLCBuZXh0KSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgICAgdGhpcy5fdXBkYXRlKGRhdGEpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaCh0aGlzLl91cGRhdGUoZGF0YSkpXG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIG5leHQoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbiAoZG9uZSkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgdGhpcy5wdXNoKHRoaXMuX19maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9XG5cbiAgZG9uZShlcnIpXG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9fZmluYWwoKSB8fCBCdWZmZXIuYWxsb2MoMClcbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX3RvU3RyaW5nID0gZnVuY3Rpb24gKHZhbHVlLCBlbmMsIGZpbikge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cblxuICBpZiAodGhpcy5fZW5jb2RpbmcgIT09IGVuYykgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuXG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluKSB7XG4gICAgb3V0ICs9IHRoaXMuX2RlY29kZXIuZW5kKClcbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDaXBoZXJCYXNlXG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpO1xuICB9XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG4iLCIndXNlIHN0cmljdCdcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoNjUpXG52YXIgTUQ1ID0gcmVxdWlyZSg2OSlcbnZhciBSSVBFTUQxNjAgPSByZXF1aXJlKDkyKVxudmFyIHNoYSA9IHJlcXVpcmUoOTYpXG52YXIgQmFzZSA9IHJlcXVpcmUoMzkpXG5cbmZ1bmN0aW9uIEhhc2ggKGhhc2gpIHtcbiAgQmFzZS5jYWxsKHRoaXMsICdkaWdlc3QnKVxuXG4gIHRoaXMuX2hhc2ggPSBoYXNoXG59XG5cbmluaGVyaXRzKEhhc2gsIEJhc2UpXG5cbkhhc2gucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxufVxuXG5IYXNoLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLl9oYXNoLmRpZ2VzdCgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlSGFzaCAoYWxnKSB7XG4gIGFsZyA9IGFsZy50b0xvd2VyQ2FzZSgpXG4gIGlmIChhbGcgPT09ICdtZDUnKSByZXR1cm4gbmV3IE1ENSgpXG4gIGlmIChhbGcgPT09ICdybWQxNjAnIHx8IGFsZyA9PT0gJ3JpcGVtZDE2MCcpIHJldHVybiBuZXcgUklQRU1EMTYwKClcblxuICByZXR1cm4gbmV3IEhhc2goc2hhKGFsZykpXG59XG4iLCJ2YXIgTUQ1ID0gcmVxdWlyZSg2OSlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYnVmZmVyKSB7XG4gIHJldHVybiBuZXcgTUQ1KCkudXBkYXRlKGJ1ZmZlcikuZGlnZXN0KClcbn1cbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBMZWdhY3kgPSByZXF1aXJlKDQ0KVxudmFyIEJhc2UgPSByZXF1aXJlKDM5KVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlclxudmFyIG1kNSA9IHJlcXVpcmUoNDIpXG52YXIgUklQRU1EMTYwID0gcmVxdWlyZSg5MilcblxudmFyIHNoYSA9IHJlcXVpcmUoOTYpXG5cbnZhciBaRVJPUyA9IEJ1ZmZlci5hbGxvYygxMjgpXG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdmFyIGJsb2Nrc2l6ZSA9IChhbGcgPT09ICdzaGE1MTInIHx8IGFsZyA9PT0gJ3NoYTM4NCcpID8gMTI4IDogNjRcblxuICB0aGlzLl9hbGcgPSBhbGdcbiAgdGhpcy5fa2V5ID0ga2V5XG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAgdmFyIGhhc2ggPSBhbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKGFsZylcbiAgICBrZXkgPSBoYXNoLnVwZGF0ZShrZXkpLmRpZ2VzdCgpXG4gIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgWkVST1NdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IHRoaXMuX2lwYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuICB2YXIgb3BhZCA9IHRoaXMuX29wYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tzaXplOyBpKyspIHtcbiAgICBpcGFkW2ldID0ga2V5W2ldIF4gMHgzNlxuICAgIG9wYWRbaV0gPSBrZXlbaV0gXiAweDVDXG4gIH1cbiAgdGhpcy5faGFzaCA9IGFsZyA9PT0gJ3JtZDE2MCcgPyBuZXcgUklQRU1EMTYwKCkgOiBzaGEoYWxnKVxuICB0aGlzLl9oYXNoLnVwZGF0ZShpcGFkKVxufVxuXG5pbmhlcml0cyhIbWFjLCBCYXNlKVxuXG5IbWFjLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbn1cblxuSG1hYy5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaCA9IHRoaXMuX2hhc2guZGlnZXN0KClcbiAgdmFyIGhhc2ggPSB0aGlzLl9hbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKHRoaXMuX2FsZylcbiAgcmV0dXJuIGhhc2gudXBkYXRlKHRoaXMuX29wYWQpLnVwZGF0ZShoKS5kaWdlc3QoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhtYWMgKGFsZywga2V5KSB7XG4gIGFsZyA9IGFsZy50b0xvd2VyQ2FzZSgpXG4gIGlmIChhbGcgPT09ICdybWQxNjAnIHx8IGFsZyA9PT0gJ3JpcGVtZDE2MCcpIHtcbiAgICByZXR1cm4gbmV3IEhtYWMoJ3JtZDE2MCcsIGtleSlcbiAgfVxuICBpZiAoYWxnID09PSAnbWQ1Jykge1xuICAgIHJldHVybiBuZXcgTGVnYWN5KG1kNSwga2V5KVxuICB9XG4gIHJldHVybiBuZXcgSG1hYyhhbGcsIGtleSlcbn1cbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcblxudmFyIEJhc2UgPSByZXF1aXJlKDM5KVxuXG52YXIgWkVST1MgPSBCdWZmZXIuYWxsb2MoMTI4KVxudmFyIGJsb2Nrc2l6ZSA9IDY0XG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdGhpcy5fYWxnID0gYWxnXG4gIHRoaXMuX2tleSA9IGtleVxuXG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAga2V5ID0gYWxnKGtleSlcbiAgfSBlbHNlIGlmIChrZXkubGVuZ3RoIDwgYmxvY2tzaXplKSB7XG4gICAga2V5ID0gQnVmZmVyLmNvbmNhdChba2V5LCBaRVJPU10sIGJsb2Nrc2l6ZSlcbiAgfVxuXG4gIHZhciBpcGFkID0gdGhpcy5faXBhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG4gIHZhciBvcGFkID0gdGhpcy5fb3BhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja3NpemU7IGkrKykge1xuICAgIGlwYWRbaV0gPSBrZXlbaV0gXiAweDM2XG4gICAgb3BhZFtpXSA9IGtleVtpXSBeIDB4NUNcbiAgfVxuXG4gIHRoaXMuX2hhc2ggPSBbaXBhZF1cbn1cblxuaW5oZXJpdHMoSG1hYywgQmFzZSlcblxuSG1hYy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2hhc2gucHVzaChkYXRhKVxufVxuXG5IbWFjLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBoID0gdGhpcy5fYWxnKEJ1ZmZlci5jb25jYXQodGhpcy5faGFzaCkpXG4gIHJldHVybiB0aGlzLl9hbGcoQnVmZmVyLmNvbmNhdChbdGhpcy5fb3BhZCwgaF0pKVxufVxubW9kdWxlLmV4cG9ydHMgPSBIbWFjXG4iLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSg0NyksIHJlcXVpcmUoNDgpLCByZXF1aXJlKDUyKSwgcmVxdWlyZSg1MCksIHJlcXVpcmUoNDYpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL2VuYy1iYXNlNjRcIiwgXCIuL21kNVwiLCBcIi4vZXZwa2RmXCIsIFwiLi9jaXBoZXItY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyID0gQ19saWIuQmxvY2tDaXBoZXI7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICAvLyBMb29rdXAgdGFibGVzXG5cdCAgICB2YXIgU0JPWCA9IFtdO1xuXHQgICAgdmFyIElOVl9TQk9YID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8wID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8xID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8yID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8zID0gW107XG5cdCAgICB2YXIgSU5WX1NVQl9NSVhfMCA9IFtdO1xuXHQgICAgdmFyIElOVl9TVUJfTUlYXzEgPSBbXTtcblx0ICAgIHZhciBJTlZfU1VCX01JWF8yID0gW107XG5cdCAgICB2YXIgSU5WX1NVQl9NSVhfMyA9IFtdO1xuXG5cdCAgICAvLyBDb21wdXRlIGxvb2t1cCB0YWJsZXNcblx0ICAgIChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgLy8gQ29tcHV0ZSBkb3VibGUgdGFibGVcblx0ICAgICAgICB2YXIgZCA9IFtdO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcblx0ICAgICAgICAgICAgaWYgKGkgPCAxMjgpIHtcblx0ICAgICAgICAgICAgICAgIGRbaV0gPSBpIDw8IDE7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBkW2ldID0gKGkgPDwgMSkgXiAweDExYjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIFdhbGsgR0YoMl44KVxuXHQgICAgICAgIHZhciB4ID0gMDtcblx0ICAgICAgICB2YXIgeGkgPSAwO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBzYm94XG5cdCAgICAgICAgICAgIHZhciBzeCA9IHhpIF4gKHhpIDw8IDEpIF4gKHhpIDw8IDIpIF4gKHhpIDw8IDMpIF4gKHhpIDw8IDQpO1xuXHQgICAgICAgICAgICBzeCA9IChzeCA+Pj4gOCkgXiAoc3ggJiAweGZmKSBeIDB4NjM7XG5cdCAgICAgICAgICAgIFNCT1hbeF0gPSBzeDtcblx0ICAgICAgICAgICAgSU5WX1NCT1hbc3hdID0geDtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIG11bHRpcGxpY2F0aW9uXG5cdCAgICAgICAgICAgIHZhciB4MiA9IGRbeF07XG5cdCAgICAgICAgICAgIHZhciB4NCA9IGRbeDJdO1xuXHQgICAgICAgICAgICB2YXIgeDggPSBkW3g0XTtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIHN1YiBieXRlcywgbWl4IGNvbHVtbnMgdGFibGVzXG5cdCAgICAgICAgICAgIHZhciB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKTtcblx0ICAgICAgICAgICAgU1VCX01JWF8wW3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzFbeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzJbeF0gPSAodCA8PCA4KSAgfCAodCA+Pj4gMjQpO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzNbeF0gPSB0O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgaW52IHN1YiBieXRlcywgaW52IG1peCBjb2x1bW5zIHRhYmxlc1xuXHQgICAgICAgICAgICB2YXIgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKTtcblx0ICAgICAgICAgICAgSU5WX1NVQl9NSVhfMFtzeF0gPSAodCA8PCAyNCkgfCAodCA+Pj4gOCk7XG5cdCAgICAgICAgICAgIElOVl9TVUJfTUlYXzFbc3hdID0gKHQgPDwgMTYpIHwgKHQgPj4+IDE2KTtcblx0ICAgICAgICAgICAgSU5WX1NVQl9NSVhfMltzeF0gPSAodCA8PCA4KSAgfCAodCA+Pj4gMjQpO1xuXHQgICAgICAgICAgICBJTlZfU1VCX01JWF8zW3N4XSA9IHQ7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBuZXh0IGNvdW50ZXJcblx0ICAgICAgICAgICAgaWYgKCF4KSB7XG5cdCAgICAgICAgICAgICAgICB4ID0geGkgPSAxO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgeCA9IHgyIF4gZFtkW2RbeDggXiB4Ml1dXTtcblx0ICAgICAgICAgICAgICAgIHhpIF49IGRbZFt4aV1dO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSgpKTtcblxuXHQgICAgLy8gUHJlY29tcHV0ZWQgUmNvbiBsb29rdXBcblx0ICAgIHZhciBSQ09OID0gWzB4MDAsIDB4MDEsIDB4MDIsIDB4MDQsIDB4MDgsIDB4MTAsIDB4MjAsIDB4NDAsIDB4ODAsIDB4MWIsIDB4MzZdO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFFUyBibG9jayBjaXBoZXIgYWxnb3JpdGhtLlxuXHQgICAgICovXG5cdCAgICB2YXIgQUVTID0gQ19hbGdvLkFFUyA9IEJsb2NrQ2lwaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2tpcCByZXNldCBvZiBuUm91bmRzIGhhcyBiZWVuIHNldCBiZWZvcmUgYW5kIGtleSBkaWQgbm90IGNoYW5nZVxuXHQgICAgICAgICAgICBpZiAodGhpcy5fblJvdW5kcyAmJiB0aGlzLl9rZXlQcmlvclJlc2V0ID09PSB0aGlzLl9rZXkpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIga2V5ID0gdGhpcy5fa2V5UHJpb3JSZXNldCA9IHRoaXMuX2tleTtcblx0ICAgICAgICAgICAgdmFyIGtleVdvcmRzID0ga2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGtleS5zaWdCeXRlcyAvIDQ7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBudW1iZXIgb2Ygcm91bmRzXG5cdCAgICAgICAgICAgIHZhciBuUm91bmRzID0gdGhpcy5fblJvdW5kcyA9IGtleVNpemUgKyA2O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgbnVtYmVyIG9mIGtleSBzY2hlZHVsZSByb3dzXG5cdCAgICAgICAgICAgIHZhciBrc1Jvd3MgPSAoblJvdW5kcyArIDEpICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIGtleSBzY2hlZHVsZVxuXHQgICAgICAgICAgICB2YXIga2V5U2NoZWR1bGUgPSB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBrc1JvdyA9IDA7IGtzUm93IDwga3NSb3dzOyBrc1JvdysrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoa3NSb3cgPCBrZXlTaXplKSB7XG5cdCAgICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5V29yZHNba3NSb3ddO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgdCA9IGtleVNjaGVkdWxlW2tzUm93IC0gMV07XG5cblx0ICAgICAgICAgICAgICAgICAgICBpZiAoIShrc1JvdyAlIGtleVNpemUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJvdCB3b3JkXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAodCA8PCA4KSB8ICh0ID4+PiAyNCk7XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3ViIHdvcmRcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdCA9IChTQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsodCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3QgJiAweGZmXTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBNaXggUmNvblxuXHQgICAgICAgICAgICAgICAgICAgICAgICB0IF49IFJDT05bKGtzUm93IC8ga2V5U2l6ZSkgfCAwXSA8PCAyNDtcblx0ICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PSA0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1YiB3b3JkXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAoU0JPWFt0ID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFt0ICYgMHhmZl07XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQ7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIGludiBrZXkgc2NoZWR1bGVcblx0ICAgICAgICAgICAgdmFyIGludktleVNjaGVkdWxlID0gdGhpcy5faW52S2V5U2NoZWR1bGUgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaW52S3NSb3cgPSAwOyBpbnZLc1JvdyA8IGtzUm93czsgaW52S3NSb3crKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGtzUm93ID0ga3NSb3dzIC0gaW52S3NSb3c7XG5cblx0ICAgICAgICAgICAgICAgIGlmIChpbnZLc1JvdyAlIDQpIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgdCA9IGtleVNjaGVkdWxlW2tzUm93XTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSBrZXlTY2hlZHVsZVtrc1JvdyAtIDRdO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICBpZiAoaW52S3NSb3cgPCA0IHx8IGtzUm93IDw9IDQpIHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSB0O1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSBJTlZfU1VCX01JWF8wW1NCT1hbdCA+Pj4gMjRdXSBeIElOVl9TVUJfTUlYXzFbU0JPWFsodCA+Pj4gMTYpICYgMHhmZl1dIF5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlZfU1VCX01JWF8yW1NCT1hbKHQgPj4+IDgpICYgMHhmZl1dIF4gSU5WX1NVQl9NSVhfM1tTQk9YW3QgJiAweGZmXV07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgZW5jcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2RvQ3J5cHRCbG9jayhNLCBvZmZzZXQsIHRoaXMuX2tleVNjaGVkdWxlLCBTVUJfTUlYXzAsIFNVQl9NSVhfMSwgU1VCX01JWF8yLCBTVUJfTUlYXzMsIFNCT1gpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBkZWNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU3dhcCAybmQgYW5kIDR0aCByb3dzXG5cdCAgICAgICAgICAgIHZhciB0ID0gTVtvZmZzZXQgKyAxXTtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAxXSA9IE1bb2Zmc2V0ICsgM107XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgM10gPSB0O1xuXG5cdCAgICAgICAgICAgIHRoaXMuX2RvQ3J5cHRCbG9jayhNLCBvZmZzZXQsIHRoaXMuX2ludktleVNjaGVkdWxlLCBJTlZfU1VCX01JWF8wLCBJTlZfU1VCX01JWF8xLCBJTlZfU1VCX01JWF8yLCBJTlZfU1VCX01JWF8zLCBJTlZfU0JPWCk7XG5cblx0ICAgICAgICAgICAgLy8gSW52IHN3YXAgMm5kIGFuZCA0dGggcm93c1xuXHQgICAgICAgICAgICB2YXIgdCA9IE1bb2Zmc2V0ICsgMV07XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSBNW29mZnNldCArIDNdO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDNdID0gdDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvQ3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCwga2V5U2NoZWR1bGUsIFNVQl9NSVhfMCwgU1VCX01JWF8xLCBTVUJfTUlYXzIsIFNVQl9NSVhfMywgU0JPWCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgblJvdW5kcyA9IHRoaXMuX25Sb3VuZHM7XG5cblx0ICAgICAgICAgICAgLy8gR2V0IGlucHV0LCBhZGQgcm91bmQga2V5XG5cdCAgICAgICAgICAgIHZhciBzMCA9IE1bb2Zmc2V0XSAgICAgXiBrZXlTY2hlZHVsZVswXTtcblx0ICAgICAgICAgICAgdmFyIHMxID0gTVtvZmZzZXQgKyAxXSBeIGtleVNjaGVkdWxlWzFdO1xuXHQgICAgICAgICAgICB2YXIgczIgPSBNW29mZnNldCArIDJdIF4ga2V5U2NoZWR1bGVbMl07XG5cdCAgICAgICAgICAgIHZhciBzMyA9IE1bb2Zmc2V0ICsgM10gXiBrZXlTY2hlZHVsZVszXTtcblxuXHQgICAgICAgICAgICAvLyBLZXkgc2NoZWR1bGUgcm93IGNvdW50ZXJcblx0ICAgICAgICAgICAgdmFyIGtzUm93ID0gNDtcblxuXHQgICAgICAgICAgICAvLyBSb3VuZHNcblx0ICAgICAgICAgICAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IG5Sb3VuZHM7IHJvdW5kKyspIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNoaWZ0IHJvd3MsIHN1YiBieXRlcywgbWl4IGNvbHVtbnMsIGFkZCByb3VuZCBrZXlcblx0ICAgICAgICAgICAgICAgIHZhciB0MCA9IFNVQl9NSVhfMFtzMCA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMSA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MzICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MSA9IFNVQl9NSVhfMFtzMSA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMiA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMzID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MwICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MiA9IFNVQl9NSVhfMFtzMiA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMyA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MxICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MyA9IFNVQl9NSVhfMFtzMyA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMCA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MyICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblxuXHQgICAgICAgICAgICAgICAgLy8gVXBkYXRlIHN0YXRlXG5cdCAgICAgICAgICAgICAgICBzMCA9IHQwO1xuXHQgICAgICAgICAgICAgICAgczEgPSB0MTtcblx0ICAgICAgICAgICAgICAgIHMyID0gdDI7XG5cdCAgICAgICAgICAgICAgICBzMyA9IHQzO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gU2hpZnQgcm93cywgc3ViIGJ5dGVzLCBhZGQgcm91bmQga2V5XG5cdCAgICAgICAgICAgIHZhciB0MCA9ICgoU0JPWFtzMCA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMSA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMyID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMyAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdO1xuXHQgICAgICAgICAgICB2YXIgdDEgPSAoKFNCT1hbczEgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczIgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMyA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczAgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgdmFyIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgIHZhciB0MyA9ICgoU0JPWFtzMyA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMxID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMiAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdO1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBvdXRwdXRcblx0ICAgICAgICAgICAgTVtvZmZzZXRdICAgICA9IHQwO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDFdID0gdDE7XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgMl0gPSB0Mjtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAzXSA9IHQzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBrZXlTaXplOiAyNTYvMzJcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9ucyB0byB0aGUgY2lwaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgY2lwaGVydGV4dCA9IENyeXB0b0pTLkFFUy5lbmNyeXB0KG1lc3NhZ2UsIGtleSwgY2ZnKTtcblx0ICAgICAqICAgICB2YXIgcGxhaW50ZXh0ICA9IENyeXB0b0pTLkFFUy5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTtcblx0ICAgICAqL1xuXHQgICAgQy5BRVMgPSBCbG9ja0NpcGhlci5fY3JlYXRlSGVscGVyKEFFUyk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuQUVTO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoNDcpLCByZXF1aXJlKDUwKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9ldnBrZGZcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdC8qKlxuXHQgKiBDaXBoZXIgY29yZSBjb21wb25lbnRzLlxuXHQgKi9cblx0Q3J5cHRvSlMubGliLkNpcGhlciB8fCAoZnVuY3Rpb24gKHVuZGVmaW5lZCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBDX2xpYi5CdWZmZXJlZEJsb2NrQWxnb3JpdGhtO1xuXHQgICAgdmFyIENfZW5jID0gQy5lbmM7XG5cdCAgICB2YXIgVXRmOCA9IENfZW5jLlV0Zjg7XG5cdCAgICB2YXIgQmFzZTY0ID0gQ19lbmMuQmFzZTY0O1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblx0ICAgIHZhciBFdnBLREYgPSBDX2FsZ28uRXZwS0RGO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFic3RyYWN0IGJhc2UgY2lwaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBrZXlTaXplIFRoaXMgY2lwaGVyJ3Mga2V5IHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKVxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGl2U2l6ZSBUaGlzIGNpcGhlcidzIElWIHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKVxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9FTkNfWEZPUk1fTU9ERSBBIGNvbnN0YW50IHJlcHJlc2VudGluZyBlbmNyeXB0aW9uIG1vZGUuXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX0RFQ19YRk9STV9NT0RFIEEgY29uc3RhbnQgcmVwcmVzZW50aW5nIGRlY3J5cHRpb24gbW9kZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENpcGhlciA9IENfbGliLkNpcGhlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gaXYgVGhlIElWIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyB0aGlzIGNpcGhlciBpbiBlbmNyeXB0aW9uIG1vZGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlcn0gQSBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXIgPSBDcnlwdG9KUy5hbGdvLkFFUy5jcmVhdGVFbmNyeXB0b3Ioa2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVFbmNyeXB0b3I6IGZ1bmN0aW9uIChrZXksIGNmZykge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUodGhpcy5fRU5DX1hGT1JNX01PREUsIGtleSwgY2ZnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyB0aGlzIGNpcGhlciBpbiBkZWNyeXB0aW9uIG1vZGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlcn0gQSBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXIgPSBDcnlwdG9KUy5hbGdvLkFFUy5jcmVhdGVEZWNyeXB0b3Ioa2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVEZWNyeXB0b3I6IGZ1bmN0aW9uIChrZXksIGNmZykge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUodGhpcy5fREVDX1hGT1JNX01PREUsIGtleSwgY2ZnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIGNpcGhlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4Zm9ybU1vZGUgRWl0aGVyIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gdHJhbnNvcm1hdGlvbiBtb2RlIGNvbnN0YW50LlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVyID0gQ3J5cHRvSlMuYWxnby5BRVMuY3JlYXRlKENyeXB0b0pTLmFsZ28uQUVTLl9FTkNfWEZPUk1fTU9ERSwga2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoeGZvcm1Nb2RlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBTdG9yZSB0cmFuc2Zvcm0gbW9kZSBhbmQga2V5XG5cdCAgICAgICAgICAgIHRoaXMuX3hmb3JtTW9kZSA9IHhmb3JtTW9kZTtcblx0ICAgICAgICAgICAgdGhpcy5fa2V5ID0ga2V5O1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFJlc2V0cyB0aGlzIGNpcGhlciB0byBpdHMgaW5pdGlhbCBzdGF0ZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgY2lwaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gUmVzZXQgZGF0YSBidWZmZXJcblx0ICAgICAgICAgICAgQnVmZmVyZWRCbG9ja0FsZ29yaXRobS5yZXNldC5jYWxsKHRoaXMpO1xuXG5cdCAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljXG5cdCAgICAgICAgICAgIHRoaXMuX2RvUmVzZXQoKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQWRkcyBkYXRhIHRvIGJlIGVuY3J5cHRlZCBvciBkZWNyeXB0ZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGRhdGFVcGRhdGUgVGhlIGRhdGEgdG8gZW5jcnlwdCBvciBkZWNyeXB0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGF0YSBhZnRlciBwcm9jZXNzaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgZW5jcnlwdGVkID0gY2lwaGVyLnByb2Nlc3MoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5wcm9jZXNzKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcHJvY2VzczogZnVuY3Rpb24gKGRhdGFVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gQXBwZW5kXG5cdCAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTtcblxuXHQgICAgICAgICAgICAvLyBQcm9jZXNzIGF2YWlsYWJsZSBibG9ja3Ncblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3MoKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRmluYWxpemVzIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gcHJvY2Vzcy5cblx0ICAgICAgICAgKiBOb3RlIHRoYXQgdGhlIGZpbmFsaXplIG9wZXJhdGlvbiBpcyBlZmZlY3RpdmVseSBhIGRlc3RydWN0aXZlLCByZWFkLW9uY2Ugb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhVXBkYXRlIFRoZSBmaW5hbCBkYXRhIHRvIGVuY3J5cHQgb3IgZGVjcnlwdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRhdGEgYWZ0ZXIgZmluYWwgcHJvY2Vzc2luZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5maW5hbGl6ZSgpO1xuXHQgICAgICAgICAqICAgICB2YXIgZW5jcnlwdGVkID0gY2lwaGVyLmZpbmFsaXplKCdkYXRhJyk7XG5cdCAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmaW5hbGl6ZTogZnVuY3Rpb24gKGRhdGFVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gRmluYWwgZGF0YSB1cGRhdGVcblx0ICAgICAgICAgICAgaWYgKGRhdGFVcGRhdGUpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljXG5cdCAgICAgICAgICAgIHZhciBmaW5hbFByb2Nlc3NlZERhdGEgPSB0aGlzLl9kb0ZpbmFsaXplKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGZpbmFsUHJvY2Vzc2VkRGF0YTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAga2V5U2l6ZTogMTI4LzMyLFxuXG5cdCAgICAgICAgaXZTaXplOiAxMjgvMzIsXG5cblx0ICAgICAgICBfRU5DX1hGT1JNX01PREU6IDEsXG5cblx0ICAgICAgICBfREVDX1hGT1JNX01PREU6IDIsXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIHNob3J0Y3V0IGZ1bmN0aW9ucyB0byBhIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgdG8gY3JlYXRlIGEgaGVscGVyIGZvci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gQW4gb2JqZWN0IHdpdGggZW5jcnlwdCBhbmQgZGVjcnlwdCBzaG9ydGN1dCBmdW5jdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBBRVMgPSBDcnlwdG9KUy5saWIuQ2lwaGVyLl9jcmVhdGVIZWxwZXIoQ3J5cHRvSlMuYWxnby5BRVMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9jcmVhdGVIZWxwZXI6IChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIGZ1bmN0aW9uIHNlbGVjdENpcGhlclN0cmF0ZWd5KGtleSkge1xuXHQgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBrZXkgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGFzc3dvcmRCYXNlZENpcGhlcjtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNlcmlhbGl6YWJsZUNpcGhlcjtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoY2lwaGVyKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGVuY3J5cHQ6IGZ1bmN0aW9uIChtZXNzYWdlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0Q2lwaGVyU3RyYXRlZ3koa2V5KS5lbmNyeXB0KGNpcGhlciwgbWVzc2FnZSwga2V5LCBjZmcpO1xuXHQgICAgICAgICAgICAgICAgICAgIH0sXG5cblx0ICAgICAgICAgICAgICAgICAgICBkZWNyeXB0OiBmdW5jdGlvbiAoY2lwaGVydGV4dCwga2V5LCBjZmcpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdENpcGhlclN0cmF0ZWd5KGtleSkuZGVjcnlwdChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH0oKSlcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFic3RyYWN0IGJhc2Ugc3RyZWFtIGNpcGhlciB0ZW1wbGF0ZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgY2lwaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiAxICgzMiBiaXRzKVxuXHQgICAgICovXG5cdCAgICB2YXIgU3RyZWFtQ2lwaGVyID0gQ19saWIuU3RyZWFtQ2lwaGVyID0gQ2lwaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gUHJvY2VzcyBwYXJ0aWFsIGJsb2Nrc1xuXHQgICAgICAgICAgICB2YXIgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKCEhJ2ZsdXNoJyk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGZpbmFsUHJvY2Vzc2VkQmxvY2tzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBibG9ja1NpemU6IDFcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIE1vZGUgbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19tb2RlID0gQy5tb2RlID0ge307XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYmFzZSBibG9jayBjaXBoZXIgbW9kZSB0ZW1wbGF0ZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyTW9kZSA9IENfbGliLkJsb2NrQ2lwaGVyTW9kZSA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIHRoaXMgbW9kZSBmb3IgZW5jcnlwdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgQSBibG9jayBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtBcnJheX0gaXYgVGhlIElWIHdvcmRzLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgbW9kZSA9IENyeXB0b0pTLm1vZGUuQ0JDLmNyZWF0ZUVuY3J5cHRvcihjaXBoZXIsIGl2LndvcmRzKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVFbmNyeXB0b3I6IGZ1bmN0aW9uIChjaXBoZXIsIGl2KSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLkVuY3J5cHRvci5jcmVhdGUoY2lwaGVyLCBpdik7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENyZWF0ZXMgdGhpcyBtb2RlIGZvciBkZWNyeXB0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBBIGJsb2NrIGNpcGhlciBpbnN0YW5jZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBpdiBUaGUgSVYgd29yZHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBtb2RlID0gQ3J5cHRvSlMubW9kZS5DQkMuY3JlYXRlRGVjcnlwdG9yKGNpcGhlciwgaXYud29yZHMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNyZWF0ZURlY3J5cHRvcjogZnVuY3Rpb24gKGNpcGhlciwgaXYpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuRGVjcnlwdG9yLmNyZWF0ZShjaXBoZXIsIGl2KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG1vZGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIEEgYmxvY2sgY2lwaGVyIGluc3RhbmNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGl2IFRoZSBJViB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIG1vZGUgPSBDcnlwdG9KUy5tb2RlLkNCQy5FbmNyeXB0b3IuY3JlYXRlKGNpcGhlciwgaXYud29yZHMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjaXBoZXIsIGl2KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2NpcGhlciA9IGNpcGhlcjtcblx0ICAgICAgICAgICAgdGhpcy5faXYgPSBpdjtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENCQyA9IENfbW9kZS5DQkMgPSAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEFic3RyYWN0IGJhc2UgQ0JDIG1vZGUuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdmFyIENCQyA9IEJsb2NrQ2lwaGVyTW9kZS5leHRlbmQoKTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENCQyBlbmNyeXB0b3IuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgQ0JDLkVuY3J5cHRvciA9IENCQy5leHRlbmQoe1xuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogUHJvY2Vzc2VzIHRoZSBkYXRhIGJsb2NrIGF0IG9mZnNldC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgVGhlIGRhdGEgd29yZHMgdG8gb3BlcmF0ZSBvbi5cblx0ICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBUaGUgb2Zmc2V0IHdoZXJlIHRoZSBibG9jayBzdGFydHMuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBtb2RlLnByb2Nlc3NCbG9jayhkYXRhLndvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyO1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZSA9IGNpcGhlci5ibG9ja1NpemU7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFhPUiBhbmQgZW5jcnlwdFxuXHQgICAgICAgICAgICAgICAgeG9yQmxvY2suY2FsbCh0aGlzLCB3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUpO1xuXHQgICAgICAgICAgICAgICAgY2lwaGVyLmVuY3J5cHRCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhpcyBibG9jayB0byB1c2Ugd2l0aCBuZXh0IGJsb2NrXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9wcmV2QmxvY2sgPSB3b3Jkcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGJsb2NrU2l6ZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENCQyBkZWNyeXB0b3IuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgQ0JDLkRlY3J5cHRvciA9IENCQy5leHRlbmQoe1xuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogUHJvY2Vzc2VzIHRoZSBkYXRhIGJsb2NrIGF0IG9mZnNldC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgVGhlIGRhdGEgd29yZHMgdG8gb3BlcmF0ZSBvbi5cblx0ICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBUaGUgb2Zmc2V0IHdoZXJlIHRoZSBibG9jayBzdGFydHMuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBtb2RlLnByb2Nlc3NCbG9jayhkYXRhLndvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyO1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZSA9IGNpcGhlci5ibG9ja1NpemU7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoaXMgYmxvY2sgdG8gdXNlIHdpdGggbmV4dCBibG9ja1xuXHQgICAgICAgICAgICAgICAgdmFyIHRoaXNCbG9jayA9IHdvcmRzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmxvY2tTaXplKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gRGVjcnlwdCBhbmQgWE9SXG5cdCAgICAgICAgICAgICAgICBjaXBoZXIuZGVjcnlwdEJsb2NrKHdvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgICAgeG9yQmxvY2suY2FsbCh0aGlzLCB3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBUaGlzIGJsb2NrIGJlY29tZXMgdGhlIHByZXZpb3VzIGJsb2NrXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9wcmV2QmxvY2sgPSB0aGlzQmxvY2s7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblxuXHQgICAgICAgIGZ1bmN0aW9uIHhvckJsb2NrKHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLl9pdjtcblxuXHQgICAgICAgICAgICAvLyBDaG9vc2UgbWl4aW5nIGJsb2NrXG5cdCAgICAgICAgICAgIGlmIChpdikge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gaXY7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBJViBmb3Igc3Vic2VxdWVudCBibG9ja3Ncblx0ICAgICAgICAgICAgICAgIHRoaXMuX2l2ID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gdGhpcy5fcHJldkJsb2NrO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gWE9SIGJsb2Nrc1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrU2l6ZTsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tvZmZzZXQgKyBpXSBePSBibG9ja1tpXTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBDQkM7XG5cdCAgICB9KCkpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFBhZGRpbmcgbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19wYWQgPSBDLnBhZCA9IHt9O1xuXG5cdCAgICAvKipcblx0ICAgICAqIFBLQ1MgIzUvNyBwYWRkaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgUGtjczcgPSBDX3BhZC5Qa2NzNyA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBQYWRzIGRhdGEgdXNpbmcgdGhlIGFsZ29yaXRobSBkZWZpbmVkIGluIFBLQ1MgIzUvNy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBkYXRhIFRoZSBkYXRhIHRvIHBhZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gYmxvY2tTaXplIFRoZSBtdWx0aXBsZSB0aGF0IHRoZSBkYXRhIHNob3VsZCBiZSBwYWRkZWQgdG8uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIENyeXB0b0pTLnBhZC5Qa2NzNy5wYWQod29yZEFycmF5LCA0KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBwYWRkaW5nIGJ5dGVzXG5cdCAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gYmxvY2tTaXplQnl0ZXMgLSBkYXRhLnNpZ0J5dGVzICUgYmxvY2tTaXplQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIHBhZGRpbmcgd29yZFxuXHQgICAgICAgICAgICB2YXIgcGFkZGluZ1dvcmQgPSAoblBhZGRpbmdCeXRlcyA8PCAyNCkgfCAoblBhZGRpbmdCeXRlcyA8PCAxNikgfCAoblBhZGRpbmdCeXRlcyA8PCA4KSB8IG5QYWRkaW5nQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIHBhZGRpbmdcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmdXb3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5QYWRkaW5nQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgcGFkZGluZ1dvcmRzLnB1c2gocGFkZGluZ1dvcmQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nID0gV29yZEFycmF5LmNyZWF0ZShwYWRkaW5nV29yZHMsIG5QYWRkaW5nQnl0ZXMpO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGEuY29uY2F0KHBhZGRpbmcpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBVbnBhZHMgZGF0YSB0aGF0IGhhZCBiZWVuIHBhZGRlZCB1c2luZyB0aGUgYWxnb3JpdGhtIGRlZmluZWQgaW4gUEtDUyAjNS83LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGRhdGEgVGhlIGRhdGEgdG8gdW5wYWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIENyeXB0b0pTLnBhZC5Qa2NzNy51bnBhZCh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHVucGFkOiBmdW5jdGlvbiAoZGF0YSkge1xuXHQgICAgICAgICAgICAvLyBHZXQgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgZnJvbSBsYXN0IGJ5dGVcblx0ICAgICAgICAgICAgdmFyIG5QYWRkaW5nQnl0ZXMgPSBkYXRhLndvcmRzWyhkYXRhLnNpZ0J5dGVzIC0gMSkgPj4+IDJdICYgMHhmZjtcblxuXHQgICAgICAgICAgICAvLyBSZW1vdmUgcGFkZGluZ1xuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzIC09IG5QYWRkaW5nQnl0ZXM7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBYnN0cmFjdCBiYXNlIGJsb2NrIGNpcGhlciB0ZW1wbGF0ZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgY2lwaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiA0ICgxMjggYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyID0gQ19saWIuQmxvY2tDaXBoZXIgPSBDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge01vZGV9IG1vZGUgVGhlIGJsb2NrIG1vZGUgdG8gdXNlLiBEZWZhdWx0OiBDQkNcblx0ICAgICAgICAgKiBAcHJvcGVydHkge1BhZGRpbmd9IHBhZGRpbmcgVGhlIHBhZGRpbmcgc3RyYXRlZ3kgdG8gdXNlLiBEZWZhdWx0OiBQa2NzN1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogQ2lwaGVyLmNmZy5leHRlbmQoe1xuXHQgICAgICAgICAgICBtb2RlOiBDQkMsXG5cdCAgICAgICAgICAgIHBhZGRpbmc6IFBrY3M3XG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBSZXNldCBjaXBoZXJcblx0ICAgICAgICAgICAgQ2lwaGVyLnJlc2V0LmNhbGwodGhpcyk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBjZmcgPSB0aGlzLmNmZztcblx0ICAgICAgICAgICAgdmFyIGl2ID0gY2ZnLml2O1xuXHQgICAgICAgICAgICB2YXIgbW9kZSA9IGNmZy5tb2RlO1xuXG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGJsb2NrIG1vZGVcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3hmb3JtTW9kZSA9PSB0aGlzLl9FTkNfWEZPUk1fTU9ERSkge1xuXHQgICAgICAgICAgICAgICAgdmFyIG1vZGVDcmVhdG9yID0gbW9kZS5jcmVhdGVFbmNyeXB0b3I7XG5cdCAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqLyB7XG5cdCAgICAgICAgICAgICAgICB2YXIgbW9kZUNyZWF0b3IgPSBtb2RlLmNyZWF0ZURlY3J5cHRvcjtcblx0ICAgICAgICAgICAgICAgIC8vIEtlZXAgYXQgbGVhc3Qgb25lIGJsb2NrIGluIHRoZSBidWZmZXIgZm9yIHVucGFkZGluZ1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fbWluQnVmZmVyU2l6ZSA9IDE7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBpZiAodGhpcy5fbW9kZSAmJiB0aGlzLl9tb2RlLl9fY3JlYXRvciA9PSBtb2RlQ3JlYXRvcikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fbW9kZS5pbml0KHRoaXMsIGl2ICYmIGl2LndvcmRzKTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX21vZGUgPSBtb2RlQ3JlYXRvci5jYWxsKG1vZGUsIHRoaXMsIGl2ICYmIGl2LndvcmRzKTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX21vZGUuX19jcmVhdG9yID0gbW9kZUNyZWF0b3I7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICB0aGlzLl9tb2RlLnByb2Nlc3NCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmcgPSB0aGlzLmNmZy5wYWRkaW5nO1xuXG5cdCAgICAgICAgICAgIC8vIEZpbmFsaXplXG5cdCAgICAgICAgICAgIGlmICh0aGlzLl94Zm9ybU1vZGUgPT0gdGhpcy5fRU5DX1hGT1JNX01PREUpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFBhZCBkYXRhXG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nLnBhZCh0aGlzLl9kYXRhLCB0aGlzLmJsb2NrU2l6ZSk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgICAgICB2YXIgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKCEhJ2ZsdXNoJyk7XG5cdCAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqLyB7XG5cdCAgICAgICAgICAgICAgICAvLyBQcm9jZXNzIGZpbmFsIGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkQmxvY2tzID0gdGhpcy5fcHJvY2VzcyghISdmbHVzaCcpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBVbnBhZCBkYXRhXG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nLnVucGFkKGZpbmFsUHJvY2Vzc2VkQmxvY2tzKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBmaW5hbFByb2Nlc3NlZEJsb2Nrcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgYmxvY2tTaXplOiAxMjgvMzJcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEEgY29sbGVjdGlvbiBvZiBjaXBoZXIgcGFyYW1ldGVycy5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gY2lwaGVydGV4dCBUaGUgcmF3IGNpcGhlcnRleHQuXG5cdCAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkgdG8gdGhpcyBjaXBoZXJ0ZXh0LlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IGl2IFRoZSBJViB1c2VkIGluIHRoZSBjaXBoZXJpbmcgb3BlcmF0aW9uLlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IHNhbHQgVGhlIHNhbHQgdXNlZCB3aXRoIGEga2V5IGRlcml2YXRpb24gZnVuY3Rpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge0NpcGhlcn0gYWxnb3JpdGhtIFRoZSBjaXBoZXIgYWxnb3JpdGhtLlxuXHQgICAgICogQHByb3BlcnR5IHtNb2RlfSBtb2RlIFRoZSBibG9jayBtb2RlIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge1BhZGRpbmd9IHBhZGRpbmcgVGhlIHBhZGRpbmcgc2NoZW1lIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBibG9jayBzaXplIG9mIHRoZSBjaXBoZXIuXG5cdCAgICAgKiBAcHJvcGVydHkge0Zvcm1hdH0gZm9ybWF0dGVyIFRoZSBkZWZhdWx0IGZvcm1hdHRpbmcgc3RyYXRlZ3kgdG8gY29udmVydCB0aGlzIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGEgc3RyaW5nLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ2lwaGVyUGFyYW1zID0gQ19saWIuQ2lwaGVyUGFyYW1zID0gQmFzZS5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjaXBoZXJQYXJhbXMgQW4gb2JqZWN0IHdpdGggYW55IG9mIHRoZSBwb3NzaWJsZSBjaXBoZXIgcGFyYW1ldGVycy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlclBhcmFtcyA9IENyeXB0b0pTLmxpYi5DaXBoZXJQYXJhbXMuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIGNpcGhlcnRleHQ6IGNpcGhlcnRleHRXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBrZXk6IGtleVdvcmRBcnJheSxcblx0ICAgICAgICAgKiAgICAgICAgIGl2OiBpdldvcmRBcnJheSxcblx0ICAgICAgICAgKiAgICAgICAgIHNhbHQ6IHNhbHRXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBhbGdvcml0aG06IENyeXB0b0pTLmFsZ28uQUVTLFxuXHQgICAgICAgICAqICAgICAgICAgbW9kZTogQ3J5cHRvSlMubW9kZS5DQkMsXG5cdCAgICAgICAgICogICAgICAgICBwYWRkaW5nOiBDcnlwdG9KUy5wYWQuUEtDUzcsXG5cdCAgICAgICAgICogICAgICAgICBibG9ja1NpemU6IDQsXG5cdCAgICAgICAgICogICAgICAgICBmb3JtYXR0ZXI6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMXG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjaXBoZXJQYXJhbXMpIHtcblx0ICAgICAgICAgICAgdGhpcy5taXhJbihjaXBoZXJQYXJhbXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtGb3JtYXR9IGZvcm1hdHRlciAoT3B0aW9uYWwpIFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIHVzZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIGNpcGhlciBwYXJhbXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAdGhyb3dzIEVycm9yIElmIG5laXRoZXIgdGhlIGZvcm1hdHRlciBub3IgdGhlIGRlZmF1bHQgZm9ybWF0dGVyIGlzIHNldC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IGNpcGhlclBhcmFtcyArICcnO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zLnRvU3RyaW5nKCk7XG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSBjaXBoZXJQYXJhbXMudG9TdHJpbmcoQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRvU3RyaW5nOiBmdW5jdGlvbiAoZm9ybWF0dGVyKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAoZm9ybWF0dGVyIHx8IHRoaXMuZm9ybWF0dGVyKS5zdHJpbmdpZnkodGhpcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogRm9ybWF0IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZm9ybWF0ID0gQy5mb3JtYXQgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBPcGVuU1NMIGZvcm1hdHRpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBPcGVuU1NMRm9ybWF0dGVyID0gQ19mb3JtYXQuT3BlblNTTCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc30gY2lwaGVyUGFyYW1zIFRoZSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBvcGVuU1NMU3RyaW5nID0gQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wuc3RyaW5naWZ5KGNpcGhlclBhcmFtcyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IGNpcGhlclBhcmFtcy5jaXBoZXJ0ZXh0O1xuXHQgICAgICAgICAgICB2YXIgc2FsdCA9IGNpcGhlclBhcmFtcy5zYWx0O1xuXG5cdCAgICAgICAgICAgIC8vIEZvcm1hdFxuXHQgICAgICAgICAgICBpZiAoc2FsdCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheSA9IFdvcmRBcnJheS5jcmVhdGUoWzB4NTM2MTZjNzQsIDB4NjU2NDVmNWZdKS5jb25jYXQoc2FsdCkuY29uY2F0KGNpcGhlcnRleHQpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheSA9IGNpcGhlcnRleHQ7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gd29yZEFycmF5LnRvU3RyaW5nKEJhc2U2NCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcgdG8gYSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVuU1NMU3RyIFRoZSBPcGVuU1NMLWNvbXBhdGlibGUgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgY2lwaGVyIHBhcmFtcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJQYXJhbXMgPSBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTC5wYXJzZShvcGVuU1NMU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKG9wZW5TU0xTdHIpIHtcblx0ICAgICAgICAgICAgLy8gUGFyc2UgYmFzZTY0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0ID0gQmFzZTY0LnBhcnNlKG9wZW5TU0xTdHIpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0V29yZHMgPSBjaXBoZXJ0ZXh0LndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFRlc3QgZm9yIHNhbHRcblx0ICAgICAgICAgICAgaWYgKGNpcGhlcnRleHRXb3Jkc1swXSA9PSAweDUzNjE2Yzc0ICYmIGNpcGhlcnRleHRXb3Jkc1sxXSA9PSAweDY1NjQ1ZjVmKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IHNhbHRcblx0ICAgICAgICAgICAgICAgIHZhciBzYWx0ID0gV29yZEFycmF5LmNyZWF0ZShjaXBoZXJ0ZXh0V29yZHMuc2xpY2UoMiwgNCkpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgc2FsdCBmcm9tIGNpcGhlcnRleHRcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHRXb3Jkcy5zcGxpY2UoMCwgNCk7XG5cdCAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0LnNpZ0J5dGVzIC09IDE2O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoeyBjaXBoZXJ0ZXh0OiBjaXBoZXJ0ZXh0LCBzYWx0OiBzYWx0IH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQSBjaXBoZXIgd3JhcHBlciB0aGF0IHJldHVybnMgY2lwaGVydGV4dCBhcyBhIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAqL1xuXHQgICAgdmFyIFNlcmlhbGl6YWJsZUNpcGhlciA9IENfbGliLlNlcmlhbGl6YWJsZUNpcGhlciA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0Zvcm1hdHRlcn0gZm9ybWF0IFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIGNvbnZlcnQgY2lwaGVyIHBhcmFtIG9iamVjdHMgdG8gYW5kIGZyb20gYSBzdHJpbmcuIERlZmF1bHQ6IE9wZW5TU0xcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjZmc6IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgZm9ybWF0OiBPcGVuU1NMRm9ybWF0dGVyXG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBFbmNyeXB0cyBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gZW5jcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gQSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuU2VyaWFsaXphYmxlQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsIGtleSk7XG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBtZXNzYWdlLCBrZXksIHsgaXY6IGl2IH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5TZXJpYWxpemFibGVDaXBoZXIuZW5jcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgbWVzc2FnZSwga2V5LCB7IGl2OiBpdiwgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgZW5jcnlwdG9yID0gY2lwaGVyLmNyZWF0ZUVuY3J5cHRvcihrZXksIGNmZyk7XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0ID0gZW5jcnlwdG9yLmZpbmFsaXplKG1lc3NhZ2UpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJDZmcgPSBlbmNyeXB0b3IuY2ZnO1xuXG5cdCAgICAgICAgICAgIC8vIENyZWF0ZSBhbmQgcmV0dXJuIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zXG5cdCAgICAgICAgICAgIHJldHVybiBDaXBoZXJQYXJhbXMuY3JlYXRlKHtcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHQ6IGNpcGhlcnRleHQsXG5cdCAgICAgICAgICAgICAgICBrZXk6IGtleSxcblx0ICAgICAgICAgICAgICAgIGl2OiBjaXBoZXJDZmcuaXYsXG5cdCAgICAgICAgICAgICAgICBhbGdvcml0aG06IGNpcGhlcixcblx0ICAgICAgICAgICAgICAgIG1vZGU6IGNpcGhlckNmZy5tb2RlLFxuXHQgICAgICAgICAgICAgICAgcGFkZGluZzogY2lwaGVyQ2ZnLnBhZGRpbmcsXG5cdCAgICAgICAgICAgICAgICBibG9ja1NpemU6IGNpcGhlci5ibG9ja1NpemUsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IGNmZy5mb3JtYXRcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlY3J5cHRzIHNlcmlhbGl6ZWQgY2lwaGVydGV4dC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfHN0cmluZ30gY2lwaGVydGV4dCBUaGUgY2lwaGVydGV4dCB0byBkZWNyeXB0LlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcGxhaW50ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0IHN0cmluZyB0byBDaXBoZXJQYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dCA9IHRoaXMuX3BhcnNlKGNpcGhlcnRleHQsIGNmZy5mb3JtYXQpO1xuXG5cdCAgICAgICAgICAgIC8vIERlY3J5cHRcblx0ICAgICAgICAgICAgdmFyIHBsYWludGV4dCA9IGNpcGhlci5jcmVhdGVEZWNyeXB0b3Ioa2V5LCBjZmcpLmZpbmFsaXplKGNpcGhlcnRleHQuY2lwaGVydGV4dCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHRvIENpcGhlclBhcmFtcyxcblx0ICAgICAgICAgKiBlbHNlIGFzc3VtZWQgQ2lwaGVyUGFyYW1zIGFscmVhZHkgYW5kIHJldHVybnMgY2lwaGVydGV4dCB1bmNoYW5nZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtGb3JtYXR0ZXJ9IGZvcm1hdCBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byB1c2UgdG8gcGFyc2Ugc2VyaWFsaXplZCBjaXBoZXJ0ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgdW5zZXJpYWxpemVkIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5fcGFyc2UoY2lwaGVydGV4dFN0cmluZ09yUGFyYW1zLCBmb3JtYXQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wYXJzZTogZnVuY3Rpb24gKGNpcGhlcnRleHQsIGZvcm1hdCkge1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXQucGFyc2UoY2lwaGVydGV4dCwgdGhpcyk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfa2RmID0gQy5rZGYgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBPcGVuU1NMIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uLlxuXHQgICAgICovXG5cdCAgICB2YXIgT3BlblNTTEtkZiA9IENfa2RmLk9wZW5TU0wgPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVyaXZlcyBhIGtleSBhbmQgSVYgZnJvbSBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZCB0byBkZXJpdmUgZnJvbS5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0ga2V5U2l6ZSBUaGUgc2l6ZSBpbiB3b3JkcyBvZiB0aGUga2V5IHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpdlNpemUgVGhlIHNpemUgaW4gd29yZHMgb2YgdGhlIElWIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gc2FsdCAoT3B0aW9uYWwpIEEgNjQtYml0IHNhbHQgdG8gdXNlLiBJZiBvbWl0dGVkLCBhIHNhbHQgd2lsbCBiZSBnZW5lcmF0ZWQgcmFuZG9tbHkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IEEgY2lwaGVyIHBhcmFtcyBvYmplY3Qgd2l0aCB0aGUga2V5LCBJViwgYW5kIHNhbHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMik7XG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMiwgJ3NhbHRzYWx0Jyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZXhlY3V0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBrZXlTaXplLCBpdlNpemUsIHNhbHQpIHtcblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUgcmFuZG9tIHNhbHRcblx0ICAgICAgICAgICAgaWYgKCFzYWx0KSB7XG5cdCAgICAgICAgICAgICAgICBzYWx0ID0gV29yZEFycmF5LnJhbmRvbSg2NC84KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIERlcml2ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBrZXkgPSBFdnBLREYuY3JlYXRlKHsga2V5U2l6ZToga2V5U2l6ZSArIGl2U2l6ZSB9KS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTtcblxuXHQgICAgICAgICAgICAvLyBTZXBhcmF0ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBpdiA9IFdvcmRBcnJheS5jcmVhdGUoa2V5LndvcmRzLnNsaWNlKGtleVNpemUpLCBpdlNpemUgKiA0KTtcblx0ICAgICAgICAgICAga2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gUmV0dXJuIHBhcmFtc1xuXHQgICAgICAgICAgICByZXR1cm4gQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7IGtleToga2V5LCBpdjogaXYsIHNhbHQ6IHNhbHQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBIHNlcmlhbGl6YWJsZSBjaXBoZXIgd3JhcHBlciB0aGF0IGRlcml2ZXMgdGhlIGtleSBmcm9tIGEgcGFzc3dvcmQsXG5cdCAgICAgKiBhbmQgcmV0dXJucyBjaXBoZXJ0ZXh0IGFzIGEgc2VyaWFsaXphYmxlIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICovXG5cdCAgICB2YXIgUGFzc3dvcmRCYXNlZENpcGhlciA9IENfbGliLlBhc3N3b3JkQmFzZWRDaXBoZXIgPSBTZXJpYWxpemFibGVDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0tERn0ga2RmIFRoZSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbiB0byB1c2UgdG8gZ2VuZXJhdGUgYSBrZXkgYW5kIElWIGZyb20gYSBwYXNzd29yZC4gRGVmYXVsdDogT3BlblNTTFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogU2VyaWFsaXphYmxlQ2lwaGVyLmNmZy5leHRlbmQoe1xuXHQgICAgICAgICAgICBrZGY6IE9wZW5TU0xLZGZcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEVuY3J5cHRzIGEgbWVzc2FnZSB1c2luZyBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBUaGUgY2lwaGVyIGFsZ29yaXRobSB0byB1c2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGVuY3J5cHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBBIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcpO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcsIHsgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBwYXNzd29yZCwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplKTtcblxuXHQgICAgICAgICAgICAvLyBBZGQgSVYgdG8gY29uZmlnXG5cdCAgICAgICAgICAgIGNmZy5pdiA9IGRlcml2ZWRQYXJhbXMuaXY7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IFNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0LmNhbGwodGhpcywgY2lwaGVyLCBtZXNzYWdlLCBkZXJpdmVkUGFyYW1zLmtleSwgY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBNaXggaW4gZGVyaXZlZCBwYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dC5taXhJbihkZXJpdmVkUGFyYW1zKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVjcnlwdHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHVzaW5nIGEgcGFzc3dvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQgdG8gZGVjcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmQgVGhlIHBhc3N3b3JkLlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwbGFpbnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZGVjcnlwdDogZnVuY3Rpb24gKGNpcGhlciwgY2lwaGVydGV4dCwgcGFzc3dvcmQsIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gQ2lwaGVyUGFyYW1zXG5cdCAgICAgICAgICAgIGNpcGhlcnRleHQgPSB0aGlzLl9wYXJzZShjaXBoZXJ0ZXh0LCBjZmcuZm9ybWF0KTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplLCBjaXBoZXJ0ZXh0LnNhbHQpO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBJViB0byBjb25maWdcblx0ICAgICAgICAgICAgY2ZnLml2ID0gZGVyaXZlZFBhcmFtcy5pdjtcblxuXHQgICAgICAgICAgICAvLyBEZWNyeXB0XG5cdCAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBTZXJpYWxpemFibGVDaXBoZXIuZGVjcnlwdC5jYWxsKHRoaXMsIGNpcGhlciwgY2lwaGVydGV4dCwgZGVyaXZlZFBhcmFtcy5rZXksIGNmZyk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0fSgpKTtcblxuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdHJvb3QuQ3J5cHRvSlMgPSBmYWN0b3J5KCk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuXG5cdC8qKlxuXHQgKiBDcnlwdG9KUyBjb3JlIGNvbXBvbmVudHMuXG5cdCAqL1xuXHR2YXIgQ3J5cHRvSlMgPSBDcnlwdG9KUyB8fCAoZnVuY3Rpb24gKE1hdGgsIHVuZGVmaW5lZCkge1xuXHQgICAgLypcblx0ICAgICAqIExvY2FsIHBvbHlmaWwgb2YgT2JqZWN0LmNyZWF0ZVxuXHQgICAgICovXG5cdCAgICB2YXIgY3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGZ1bmN0aW9uIEYoKSB7fTtcblxuXHQgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7XG5cdCAgICAgICAgICAgIHZhciBzdWJ0eXBlO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gb2JqO1xuXG5cdCAgICAgICAgICAgIHN1YnR5cGUgPSBuZXcgRigpO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gbnVsbDtcblxuXHQgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICB9O1xuXHQgICAgfSgpKVxuXG5cdCAgICAvKipcblx0ICAgICAqIENyeXB0b0pTIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBMaWJyYXJ5IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfbGliID0gQy5saWIgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBCYXNlIG9iamVjdCBmb3IgcHJvdG90eXBhbCBpbmhlcml0YW5jZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlID0gKGZ1bmN0aW9uICgpIHtcblxuXG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGlzIG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG92ZXJyaWRlcyBQcm9wZXJ0aWVzIHRvIGNvcHkgaW50byB0aGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiAgICAgdmFyIE15VHlwZSA9IENyeXB0b0pTLmxpYi5CYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgZmllbGQ6ICd2YWx1ZScsXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgfVxuXHQgICAgICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBleHRlbmQ6IGZ1bmN0aW9uIChvdmVycmlkZXMpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNwYXduXG5cdCAgICAgICAgICAgICAgICB2YXIgc3VidHlwZSA9IGNyZWF0ZSh0aGlzKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gQXVnbWVudFxuXHQgICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlcykge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1YnR5cGUubWl4SW4ob3ZlcnJpZGVzKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGRlZmF1bHQgaW5pdGlhbGl6ZXJcblx0ICAgICAgICAgICAgICAgIGlmICghc3VidHlwZS5oYXNPd25Qcm9wZXJ0eSgnaW5pdCcpIHx8IHRoaXMuaW5pdCA9PT0gc3VidHlwZS5pbml0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgc3VidHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlci5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZXIncyBwcm90b3R5cGUgaXMgdGhlIHN1YnR5cGUgb2JqZWN0XG5cdCAgICAgICAgICAgICAgICBzdWJ0eXBlLmluaXQucHJvdG90eXBlID0gc3VidHlwZTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVmZXJlbmNlIHN1cGVydHlwZVxuXHQgICAgICAgICAgICAgICAgc3VidHlwZS4kc3VwZXIgPSB0aGlzO1xuXG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogRXh0ZW5kcyB0aGlzIG9iamVjdCBhbmQgcnVucyB0aGUgaW5pdCBtZXRob2QuXG5cdCAgICAgICAgICAgICAqIEFyZ3VtZW50cyB0byBjcmVhdGUoKSB3aWxsIGJlIHBhc3NlZCB0byBpbml0KCkuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIG5ldyBvYmplY3QuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBpbnN0YW5jZSA9IE15VHlwZS5jcmVhdGUoKTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gdGhpcy5leHRlbmQoKTtcblx0ICAgICAgICAgICAgICAgIGluc3RhbmNlLmluaXQuYXBwbHkoaW5zdGFuY2UsIGFyZ3VtZW50cyk7XG5cblx0ICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG9iamVjdC5cblx0ICAgICAgICAgICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gYWRkIHNvbWUgbG9naWMgd2hlbiB5b3VyIG9iamVjdHMgYXJlIGNyZWF0ZWQuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICB2YXIgTXlUeXBlID0gQ3J5cHRvSlMubGliLkJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgICogICAgICAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgICAgIC8vIC4uLlxuXHQgICAgICAgICAgICAgKiAgICAgICAgIH1cblx0ICAgICAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB9LFxuXG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBDb3BpZXMgcHJvcGVydGllcyBpbnRvIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBUaGUgcHJvcGVydGllcyB0byBtaXggaW4uXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBNeVR5cGUubWl4SW4oe1xuXHQgICAgICAgICAgICAgKiAgICAgICAgIGZpZWxkOiAndmFsdWUnXG5cdCAgICAgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIG1peEluOiBmdW5jdGlvbiAocHJvcGVydGllcykge1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcGVydHlOYW1lIGluIHByb3BlcnRpZXMpIHtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcHJvcGVydHlOYW1lXSA9IHByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIC8vIElFIHdvbid0IGNvcHkgdG9TdHJpbmcgdXNpbmcgdGhlIGxvb3AgYWJvdmVcblx0ICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KCd0b1N0cmluZycpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy50b1N0cmluZyA9IHByb3BlcnRpZXMudG9TdHJpbmc7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0sXG5cblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IGluc3RhbmNlLmNsb25lKCk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5pdC5wcm90b3R5cGUuZXh0ZW5kKHRoaXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH0oKSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiAzMi1iaXQgd29yZHMuXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gc2lnQnl0ZXMgVGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBieXRlcyBpbiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgKi9cblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyAoT3B0aW9uYWwpIEFuIGFycmF5IG9mIDMyLWJpdCB3b3Jkcy5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gc2lnQnl0ZXMgKE9wdGlvbmFsKSBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoZSB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKCk7XG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbMHgwMDAxMDIwMywgMHgwNDA1MDYwN10pO1xuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoWzB4MDAwMTAyMDMsIDB4MDQwNTA2MDddLCA2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAod29yZHMsIHNpZ0J5dGVzKSB7XG5cdCAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdO1xuXG5cdCAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSBzaWdCeXRlcztcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSB3b3Jkcy5sZW5ndGggKiA0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIHRoaXMgd29yZCBhcnJheSB0byBhIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlciAoT3B0aW9uYWwpIFRoZSBlbmNvZGluZyBzdHJhdGVneSB0byB1c2UuIERlZmF1bHQ6IENyeXB0b0pTLmVuYy5IZXhcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkgKyAnJztcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IHdvcmRBcnJheS50b1N0cmluZygpO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gd29yZEFycmF5LnRvU3RyaW5nKENyeXB0b0pTLmVuYy5VdGY4KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0b1N0cmluZzogZnVuY3Rpb24gKGVuY29kZXIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIChlbmNvZGVyIHx8IEhleCkuc3RyaW5naWZ5KHRoaXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25jYXRlbmF0ZXMgYSB3b3JkIGFycmF5IHRvIHRoaXMgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheTEuY29uY2F0KHdvcmRBcnJheTIpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbmNhdDogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHRoaXNXb3JkcyA9IHRoaXMud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGF0V29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGlzU2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXHQgICAgICAgICAgICB2YXIgdGhhdFNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzXG5cdCAgICAgICAgICAgIHRoaXMuY2xhbXAoKTtcblxuXHQgICAgICAgICAgICAvLyBDb25jYXRcblx0ICAgICAgICAgICAgaWYgKHRoaXNTaWdCeXRlcyAlIDQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIENvcHkgb25lIGJ5dGUgYXQgYSB0aW1lXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoYXRTaWdCeXRlczsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHRoYXRCeXRlID0gKHRoYXRXb3Jkc1tpID4+PiAyXSA+Pj4gKDI0IC0gKGkgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpc1dvcmRzWyh0aGlzU2lnQnl0ZXMgKyBpKSA+Pj4gMl0gfD0gdGhhdEJ5dGUgPDwgKDI0IC0gKCh0aGlzU2lnQnl0ZXMgKyBpKSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBDb3B5IG9uZSB3b3JkIGF0IGEgdGltZVxuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGF0U2lnQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXNXb3Jkc1sodGhpc1NpZ0J5dGVzICsgaSkgPj4+IDJdID0gdGhhdFdvcmRzW2kgPj4+IDJdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgKz0gdGhhdFNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVtb3ZlcyBpbnNpZ25pZmljYW50IGJpdHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheS5jbGFtcCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsYW1wOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB0aGlzLndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wXG5cdCAgICAgICAgICAgIHdvcmRzW3NpZ0J5dGVzID4+PiAyXSAmPSAweGZmZmZmZmZmIDw8ICgzMiAtIChzaWdCeXRlcyAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIHdvcmRzLmxlbmd0aCA9IE1hdGguY2VpbChzaWdCeXRlcyAvIDQpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gd29yZEFycmF5LmNsb25lKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gQmFzZS5jbG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICBjbG9uZS53b3JkcyA9IHRoaXMud29yZHMuc2xpY2UoMCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgd29yZCBhcnJheSBmaWxsZWQgd2l0aCByYW5kb20gYnl0ZXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbkJ5dGVzIFRoZSBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcmFuZG9tIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSgxNik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcmFuZG9tOiBmdW5jdGlvbiAobkJ5dGVzKSB7XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXG5cdCAgICAgICAgICAgIHZhciByID0gKGZ1bmN0aW9uIChtX3cpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBtX3cgPSBtX3c7XG5cdCAgICAgICAgICAgICAgICB2YXIgbV96ID0gMHgzYWRlNjhiMTtcblx0ICAgICAgICAgICAgICAgIHZhciBtYXNrID0gMHhmZmZmZmZmZjtcblxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgICAgICBtX3ogPSAoMHg5MDY5ICogKG1feiAmIDB4RkZGRikgKyAobV96ID4+IDB4MTApKSAmIG1hc2s7XG5cdCAgICAgICAgICAgICAgICAgICAgbV93ID0gKDB4NDY1MCAqIChtX3cgJiAweEZGRkYpICsgKG1fdyA+PiAweDEwKSkgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSAoKG1feiA8PCAweDEwKSArIG1fdykgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAvPSAweDEwMDAwMDAwMDtcblx0ICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gMC41O1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgKiAoTWF0aC5yYW5kb20oKSA+IC41ID8gMSA6IC0xKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIHJjYWNoZTsgaSA8IG5CeXRlczsgaSArPSA0KSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgX3IgPSByKChyY2FjaGUgfHwgTWF0aC5yYW5kb20oKSkgKiAweDEwMDAwMDAwMCk7XG5cblx0ICAgICAgICAgICAgICAgIHJjYWNoZSA9IF9yKCkgKiAweDNhZGU2N2I3O1xuXHQgICAgICAgICAgICAgICAgd29yZHMucHVzaCgoX3IoKSAqIDB4MTAwMDAwMDAwKSB8IDApO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBXb3JkQXJyYXkuaW5pdCh3b3JkcywgbkJ5dGVzKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBFbmNvZGVyIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZW5jID0gQy5lbmMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBIZXggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBIZXggPSBDX2VuYy5IZXggPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBoZXggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGV4U3RyaW5nID0gQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IHdvcmRBcnJheS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgdmFyIGhleENoYXJzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJpdGUgPSAod29yZHNbaSA+Pj4gMl0gPj4+ICgyNCAtIChpICUgNCkgKiA4KSkgJiAweGZmO1xuXHQgICAgICAgICAgICAgICAgaGV4Q2hhcnMucHVzaCgoYml0ZSA+Pj4gNCkudG9TdHJpbmcoMTYpKTtcblx0ICAgICAgICAgICAgICAgIGhleENoYXJzLnB1c2goKGJpdGUgJiAweDBmKS50b1N0cmluZygxNikpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhleENoYXJzLmpvaW4oJycpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGhleFN0ciBUaGUgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGhleFN0cmluZyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChoZXhTdHIpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhleFN0ckxlbmd0aCA9IGhleFN0ci5sZW5ndGg7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXhTdHJMZW5ndGg7IGkgKz0gMikge1xuXHQgICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gM10gfD0gcGFyc2VJbnQoaGV4U3RyLnN1YnN0cihpLCAyKSwgMTYpIDw8ICgyNCAtIChpICUgOCkgKiA0KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQod29yZHMsIGhleFN0ckxlbmd0aCAvIDIpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogTGF0aW4xIGVuY29kaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgTGF0aW4xID0gQ19lbmMuTGF0aW4xID0ge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIExhdGluMSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgTGF0aW4xIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGxhdGluMVN0cmluZyA9IENyeXB0b0pTLmVuYy5MYXRpbjEuc3RyaW5naWZ5KHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlcztcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciBsYXRpbjFDaGFycyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBiaXRlID0gKHdvcmRzW2kgPj4+IDJdID4+PiAoMjQgLSAoaSAlIDQpICogOCkpICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIGxhdGluMUNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShiaXRlKSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbGF0aW4xQ2hhcnMuam9pbignJyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgTGF0aW4xIHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF0aW4xU3RyIFRoZSBMYXRpbjEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5MYXRpbjEucGFyc2UobGF0aW4xU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKGxhdGluMVN0cikge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgbGF0aW4xU3RyTGVuZ3RoID0gbGF0aW4xU3RyLmxlbmd0aDtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhdGluMVN0ckxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAyXSB8PSAobGF0aW4xU3RyLmNoYXJDb2RlQXQoaSkgJiAweGZmKSA8PCAoMjQgLSAoaSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBsYXRpbjFTdHJMZW5ndGgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogVVRGLTggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmOCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBVVEYtOCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgdXRmOFN0cmluZyA9IENyeXB0b0pTLmVuYy5VdGY4LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUoTGF0aW4xLnN0cmluZ2lmeSh3b3JkQXJyYXkpKSk7XG5cdCAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWFsZm9ybWVkIFVURi04IGRhdGEnKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi04IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXRmOFN0ciBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5VdGY4LnBhcnNlKHV0ZjhTdHJpbmcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmOFN0cikge1xuXHQgICAgICAgICAgICByZXR1cm4gTGF0aW4xLnBhcnNlKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudCh1dGY4U3RyKSkpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYnVmZmVyZWQgYmxvY2sgYWxnb3JpdGhtIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIFRoZSBwcm9wZXJ0eSBibG9ja1NpemUgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiBhIGNvbmNyZXRlIHN1YnR5cGUuXG5cdCAgICAgKlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9taW5CdWZmZXJTaXplIFRoZSBudW1iZXIgb2YgYmxvY2tzIHRoYXQgc2hvdWxkIGJlIGtlcHQgdW5wcm9jZXNzZWQgaW4gdGhlIGJ1ZmZlci4gRGVmYXVsdDogMFxuXHQgICAgICovXG5cdCAgICB2YXIgQnVmZmVyZWRCbG9ja0FsZ29yaXRobSA9IENfbGliLkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVzZXRzIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgZGF0YSBidWZmZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLl9kYXRhID0gbmV3IFdvcmRBcnJheS5pbml0KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX25EYXRhQnl0ZXMgPSAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBZGRzIG5ldyBkYXRhIHRvIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgYnVmZmVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGFwcGVuZC4gU3RyaW5ncyBhcmUgY29udmVydGVkIHRvIGEgV29yZEFycmF5IHVzaW5nIFVURi04LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9hcHBlbmQoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fYXBwZW5kKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2FwcGVuZDogZnVuY3Rpb24gKGRhdGEpIHtcblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIGRhdGEgPSBVdGY4LnBhcnNlKGRhdGEpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQXBwZW5kXG5cdCAgICAgICAgICAgIHRoaXMuX2RhdGEuY29uY2F0KGRhdGEpO1xuXHQgICAgICAgICAgICB0aGlzLl9uRGF0YUJ5dGVzICs9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFByb2Nlc3NlcyBhdmFpbGFibGUgZGF0YSBibG9ja3MuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIF9kb1Byb2Nlc3NCbG9jayhvZmZzZXQpLCB3aGljaCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGEgY29uY3JldGUgc3VidHlwZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9GbHVzaCBXaGV0aGVyIGFsbCBibG9ja3MgYW5kIHBhcnRpYWwgYmxvY2tzIHNob3VsZCBiZSBwcm9jZXNzZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwcm9jZXNzZWQgZGF0YS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHByb2Nlc3NlZERhdGEgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9wcm9jZXNzKCk7XG5cdCAgICAgICAgICogICAgIHZhciBwcm9jZXNzZWREYXRhID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fcHJvY2VzcyghISdmbHVzaCcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wcm9jZXNzOiBmdW5jdGlvbiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIGRhdGFTaWdCeXRlcyA9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSB0aGlzLmJsb2NrU2l6ZTtcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBibG9ja3MgcmVhZHlcblx0ICAgICAgICAgICAgdmFyIG5CbG9ja3NSZWFkeSA9IGRhdGFTaWdCeXRlcyAvIGJsb2NrU2l6ZUJ5dGVzO1xuXHQgICAgICAgICAgICBpZiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAgICAgLy8gUm91bmQgdXAgdG8gaW5jbHVkZSBwYXJ0aWFsIGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgbkJsb2Nrc1JlYWR5ID0gTWF0aC5jZWlsKG5CbG9ja3NSZWFkeSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBSb3VuZCBkb3duIHRvIGluY2x1ZGUgb25seSBmdWxsIGJsb2Nrcyxcblx0ICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhlIG51bWJlciBvZiBibG9ja3MgdGhhdCBtdXN0IHJlbWFpbiBpbiB0aGUgYnVmZmVyXG5cdCAgICAgICAgICAgICAgICBuQmxvY2tzUmVhZHkgPSBNYXRoLm1heCgobkJsb2Nrc1JlYWR5IHwgMCkgLSB0aGlzLl9taW5CdWZmZXJTaXplLCAwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIENvdW50IHdvcmRzIHJlYWR5XG5cdCAgICAgICAgICAgIHZhciBuV29yZHNSZWFkeSA9IG5CbG9ja3NSZWFkeSAqIGJsb2NrU2l6ZTtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBieXRlcyByZWFkeVxuXHQgICAgICAgICAgICB2YXIgbkJ5dGVzUmVhZHkgPSBNYXRoLm1pbihuV29yZHNSZWFkeSAqIDQsIGRhdGFTaWdCeXRlcyk7XG5cblx0ICAgICAgICAgICAgLy8gUHJvY2VzcyBibG9ja3Ncblx0ICAgICAgICAgICAgaWYgKG5Xb3Jkc1JlYWR5KSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBvZmZzZXQgPSAwOyBvZmZzZXQgPCBuV29yZHNSZWFkeTsgb2Zmc2V0ICs9IGJsb2NrU2l6ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtYWxnb3JpdGhtIGxvZ2ljXG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fZG9Qcm9jZXNzQmxvY2soZGF0YVdvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgICAgICB2YXIgcHJvY2Vzc2VkV29yZHMgPSBkYXRhV29yZHMuc3BsaWNlKDAsIG5Xb3Jkc1JlYWR5KTtcblx0ICAgICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgLT0gbkJ5dGVzUmVhZHk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQocHJvY2Vzc2VkV29yZHMsIG5CeXRlc1JlYWR5KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5jbG9uZSgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBjbG9uZSA9IEJhc2UuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2RhdGEgPSB0aGlzLl9kYXRhLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfbWluQnVmZmVyU2l6ZTogMFxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgaGFzaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBoYXNoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDE2ICg1MTIgYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBoYXNoIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaGVyID0gQ3J5cHRvSlMuYWxnby5TSEEyNTYuY3JlYXRlKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgaW5pdDogZnVuY3Rpb24gKGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXNldHMgdGhpcyBoYXNoZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGRhdGEgYnVmZmVyXG5cdCAgICAgICAgICAgIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQuY2FsbCh0aGlzKTtcblxuXHQgICAgICAgICAgICAvLyBQZXJmb3JtIGNvbmNyZXRlLWhhc2hlciBsb2dpY1xuXHQgICAgICAgICAgICB0aGlzLl9kb1Jlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFVwZGF0ZXMgdGhpcyBoYXNoZXIgd2l0aCBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgVGhlIG1lc3NhZ2UgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7SGFzaGVyfSBUaGlzIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICBoYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBBcHBlbmRcblx0ICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgaGFzaFxuXHQgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2hhaW5hYmxlXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIGhhc2ggY29tcHV0YXRpb24uXG5cdCAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSAoT3B0aW9uYWwpIEEgZmluYWwgbWVzc2FnZSB1cGRhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBGaW5hbCBtZXNzYWdlIHVwZGF0ZVxuXHQgICAgICAgICAgICBpZiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1oYXNoZXIgbG9naWNcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9kb0ZpbmFsaXplKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhhc2g7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogNTEyLzMyLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIHNob3J0Y3V0IGZ1bmN0aW9uIHRvIGEgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7SGFzaGVyfSBoYXNoZXIgVGhlIGhhc2hlciB0byBjcmVhdGUgYSBoZWxwZXIgZm9yLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIFNIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhlbHBlcihDcnlwdG9KUy5hbGdvLlNIQTI1Nik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2NyZWF0ZUhlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGNmZykge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBoYXNoZXIuaW5pdChjZmcpLmZpbmFsaXplKG1lc3NhZ2UpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgc2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZSBpbiB0aGlzIEhNQUMgaGVscGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIEhtYWNTSEEyNTYgPSBDcnlwdG9KUy5saWIuSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKENyeXB0b0pTLmFsZ28uU0hBMjU2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBfY3JlYXRlSG1hY0hlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGtleSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDX2FsZ28uSE1BQy5pbml0KGhhc2hlciwga2V5KS5maW5hbGl6ZShtZXNzYWdlKTtcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBbGdvcml0aG0gbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvID0ge307XG5cblx0ICAgIHJldHVybiBDO1xuXHR9KE1hdGgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoNDcpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgQ19lbmMgPSBDLmVuYztcblxuXHQgICAgLyoqXG5cdCAgICAgKiBCYXNlNjQgZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBCYXNlNjQgPSBDX2VuYy5CYXNlNjQgPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgQmFzZTY0IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBCYXNlNjQgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgYmFzZTY0U3RyaW5nID0gQ3J5cHRvSlMuZW5jLkJhc2U2NC5zdHJpbmdpZnkod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IHdvcmRBcnJheS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXHQgICAgICAgICAgICB2YXIgbWFwID0gdGhpcy5fbWFwO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzXG5cdCAgICAgICAgICAgIHdvcmRBcnJheS5jbGFtcCgpO1xuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgdmFyIGJhc2U2NENoYXJzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkgKz0gMykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJ5dGUxID0gKHdvcmRzW2kgPj4+IDJdICAgICAgID4+PiAoMjQgLSAoaSAlIDQpICogOCkpICAgICAgICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIHZhciBieXRlMiA9ICh3b3Jkc1soaSArIDEpID4+PiAyXSA+Pj4gKDI0IC0gKChpICsgMSkgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cdCAgICAgICAgICAgICAgICB2YXIgYnl0ZTMgPSAod29yZHNbKGkgKyAyKSA+Pj4gMl0gPj4+ICgyNCAtICgoaSArIDIpICUgNCkgKiA4KSkgJiAweGZmO1xuXG5cdCAgICAgICAgICAgICAgICB2YXIgdHJpcGxldCA9IChieXRlMSA8PCAxNikgfCAoYnl0ZTIgPDwgOCkgfCBieXRlMztcblxuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IChqIDwgNCkgJiYgKGkgKyBqICogMC43NSA8IHNpZ0J5dGVzKTsgaisrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYmFzZTY0Q2hhcnMucHVzaChtYXAuY2hhckF0KCh0cmlwbGV0ID4+PiAoNiAqICgzIC0gaikpKSAmIDB4M2YpKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nQ2hhciA9IG1hcC5jaGFyQXQoNjQpO1xuXHQgICAgICAgICAgICBpZiAocGFkZGluZ0NoYXIpIHtcblx0ICAgICAgICAgICAgICAgIHdoaWxlIChiYXNlNjRDaGFycy5sZW5ndGggJSA0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYmFzZTY0Q2hhcnMucHVzaChwYWRkaW5nQ2hhcik7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gYmFzZTY0Q2hhcnMuam9pbignJyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgQmFzZTY0IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZTY0U3RyIFRoZSBCYXNlNjQgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5CYXNlNjQucGFyc2UoYmFzZTY0U3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKGJhc2U2NFN0cikge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGJhc2U2NFN0ckxlbmd0aCA9IGJhc2U2NFN0ci5sZW5ndGg7XG5cdCAgICAgICAgICAgIHZhciBtYXAgPSB0aGlzLl9tYXA7XG5cdCAgICAgICAgICAgIHZhciByZXZlcnNlTWFwID0gdGhpcy5fcmV2ZXJzZU1hcDtcblxuXHQgICAgICAgICAgICBpZiAoIXJldmVyc2VNYXApIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXZlcnNlTWFwID0gdGhpcy5fcmV2ZXJzZU1hcCA9IFtdO1xuXHQgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWFwLmxlbmd0aDsgaisrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldmVyc2VNYXBbbWFwLmNoYXJDb2RlQXQoaildID0gajtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBJZ25vcmUgcGFkZGluZ1xuXHQgICAgICAgICAgICB2YXIgcGFkZGluZ0NoYXIgPSBtYXAuY2hhckF0KDY0KTtcblx0ICAgICAgICAgICAgaWYgKHBhZGRpbmdDaGFyKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0luZGV4ID0gYmFzZTY0U3RyLmluZGV4T2YocGFkZGluZ0NoYXIpO1xuXHQgICAgICAgICAgICAgICAgaWYgKHBhZGRpbmdJbmRleCAhPT0gLTEpIHtcblx0ICAgICAgICAgICAgICAgICAgICBiYXNlNjRTdHJMZW5ndGggPSBwYWRkaW5nSW5kZXg7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHJldHVybiBwYXJzZUxvb3AoYmFzZTY0U3RyLCBiYXNlNjRTdHJMZW5ndGgsIHJldmVyc2VNYXApO1xuXG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9tYXA6ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPSdcblx0ICAgIH07XG5cblx0ICAgIGZ1bmN0aW9uIHBhcnNlTG9vcChiYXNlNjRTdHIsIGJhc2U2NFN0ckxlbmd0aCwgcmV2ZXJzZU1hcCkge1xuXHQgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgdmFyIG5CeXRlcyA9IDA7XG5cdCAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmFzZTY0U3RyTGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgIGlmIChpICUgNCkge1xuXHQgICAgICAgICAgICAgIHZhciBiaXRzMSA9IHJldmVyc2VNYXBbYmFzZTY0U3RyLmNoYXJDb2RlQXQoaSAtIDEpXSA8PCAoKGkgJSA0KSAqIDIpO1xuXHQgICAgICAgICAgICAgIHZhciBiaXRzMiA9IHJldmVyc2VNYXBbYmFzZTY0U3RyLmNoYXJDb2RlQXQoaSldID4+PiAoNiAtIChpICUgNCkgKiAyKTtcblx0ICAgICAgICAgICAgICB3b3Jkc1tuQnl0ZXMgPj4+IDJdIHw9IChiaXRzMSB8IGJpdHMyKSA8PCAoMjQgLSAobkJ5dGVzICUgNCkgKiA4KTtcblx0ICAgICAgICAgICAgICBuQnl0ZXMrKztcblx0ICAgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgICByZXR1cm4gV29yZEFycmF5LmNyZWF0ZSh3b3JkcywgbkJ5dGVzKTtcblx0ICAgIH1cblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5lbmMuQmFzZTY0O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSg0NykpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0cmV0dXJuIENyeXB0b0pTLmVuYy5IZXg7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSg0NyksIHJlcXVpcmUoNTMpLCByZXF1aXJlKDUxKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9zaGExXCIsIFwiLi9obWFjXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblx0ICAgIHZhciBNRDUgPSBDX2FsZ28uTUQ1O1xuXG5cdCAgICAvKipcblx0ICAgICAqIFRoaXMga2V5IGRlcml2YXRpb24gZnVuY3Rpb24gaXMgbWVhbnQgdG8gY29uZm9ybSB3aXRoIEVWUF9CeXRlc1RvS2V5LlxuXHQgICAgICogd3d3Lm9wZW5zc2wub3JnL2RvY3MvY3J5cHRvL0VWUF9CeXRlc1RvS2V5Lmh0bWxcblx0ICAgICAqL1xuXHQgICAgdmFyIEV2cEtERiA9IENfYWxnby5FdnBLREYgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGtleVNpemUgVGhlIGtleSBzaXplIGluIHdvcmRzIHRvIGdlbmVyYXRlLiBEZWZhdWx0OiA0ICgxMjggYml0cylcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuIERlZmF1bHQ6IE1ENVxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpdGVyYXRpb25zIFRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucyB0byBwZXJmb3JtLiBEZWZhdWx0OiAxXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgIGtleVNpemU6IDEyOC8zMixcblx0ICAgICAgICAgICAgaGFzaGVyOiBNRDUsXG5cdCAgICAgICAgICAgIGl0ZXJhdGlvbnM6IDFcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhlIGRlcml2YXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoKTtcblx0ICAgICAgICAgKiAgICAgdmFyIGtkZiA9IENyeXB0b0pTLmFsZ28uRXZwS0RGLmNyZWF0ZSh7IGtleVNpemU6IDggfSk7XG5cdCAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjZmcpIHtcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVyaXZlcyBhIGtleSBmcm9tIGEgcGFzc3dvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBrZXkgPSBrZGYuY29tcHV0ZShwYXNzd29yZCwgc2FsdCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY29tcHV0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjZmcgPSB0aGlzLmNmZztcblxuXHQgICAgICAgICAgICAvLyBJbml0IGhhc2hlclxuXHQgICAgICAgICAgICB2YXIgaGFzaGVyID0gY2ZnLmhhc2hlci5jcmVhdGUoKTtcblxuXHQgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB2YXIgZGVyaXZlZEtleSA9IFdvcmRBcnJheS5jcmVhdGUoKTtcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRLZXlXb3JkcyA9IGRlcml2ZWRLZXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBrZXlTaXplID0gY2ZnLmtleVNpemU7XG5cdCAgICAgICAgICAgIHZhciBpdGVyYXRpb25zID0gY2ZnLml0ZXJhdGlvbnM7XG5cblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUga2V5XG5cdCAgICAgICAgICAgIHdoaWxlIChkZXJpdmVkS2V5V29yZHMubGVuZ3RoIDwga2V5U2l6ZSkge1xuXHQgICAgICAgICAgICAgICAgaWYgKGJsb2NrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaGFzaGVyLnVwZGF0ZShibG9jayk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB2YXIgYmxvY2sgPSBoYXNoZXIudXBkYXRlKHBhc3N3b3JkKS5maW5hbGl6ZShzYWx0KTtcblx0ICAgICAgICAgICAgICAgIGhhc2hlci5yZXNldCgpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBJdGVyYXRpb25zXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGl0ZXJhdGlvbnM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIGJsb2NrID0gaGFzaGVyLmZpbmFsaXplKGJsb2NrKTtcblx0ICAgICAgICAgICAgICAgICAgICBoYXNoZXIucmVzZXQoKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgZGVyaXZlZEtleS5jb25jYXQoYmxvY2spO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGRlcml2ZWRLZXkuc2lnQnl0ZXMgPSBrZXlTaXplICogNDtcblxuXHQgICAgICAgICAgICByZXR1cm4gZGVyaXZlZEtleTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXJpdmVzIGEga2V5IGZyb20gYSBwYXNzd29yZC5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gc2FsdCBBIHNhbHQuXG5cdCAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgY29tcHV0YXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBrZXkgPSBDcnlwdG9KUy5FdnBLREYocGFzc3dvcmQsIHNhbHQpO1xuXHQgICAgICogICAgIHZhciBrZXkgPSBDcnlwdG9KUy5FdnBLREYocGFzc3dvcmQsIHNhbHQsIHsga2V5U2l6ZTogOCB9KTtcblx0ICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDgsIGl0ZXJhdGlvbnM6IDEwMDAgfSk7XG5cdCAgICAgKi9cblx0ICAgIEMuRXZwS0RGID0gZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0LCBjZmcpIHtcblx0ICAgICAgICByZXR1cm4gRXZwS0RGLmNyZWF0ZShjZmcpLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpO1xuXHQgICAgfTtcblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5FdnBLREY7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKDQ3KSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgQ19lbmMgPSBDLmVuYztcblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmODtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8qKlxuXHQgICAgICogSE1BQyBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBITUFDID0gQ19hbGdvLkhNQUMgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIEhNQUMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBobWFjSGFzaGVyID0gQ3J5cHRvSlMuYWxnby5ITUFDLmNyZWF0ZShDcnlwdG9KUy5hbGdvLlNIQTI1Niwga2V5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoaGFzaGVyLCBrZXkpIHtcblx0ICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXJcblx0ICAgICAgICAgICAgaGFzaGVyID0gdGhpcy5faGFzaGVyID0gbmV3IGhhc2hlci5pbml0KCk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGtleSA9PSAnc3RyaW5nJykge1xuXHQgICAgICAgICAgICAgICAga2V5ID0gVXRmOC5wYXJzZShrZXkpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBoYXNoZXJCbG9ja1NpemUgPSBoYXNoZXIuYmxvY2tTaXplO1xuXHQgICAgICAgICAgICB2YXIgaGFzaGVyQmxvY2tTaXplQnl0ZXMgPSBoYXNoZXJCbG9ja1NpemUgKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEFsbG93IGFyYml0cmFyeSBsZW5ndGgga2V5c1xuXHQgICAgICAgICAgICBpZiAoa2V5LnNpZ0J5dGVzID4gaGFzaGVyQmxvY2tTaXplQnl0ZXMpIHtcblx0ICAgICAgICAgICAgICAgIGtleSA9IGhhc2hlci5maW5hbGl6ZShrZXkpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQ2xhbXAgZXhjZXNzIGJpdHNcblx0ICAgICAgICAgICAga2V5LmNsYW1wKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2xvbmUga2V5IGZvciBpbm5lciBhbmQgb3V0ZXIgcGFkc1xuXHQgICAgICAgICAgICB2YXIgb0tleSA9IHRoaXMuX29LZXkgPSBrZXkuY2xvbmUoKTtcblx0ICAgICAgICAgICAgdmFyIGlLZXkgPSB0aGlzLl9pS2V5ID0ga2V5LmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBvS2V5V29yZHMgPSBvS2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgaUtleVdvcmRzID0gaUtleS53b3JkcztcblxuXHQgICAgICAgICAgICAvLyBYT1Iga2V5cyB3aXRoIHBhZCBjb25zdGFudHNcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoZXJCbG9ja1NpemU7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgb0tleVdvcmRzW2ldIF49IDB4NWM1YzVjNWM7XG5cdCAgICAgICAgICAgICAgICBpS2V5V29yZHNbaV0gXj0gMHgzNjM2MzYzNjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBvS2V5LnNpZ0J5dGVzID0gaUtleS5zaWdCeXRlcyA9IGhhc2hlckJsb2NrU2l6ZUJ5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFJlc2V0cyB0aGlzIEhNQUMgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgaGFzaGVyID0gdGhpcy5faGFzaGVyO1xuXG5cdCAgICAgICAgICAgIC8vIFJlc2V0XG5cdCAgICAgICAgICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAgICBoYXNoZXIudXBkYXRlKHRoaXMuX2lLZXkpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBVcGRhdGVzIHRoaXMgSE1BQyB3aXRoIGEgbWVzc2FnZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSBUaGUgbWVzc2FnZSB0byBhcHBlbmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtITUFDfSBUaGlzIEhNQUMgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKCdtZXNzYWdlJyk7XG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoZXIudXBkYXRlKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRmluYWxpemVzIHRoZSBITUFDIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqIE5vdGUgdGhhdCB0aGUgZmluYWxpemUgb3BlcmF0aW9uIGlzIGVmZmVjdGl2ZWx5IGEgZGVzdHJ1Y3RpdmUsIHJlYWQtb25jZSBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgKE9wdGlvbmFsKSBBIGZpbmFsIG1lc3NhZ2UgdXBkYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBobWFjSGFzaGVyLmZpbmFsaXplKCk7XG5cdCAgICAgICAgICogICAgIHZhciBobWFjID0gaG1hY0hhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaG1hYyA9IGhtYWNIYXNoZXIuZmluYWxpemUod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmaW5hbGl6ZTogZnVuY3Rpb24gKG1lc3NhZ2VVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhhc2hlciA9IHRoaXMuX2hhc2hlcjtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIEhNQUNcblx0ICAgICAgICAgICAgdmFyIGlubmVySGFzaCA9IGhhc2hlci5maW5hbGl6ZShtZXNzYWdlVXBkYXRlKTtcblx0ICAgICAgICAgICAgaGFzaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICAgIHZhciBobWFjID0gaGFzaGVyLmZpbmFsaXplKHRoaXMuX29LZXkuY2xvbmUoKS5jb25jYXQoaW5uZXJIYXNoKSk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhtYWM7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdH0oKSk7XG5cblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoNDcpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoTWF0aCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlcjtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8vIENvbnN0YW50cyB0YWJsZVxuXHQgICAgdmFyIFQgPSBbXTtcblxuXHQgICAgLy8gQ29tcHV0ZSBjb25zdGFudHNcblx0ICAgIChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA2NDsgaSsrKSB7XG5cdCAgICAgICAgICAgIFRbaV0gPSAoTWF0aC5hYnMoTWF0aC5zaW4oaSArIDEpKSAqIDB4MTAwMDAwMDAwKSB8IDA7XG5cdCAgICAgICAgfVxuXHQgICAgfSgpKTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBNRDUgaGFzaCBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBNRDUgPSBDX2FsZ28uTUQ1ID0gSGFzaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbXG5cdCAgICAgICAgICAgICAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LFxuXHQgICAgICAgICAgICAgICAgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3NlxuXHQgICAgICAgICAgICBdKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIC8vIFN3YXAgZW5kaWFuXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0X2kgPSBvZmZzZXQgKyBpO1xuXHQgICAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0X2kgPSBNW29mZnNldF9pXTtcblxuXHQgICAgICAgICAgICAgICAgTVtvZmZzZXRfaV0gPSAoXG5cdCAgICAgICAgICAgICAgICAgICAgKCgoTV9vZmZzZXRfaSA8PCA4KSAgfCAoTV9vZmZzZXRfaSA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICAgICAoKChNX29mZnNldF9pIDw8IDI0KSB8IChNX29mZnNldF9pID4+PiA4KSkgICYgMHhmZjAwZmYwMClcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIEggPSB0aGlzLl9oYXNoLndvcmRzO1xuXG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8wICA9IE1bb2Zmc2V0ICsgMF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xICA9IE1bb2Zmc2V0ICsgMV07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8yICA9IE1bb2Zmc2V0ICsgMl07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8zICA9IE1bb2Zmc2V0ICsgM107XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF80ICA9IE1bb2Zmc2V0ICsgNF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF81ICA9IE1bb2Zmc2V0ICsgNV07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF82ICA9IE1bb2Zmc2V0ICsgNl07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF83ICA9IE1bb2Zmc2V0ICsgN107XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF84ICA9IE1bb2Zmc2V0ICsgOF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF85ICA9IE1bb2Zmc2V0ICsgOV07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xMCA9IE1bb2Zmc2V0ICsgMTBdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTEgPSBNW29mZnNldCArIDExXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEyID0gTVtvZmZzZXQgKyAxMl07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xMyA9IE1bb2Zmc2V0ICsgMTNdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTQgPSBNW29mZnNldCArIDE0XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzE1ID0gTVtvZmZzZXQgKyAxNV07XG5cblx0ICAgICAgICAgICAgLy8gV29ya2luZyB2YXJpYWxiZXNcblx0ICAgICAgICAgICAgdmFyIGEgPSBIWzBdO1xuXHQgICAgICAgICAgICB2YXIgYiA9IEhbMV07XG5cdCAgICAgICAgICAgIHZhciBjID0gSFsyXTtcblx0ICAgICAgICAgICAgdmFyIGQgPSBIWzNdO1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGF0aW9uXG5cdCAgICAgICAgICAgIGEgPSBGRihhLCBiLCBjLCBkLCBNX29mZnNldF8wLCAgNywgIFRbMF0pO1xuXHQgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMSwgIDEyLCBUWzFdKTtcblx0ICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzIsICAxNywgVFsyXSk7XG5cdCAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8zLCAgMjIsIFRbM10pO1xuXHQgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfNCwgIDcsICBUWzRdKTtcblx0ICAgICAgICAgICAgZCA9IEZGKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzUsICAxMiwgVFs1XSk7XG5cdCAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF82LCAgMTcsIFRbNl0pO1xuXHQgICAgICAgICAgICBiID0gRkYoYiwgYywgZCwgYSwgTV9vZmZzZXRfNywgIDIyLCBUWzddKTtcblx0ICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzgsICA3LCAgVFs4XSk7XG5cdCAgICAgICAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBNX29mZnNldF85LCAgMTIsIFRbOV0pO1xuXHQgICAgICAgICAgICBjID0gRkYoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTAsIDE3LCBUWzEwXSk7XG5cdCAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8xMSwgMjIsIFRbMTFdKTtcblx0ICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEyLCA3LCAgVFsxMl0pO1xuXHQgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTMsIDEyLCBUWzEzXSk7XG5cdCAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF8xNCwgMTcsIFRbMTRdKTtcblx0ICAgICAgICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzE1LCAyMiwgVFsxNV0pO1xuXG5cdCAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF8xLCAgNSwgIFRbMTZdKTtcblx0ICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzYsICA5LCAgVFsxN10pO1xuXHQgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfMTEsIDE0LCBUWzE4XSk7XG5cdCAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF8wLCAgMjAsIFRbMTldKTtcblx0ICAgICAgICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzUsICA1LCAgVFsyMF0pO1xuXHQgICAgICAgICAgICBkID0gR0coZCwgYSwgYiwgYywgTV9vZmZzZXRfMTAsIDksICBUWzIxXSk7XG5cdCAgICAgICAgICAgIGMgPSBHRyhjLCBkLCBhLCBiLCBNX29mZnNldF8xNSwgMTQsIFRbMjJdKTtcblx0ICAgICAgICAgICAgYiA9IEdHKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzQsICAyMCwgVFsyM10pO1xuXHQgICAgICAgICAgICBhID0gR0coYSwgYiwgYywgZCwgTV9vZmZzZXRfOSwgIDUsICBUWzI0XSk7XG5cdCAgICAgICAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBNX29mZnNldF8xNCwgOSwgIFRbMjVdKTtcblx0ICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzMsICAxNCwgVFsyNl0pO1xuXHQgICAgICAgICAgICBiID0gR0coYiwgYywgZCwgYSwgTV9vZmZzZXRfOCwgIDIwLCBUWzI3XSk7XG5cdCAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF8xMywgNSwgIFRbMjhdKTtcblx0ICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzIsICA5LCAgVFsyOV0pO1xuXHQgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfNywgIDE0LCBUWzMwXSk7XG5cdCAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF8xMiwgMjAsIFRbMzFdKTtcblxuXHQgICAgICAgICAgICBhID0gSEgoYSwgYiwgYywgZCwgTV9vZmZzZXRfNSwgIDQsICBUWzMyXSk7XG5cdCAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF84LCAgMTEsIFRbMzNdKTtcblx0ICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzExLCAxNiwgVFszNF0pO1xuXHQgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfMTQsIDIzLCBUWzM1XSk7XG5cdCAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF8xLCAgNCwgIFRbMzZdKTtcblx0ICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzQsICAxMSwgVFszN10pO1xuXHQgICAgICAgICAgICBjID0gSEgoYywgZCwgYSwgYiwgTV9vZmZzZXRfNywgIDE2LCBUWzM4XSk7XG5cdCAgICAgICAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBNX29mZnNldF8xMCwgMjMsIFRbMzldKTtcblx0ICAgICAgICAgICAgYSA9IEhIKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEzLCA0LCAgVFs0MF0pO1xuXHQgICAgICAgICAgICBkID0gSEgoZCwgYSwgYiwgYywgTV9vZmZzZXRfMCwgIDExLCBUWzQxXSk7XG5cdCAgICAgICAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBNX29mZnNldF8zLCAgMTYsIFRbNDJdKTtcblx0ICAgICAgICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzYsICAyMywgVFs0M10pO1xuXHQgICAgICAgICAgICBhID0gSEgoYSwgYiwgYywgZCwgTV9vZmZzZXRfOSwgIDQsICBUWzQ0XSk7XG5cdCAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF8xMiwgMTEsIFRbNDVdKTtcblx0ICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE1LCAxNiwgVFs0Nl0pO1xuXHQgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfMiwgIDIzLCBUWzQ3XSk7XG5cblx0ICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzAsICA2LCAgVFs0OF0pO1xuXHQgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfNywgIDEwLCBUWzQ5XSk7XG5cdCAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8xNCwgMTUsIFRbNTBdKTtcblx0ICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzUsICAyMSwgVFs1MV0pO1xuXHQgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTIsIDYsICBUWzUyXSk7XG5cdCAgICAgICAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBNX29mZnNldF8zLCAgMTAsIFRbNTNdKTtcblx0ICAgICAgICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzEwLCAxNSwgVFs1NF0pO1xuXHQgICAgICAgICAgICBiID0gSUkoYiwgYywgZCwgYSwgTV9vZmZzZXRfMSwgIDIxLCBUWzU1XSk7XG5cdCAgICAgICAgICAgIGEgPSBJSShhLCBiLCBjLCBkLCBNX29mZnNldF84LCAgNiwgIFRbNTZdKTtcblx0ICAgICAgICAgICAgZCA9IElJKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzE1LCAxMCwgVFs1N10pO1xuXHQgICAgICAgICAgICBjID0gSUkoYywgZCwgYSwgYiwgTV9vZmZzZXRfNiwgIDE1LCBUWzU4XSk7XG5cdCAgICAgICAgICAgIGIgPSBJSShiLCBjLCBkLCBhLCBNX29mZnNldF8xMywgMjEsIFRbNTldKTtcblx0ICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzQsICA2LCAgVFs2MF0pO1xuXHQgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTEsIDEwLCBUWzYxXSk7XG5cdCAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8yLCAgMTUsIFRbNjJdKTtcblx0ICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzksICAyMSwgVFs2M10pO1xuXG5cdCAgICAgICAgICAgIC8vIEludGVybWVkaWF0ZSBoYXNoIHZhbHVlXG5cdCAgICAgICAgICAgIEhbMF0gPSAoSFswXSArIGEpIHwgMDtcblx0ICAgICAgICAgICAgSFsxXSA9IChIWzFdICsgYikgfCAwO1xuXHQgICAgICAgICAgICBIWzJdID0gKEhbMl0gKyBjKSB8IDA7XG5cdCAgICAgICAgICAgIEhbM10gPSAoSFszXSArIGQpIHwgMDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTtcblx0ICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7XG5cblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWwgPSB0aGlzLl9uRGF0YUJ5dGVzICogODtcblx0ICAgICAgICAgICAgdmFyIG5CaXRzTGVmdCA9IGRhdGEuc2lnQnl0ZXMgKiA4O1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1tuQml0c0xlZnQgPj4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbkJpdHNMZWZ0ICUgMzIpO1xuXG5cdCAgICAgICAgICAgIHZhciBuQml0c1RvdGFsSCA9IE1hdGguZmxvb3IobkJpdHNUb3RhbCAvIDB4MTAwMDAwMDAwKTtcblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWxMID0gbkJpdHNUb3RhbDtcblx0ICAgICAgICAgICAgZGF0YVdvcmRzWygoKG5CaXRzTGVmdCArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNV0gPSAoXG5cdCAgICAgICAgICAgICAgICAoKChuQml0c1RvdGFsSCA8PCA4KSAgfCAobkJpdHNUb3RhbEggPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG5cdCAgICAgICAgICAgICAgICAoKChuQml0c1RvdGFsSCA8PCAyNCkgfCAobkJpdHNUb3RhbEggPj4+IDgpKSAgJiAweGZmMDBmZjAwKVxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IChcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxMIDw8IDgpICB8IChuQml0c1RvdGFsTCA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxMIDw8IDI0KSB8IChuQml0c1RvdGFsTCA+Pj4gOCkpICAmIDB4ZmYwMGZmMDApXG5cdCAgICAgICAgICAgICk7XG5cblx0ICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IChkYXRhV29yZHMubGVuZ3RoICsgMSkgKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEhhc2ggZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTtcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoO1xuXHQgICAgICAgICAgICB2YXIgSCA9IGhhc2gud29yZHM7XG5cblx0ICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgICAgICB2YXIgSF9pID0gSFtpXTtcblxuXHQgICAgICAgICAgICAgICAgSFtpXSA9ICgoKEhfaSA8PCA4KSAgfCAoSF9pID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICAgICgoKEhfaSA8PCAyNCkgfCAoSF9pID4+PiA4KSkgICYgMHhmZjAwZmYwMCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaFxuXHQgICAgICAgICAgICByZXR1cm4gaGFzaDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gSGFzaGVyLmNsb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBjbG9uZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgZnVuY3Rpb24gRkYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArICgoYiAmIGMpIHwgKH5iICYgZCkpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gR0coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArICgoYiAmIGQpIHwgKGMgJiB+ZCkpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gSEgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArIChiIF4gYyBeIGQpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gSUkoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArIChjIF4gKGIgfCB+ZCkpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLk1ENSgnbWVzc2FnZScpO1xuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuTUQ1KHdvcmRBcnJheSk7XG5cdCAgICAgKi9cblx0ICAgIEMuTUQ1ID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoTUQ1KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNNRDUobWVzc2FnZSwga2V5KTtcblx0ICAgICAqL1xuXHQgICAgQy5IbWFjTUQ1ID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKE1ENSk7XG5cdH0oTWF0aCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLk1ENTtcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoNDcpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyO1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblxuXHQgICAgLy8gUmV1c2FibGUgb2JqZWN0XG5cdCAgICB2YXIgVyA9IFtdO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNIQS0xIGhhc2ggYWxnb3JpdGhtLlxuXHQgICAgICovXG5cdCAgICB2YXIgU0hBMSA9IENfYWxnby5TSEExID0gSGFzaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbXG5cdCAgICAgICAgICAgICAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LFxuXHQgICAgICAgICAgICAgICAgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3Nixcblx0ICAgICAgICAgICAgICAgIDB4YzNkMmUxZjBcblx0ICAgICAgICAgICAgXSk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgSCA9IHRoaXMuX2hhc2gud29yZHM7XG5cblx0ICAgICAgICAgICAgLy8gV29ya2luZyB2YXJpYWJsZXNcblx0ICAgICAgICAgICAgdmFyIGEgPSBIWzBdO1xuXHQgICAgICAgICAgICB2YXIgYiA9IEhbMV07XG5cdCAgICAgICAgICAgIHZhciBjID0gSFsyXTtcblx0ICAgICAgICAgICAgdmFyIGQgPSBIWzNdO1xuXHQgICAgICAgICAgICB2YXIgZSA9IEhbNF07XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0YXRpb25cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4MDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoaSA8IDE2KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgV1tpXSA9IE1bb2Zmc2V0ICsgaV0gfCAwO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgbiA9IFdbaSAtIDNdIF4gV1tpIC0gOF0gXiBXW2kgLSAxNF0gXiBXW2kgLSAxNl07XG5cdCAgICAgICAgICAgICAgICAgICAgV1tpXSA9IChuIDw8IDEpIHwgKG4gPj4+IDMxKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgdmFyIHQgPSAoKGEgPDwgNSkgfCAoYSA+Pj4gMjcpKSArIGUgKyBXW2ldO1xuXHQgICAgICAgICAgICAgICAgaWYgKGkgPCAyMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHQgKz0gKChiICYgYykgfCAofmIgJiBkKSkgKyAweDVhODI3OTk5O1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpIDwgNDApIHtcblx0ICAgICAgICAgICAgICAgICAgICB0ICs9IChiIF4gYyBeIGQpICsgMHg2ZWQ5ZWJhMTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDYwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdCArPSAoKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpKSAtIDB4NzBlNDQzMjQ7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2UgLyogaWYgKGkgPCA4MCkgKi8ge1xuXHQgICAgICAgICAgICAgICAgICAgIHQgKz0gKGIgXiBjIF4gZCkgLSAweDM1OWQzZTJhO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICBlID0gZDtcblx0ICAgICAgICAgICAgICAgIGQgPSBjO1xuXHQgICAgICAgICAgICAgICAgYyA9IChiIDw8IDMwKSB8IChiID4+PiAyKTtcblx0ICAgICAgICAgICAgICAgIGIgPSBhO1xuXHQgICAgICAgICAgICAgICAgYSA9IHQ7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBJbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZVxuXHQgICAgICAgICAgICBIWzBdID0gKEhbMF0gKyBhKSB8IDA7XG5cdCAgICAgICAgICAgIEhbMV0gPSAoSFsxXSArIGIpIHwgMDtcblx0ICAgICAgICAgICAgSFsyXSA9IChIWzJdICsgYykgfCAwO1xuXHQgICAgICAgICAgICBIWzNdID0gKEhbM10gKyBkKSB8IDA7XG5cdCAgICAgICAgICAgIEhbNF0gPSAoSFs0XSArIGUpIHwgMDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTtcblx0ICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7XG5cblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWwgPSB0aGlzLl9uRGF0YUJ5dGVzICogODtcblx0ICAgICAgICAgICAgdmFyIG5CaXRzTGVmdCA9IGRhdGEuc2lnQnl0ZXMgKiA4O1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1tuQml0c0xlZnQgPj4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbkJpdHNMZWZ0ICUgMzIpO1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IE1hdGguZmxvb3IobkJpdHNUb3RhbCAvIDB4MTAwMDAwMDAwKTtcblx0ICAgICAgICAgICAgZGF0YVdvcmRzWygoKG5CaXRzTGVmdCArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNV0gPSBuQml0c1RvdGFsO1xuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzID0gZGF0YVdvcmRzLmxlbmd0aCAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gSGFzaCBmaW5hbCBibG9ja3Ncblx0ICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpO1xuXG5cdCAgICAgICAgICAgIC8vIFJldHVybiBmaW5hbCBjb21wdXRlZCBoYXNoXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYXNoO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2hhc2ggPSB0aGlzLl9oYXNoLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMSgnbWVzc2FnZScpO1xuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMSh3b3JkQXJyYXkpO1xuXHQgICAgICovXG5cdCAgICBDLlNIQTEgPSBIYXNoZXIuX2NyZWF0ZUhlbHBlcihTSEExKTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNTSEExKG1lc3NhZ2UsIGtleSk7XG5cdCAgICAgKi9cblx0ICAgIEMuSG1hY1NIQTEgPSBIYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoU0hBMSk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuU0hBMTtcblxufSkpOyIsInZhciBwU2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgb2JqZWN0S2V5cyA9IHJlcXVpcmUoNTYpO1xudmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSg1NSk7XG5cbnZhciBkZWVwRXF1YWwgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChhY3R1YWwsIGV4cGVjdGVkLCBvcHRzKSB7XG4gIGlmICghb3B0cykgb3B0cyA9IHt9O1xuICAvLyA3LjEuIEFsbCBpZGVudGljYWwgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcblxuICB9IGVsc2UgaWYgKGFjdHVhbCBpbnN0YW5jZW9mIERhdGUgJiYgZXhwZWN0ZWQgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5nZXRUaW1lKCkgPT09IGV4cGVjdGVkLmdldFRpbWUoKTtcblxuICAvLyA3LjMuIE90aGVyIHBhaXJzIHRoYXQgZG8gbm90IGJvdGggcGFzcyB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcsXG4gIC8vIGVxdWl2YWxlbmNlIGlzIGRldGVybWluZWQgYnkgPT0uXG4gIH0gZWxzZSBpZiAoIWFjdHVhbCB8fCAhZXhwZWN0ZWQgfHwgdHlwZW9mIGFjdHVhbCAhPSAnb2JqZWN0JyAmJiB0eXBlb2YgZXhwZWN0ZWQgIT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gb3B0cy5zdHJpY3QgPyBhY3R1YWwgPT09IGV4cGVjdGVkIDogYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIDcuNC4gRm9yIGFsbCBvdGhlciBPYmplY3QgcGFpcnMsIGluY2x1ZGluZyBBcnJheSBvYmplY3RzLCBlcXVpdmFsZW5jZSBpc1xuICAvLyBkZXRlcm1pbmVkIGJ5IGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoYXMgdmVyaWZpZWRcbiAgLy8gd2l0aCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwpLCB0aGUgc2FtZSBzZXQgb2Yga2V5c1xuICAvLyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSwgZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5XG4gIC8vIGNvcnJlc3BvbmRpbmcga2V5LCBhbmQgYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LiBOb3RlOiB0aGlzXG4gIC8vIGFjY291bnRzIGZvciBib3RoIG5hbWVkIGFuZCBpbmRleGVkIHByb3BlcnRpZXMgb24gQXJyYXlzLlxuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmpFcXVpdihhY3R1YWwsIGV4cGVjdGVkLCBvcHRzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZE9yTnVsbCh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNCdWZmZXIgKHgpIHtcbiAgaWYgKCF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0JyB8fCB0eXBlb2YgeC5sZW5ndGggIT09ICdudW1iZXInKSByZXR1cm4gZmFsc2U7XG4gIGlmICh0eXBlb2YgeC5jb3B5ICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiB4LnNsaWNlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh4Lmxlbmd0aCA+IDAgJiYgdHlwZW9mIHhbMF0gIT09ICdudW1iZXInKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBvYmpFcXVpdihhLCBiLCBvcHRzKSB7XG4gIHZhciBpLCBrZXk7XG4gIGlmIChpc1VuZGVmaW5lZE9yTnVsbChhKSB8fCBpc1VuZGVmaW5lZE9yTnVsbChiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS5cbiAgaWYgKGEucHJvdG90eXBlICE9PSBiLnByb3RvdHlwZSkgcmV0dXJuIGZhbHNlO1xuICAvL35+fkkndmUgbWFuYWdlZCB0byBicmVhayBPYmplY3Qua2V5cyB0aHJvdWdoIHNjcmV3eSBhcmd1bWVudHMgcGFzc2luZy5cbiAgLy8gICBDb252ZXJ0aW5nIHRvIGFycmF5IHNvbHZlcyB0aGUgcHJvYmxlbS5cbiAgaWYgKGlzQXJndW1lbnRzKGEpKSB7XG4gICAgaWYgKCFpc0FyZ3VtZW50cyhiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBkZWVwRXF1YWwoYSwgYiwgb3B0cyk7XG4gIH1cbiAgaWYgKGlzQnVmZmVyKGEpKSB7XG4gICAgaWYgKCFpc0J1ZmZlcihiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhW2ldICE9PSBiW2ldKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHRyeSB7XG4gICAgdmFyIGthID0gb2JqZWN0S2V5cyhhKSxcbiAgICAgICAga2IgPSBvYmplY3RLZXlzKGIpO1xuICB9IGNhdGNoIChlKSB7Ly9oYXBwZW5zIHdoZW4gb25lIGlzIGEgc3RyaW5nIGxpdGVyYWwgYW5kIHRoZSBvdGhlciBpc24ndFxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGtleXMgaW5jb3Jwb3JhdGVzXG4gIC8vIGhhc093blByb3BlcnR5KVxuICBpZiAoa2EubGVuZ3RoICE9IGtiLmxlbmd0aClcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vdGhlIHNhbWUgc2V0IG9mIGtleXMgKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksXG4gIGthLnNvcnQoKTtcbiAga2Iuc29ydCgpO1xuICAvL35+fmNoZWFwIGtleSB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGthW2ldICE9IGtiW2ldKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5IGNvcnJlc3BvbmRpbmcga2V5LCBhbmRcbiAgLy9+fn5wb3NzaWJseSBleHBlbnNpdmUgZGVlcCB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5ID0ga2FbaV07XG4gICAgaWYgKCFkZWVwRXF1YWwoYVtrZXldLCBiW2tleV0sIG9wdHMpKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHR5cGVvZiBhID09PSB0eXBlb2YgYjtcbn1cbiIsInZhciBzdXBwb3J0c0FyZ3VtZW50c0NsYXNzID0gKGZ1bmN0aW9uKCl7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJndW1lbnRzKVxufSkoKSA9PSAnW29iamVjdCBBcmd1bWVudHNdJztcblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gc3VwcG9ydHNBcmd1bWVudHNDbGFzcyA/IHN1cHBvcnRlZCA6IHVuc3VwcG9ydGVkO1xuXG5leHBvcnRzLnN1cHBvcnRlZCA9IHN1cHBvcnRlZDtcbmZ1bmN0aW9uIHN1cHBvcnRlZChvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xufTtcblxuZXhwb3J0cy51bnN1cHBvcnRlZCA9IHVuc3VwcG9ydGVkO1xuZnVuY3Rpb24gdW5zdXBwb3J0ZWQob2JqZWN0KXtcbiAgcmV0dXJuIG9iamVjdCAmJlxuICAgIHR5cGVvZiBvYmplY3QgPT0gJ29iamVjdCcgJiZcbiAgICB0eXBlb2Ygb2JqZWN0Lmxlbmd0aCA9PSAnbnVtYmVyJyAmJlxuICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsICdjYWxsZWUnKSAmJlxuICAgICFPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCAnY2FsbGVlJykgfHxcbiAgICBmYWxzZTtcbn07XG4iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbidcbiAgPyBPYmplY3Qua2V5cyA6IHNoaW07XG5cbmV4cG9ydHMuc2hpbSA9IHNoaW07XG5mdW5jdGlvbiBzaGltIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikga2V5cy5wdXNoKGtleSk7XG4gIHJldHVybiBrZXlzO1xufVxuIiwidmFyIGFzc2VydCA9IHJlcXVpcmUoMjcpXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoMzIpXG5cbnZhciBQb2ludCA9IHJlcXVpcmUoNjEpXG5cbmZ1bmN0aW9uIEN1cnZlIChwLCBhLCBiLCBHeCwgR3ksIG4sIGgpIHtcbiAgdGhpcy5wID0gcFxuICB0aGlzLmEgPSBhXG4gIHRoaXMuYiA9IGJcbiAgdGhpcy5HID0gUG9pbnQuZnJvbUFmZmluZSh0aGlzLCBHeCwgR3kpXG4gIHRoaXMubiA9IG5cbiAgdGhpcy5oID0gaFxuXG4gIHRoaXMuaW5maW5pdHkgPSBuZXcgUG9pbnQodGhpcywgbnVsbCwgbnVsbCwgQmlnSW50ZWdlci5aRVJPKVxuXG4gIC8vIHJlc3VsdCBjYWNoaW5nXG4gIHRoaXMucE92ZXJGb3VyID0gcC5hZGQoQmlnSW50ZWdlci5PTkUpLnNoaWZ0UmlnaHQoMilcblxuICAvLyBkZXRlcm1pbmUgc2l6ZSBvZiBwIGluIGJ5dGVzXG4gIHRoaXMucExlbmd0aCA9IE1hdGguZmxvb3IoKHRoaXMucC5iaXRMZW5ndGgoKSArIDcpIC8gOClcbn1cblxuQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVggPSBmdW5jdGlvbiAoaXNPZGQsIHgpIHtcbiAgdmFyIGFscGhhID0geC5wb3coMykuYWRkKHRoaXMuYS5tdWx0aXBseSh4KSkuYWRkKHRoaXMuYikubW9kKHRoaXMucClcbiAgdmFyIGJldGEgPSBhbHBoYS5tb2RQb3codGhpcy5wT3ZlckZvdXIsIHRoaXMucCkgLy8gWFhYOiBub3QgY29tcGF0aWJsZSB3aXRoIGFsbCBjdXJ2ZXNcblxuICB2YXIgeSA9IGJldGFcbiAgaWYgKGJldGEuaXNFdmVuKCkgXiAhaXNPZGQpIHtcbiAgICB5ID0gdGhpcy5wLnN1YnRyYWN0KHkpIC8vIC15ICUgcFxuICB9XG5cbiAgcmV0dXJuIFBvaW50LmZyb21BZmZpbmUodGhpcywgeCwgeSlcbn1cblxuQ3VydmUucHJvdG90eXBlLmlzSW5maW5pdHkgPSBmdW5jdGlvbiAoUSkge1xuICBpZiAoUSA9PT0gdGhpcy5pbmZpbml0eSkgcmV0dXJuIHRydWVcblxuICByZXR1cm4gUS56LnNpZ251bSgpID09PSAwICYmIFEueS5zaWdudW0oKSAhPT0gMFxufVxuXG5DdXJ2ZS5wcm90b3R5cGUuaXNPbkN1cnZlID0gZnVuY3Rpb24gKFEpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eShRKSkgcmV0dXJuIHRydWVcblxuICB2YXIgeCA9IFEuYWZmaW5lWFxuICB2YXIgeSA9IFEuYWZmaW5lWVxuICB2YXIgYSA9IHRoaXMuYVxuICB2YXIgYiA9IHRoaXMuYlxuICB2YXIgcCA9IHRoaXMucFxuXG4gIC8vIENoZWNrIHRoYXQgeFEgYW5kIHlRIGFyZSBpbnRlZ2VycyBpbiB0aGUgaW50ZXJ2YWwgWzAsIHAgLSAxXVxuICBpZiAoeC5zaWdudW0oKSA8IDAgfHwgeC5jb21wYXJlVG8ocCkgPj0gMCkgcmV0dXJuIGZhbHNlXG4gIGlmICh5LnNpZ251bSgpIDwgMCB8fCB5LmNvbXBhcmVUbyhwKSA+PSAwKSByZXR1cm4gZmFsc2VcblxuICAvLyBhbmQgY2hlY2sgdGhhdCB5XjIgPSB4XjMgKyBheCArIGIgKG1vZCBwKVxuICB2YXIgbGhzID0geS5zcXVhcmUoKS5tb2QocClcbiAgdmFyIHJocyA9IHgucG93KDMpLmFkZChhLm11bHRpcGx5KHgpKS5hZGQoYikubW9kKHApXG4gIHJldHVybiBsaHMuZXF1YWxzKHJocylcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBhbiBlbGxpcHRpYyBjdXJ2ZSBwb2ludC5cbiAqXG4gKiBTZWUgU0VDIDEsIHNlY3Rpb24gMy4yLjIuMTogRWxsaXB0aWMgQ3VydmUgUHVibGljIEtleSBWYWxpZGF0aW9uIFByaW1pdGl2ZVxuICovXG5DdXJ2ZS5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbiAoUSkge1xuICAvLyBDaGVjayBRICE9IE9cbiAgYXNzZXJ0KCF0aGlzLmlzSW5maW5pdHkoUSksICdQb2ludCBpcyBhdCBpbmZpbml0eScpXG4gIGFzc2VydCh0aGlzLmlzT25DdXJ2ZShRKSwgJ1BvaW50IGlzIG5vdCBvbiB0aGUgY3VydmUnKVxuXG4gIC8vIENoZWNrIG5RID0gTyAod2hlcmUgUSBpcyBhIHNjYWxhciBtdWx0aXBsZSBvZiBHKVxuICB2YXIgblEgPSBRLm11bHRpcGx5KHRoaXMubilcbiAgYXNzZXJ0KHRoaXMuaXNJbmZpbml0eShuUSksICdQb2ludCBpcyBub3QgYSBzY2FsYXIgbXVsdGlwbGUgb2YgRycpXG5cbiAgcmV0dXJuIHRydWVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDdXJ2ZVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInNlY3AxMjhyMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZcIixcbiAgICBcImFcIjogXCJmZmZmZmZmZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY1wiLFxuICAgIFwiYlwiOiBcImU4NzU3OWMxMTA3OWY0M2RkODI0OTkzYzJjZWU1ZWQzXCIsXG4gICAgXCJuXCI6IFwiZmZmZmZmZmUwMDAwMDAwMDc1YTMwZDFiOTAzOGExMTVcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCIxNjFmZjc1MjhiODk5YjJkMGMyODYwN2NhNTJjNWI4NlwiLFxuICAgIFwiR3lcIjogXCJjZjVhYzgzOTViYWZlYjEzYzAyZGEyOTJkZGVkN2E4M1wiXG4gIH0sXG4gIFwic2VjcDE2MGsxXCI6IHtcbiAgICBcInBcIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWZmZmZhYzczXCIsXG4gICAgXCJhXCI6IFwiMDBcIixcbiAgICBcImJcIjogXCIwN1wiLFxuICAgIFwiblwiOiBcIjAxMDAwMDAwMDAwMDAwMDAwMDAwMDFiOGZhMTZkZmFiOWFjYTE2YjZiM1wiLFxuICAgIFwiaFwiOiBcIjAxXCIsXG4gICAgXCJHeFwiOiBcIjNiNGMzODJjZTM3YWExOTJhNDAxOWU3NjMwMzZmNGY1ZGQ0ZDdlYmJcIixcbiAgICBcIkd5XCI6IFwiOTM4Y2Y5MzUzMThmZGNlZDZiYzI4Mjg2NTMxNzMzYzNmMDNjNGZlZVwiXG4gIH0sXG4gIFwic2VjcDE2MHIxXCI6IHtcbiAgICBcInBcIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjdmZmZmZmZmXCIsXG4gICAgXCJhXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY3ZmZmZmZmY1wiLFxuICAgIFwiYlwiOiBcIjFjOTdiZWZjNTRiZDdhOGI2NWFjZjg5ZjgxZDRkNGFkYzU2NWZhNDVcIixcbiAgICBcIm5cIjogXCIwMTAwMDAwMDAwMDAwMDAwMDAwMDAxZjRjOGY5MjdhZWQzY2E3NTIyNTdcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCI0YTk2YjU2ODhlZjU3MzI4NDY2NDY5ODk2OGMzOGJiOTEzY2JmYzgyXCIsXG4gICAgXCJHeVwiOiBcIjIzYTYyODU1MzE2ODk0N2Q1OWRjYzkxMjA0MjM1MTM3N2FjNWZiMzJcIlxuICB9LFxuICBcInNlY3AxOTJrMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWZmZmZlZTM3XCIsXG4gICAgXCJhXCI6IFwiMDBcIixcbiAgICBcImJcIjogXCIwM1wiLFxuICAgIFwiblwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZTI2ZjJmYzE3MGY2OTQ2NmE3NGRlZmQ4ZFwiLFxuICAgIFwiaFwiOiBcIjAxXCIsXG4gICAgXCJHeFwiOiBcImRiNGZmMTBlYzA1N2U5YWUyNmIwN2QwMjgwYjdmNDM0MWRhNWQxYjFlYWUwNmM3ZFwiLFxuICAgIFwiR3lcIjogXCI5YjJmMmY2ZDljNTYyOGE3ODQ0MTYzZDAxNWJlODYzNDQwODJhYTg4ZDk1ZTJmOWRcIlxuICB9LFxuICBcInNlY3AxOTJyMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZmZmZmZmZmZmZmZmXCIsXG4gICAgXCJhXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZmZmZmZmZmZmZmZjXCIsXG4gICAgXCJiXCI6IFwiNjQyMTA1MTllNTljODBlNzBmYTdlOWFiNzIyNDMwNDlmZWI4ZGVlY2MxNDZiOWIxXCIsXG4gICAgXCJuXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmOTlkZWY4MzYxNDZiYzliMWI0ZDIyODMxXCIsXG4gICAgXCJoXCI6IFwiMDFcIixcbiAgICBcIkd4XCI6IFwiMTg4ZGE4MGViMDMwOTBmNjdjYmYyMGViNDNhMTg4MDBmNGZmMGFmZDgyZmYxMDEyXCIsXG4gICAgXCJHeVwiOiBcIjA3MTkyYjk1ZmZjOGRhNzg2MzEwMTFlZDZiMjRjZGQ1NzNmOTc3YTExZTc5NDgxMVwiXG4gIH0sXG4gIFwic2VjcDI1NmsxXCI6IHtcbiAgICBcInBcIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWZmZmZmYzJmXCIsXG4gICAgXCJhXCI6IFwiMDBcIixcbiAgICBcImJcIjogXCIwN1wiLFxuICAgIFwiblwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlYmFhZWRjZTZhZjQ4YTAzYmJmZDI1ZThjZDAzNjQxNDFcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCI3OWJlNjY3ZWY5ZGNiYmFjNTVhMDYyOTVjZTg3MGIwNzAyOWJmY2RiMmRjZTI4ZDk1OWYyODE1YjE2ZjgxNzk4XCIsXG4gICAgXCJHeVwiOiBcIjQ4M2FkYTc3MjZhM2M0NjU1ZGE0ZmJmYzBlMTEwOGE4ZmQxN2I0NDhhNjg1NTQxOTljNDdkMDhmZmIxMGQ0YjhcIlxuICB9LFxuICBcInNlY3AyNTZyMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmYwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlwiLFxuICAgIFwiYVwiOiBcImZmZmZmZmZmMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmNcIixcbiAgICBcImJcIjogXCI1YWM2MzVkOGFhM2E5M2U3YjNlYmJkNTU3Njk4ODZiYzY1MWQwNmIwY2M1M2IwZjYzYmNlM2MzZTI3ZDI2MDRiXCIsXG4gICAgXCJuXCI6IFwiZmZmZmZmZmYwMDAwMDAwMGZmZmZmZmZmZmZmZmZmZmZiY2U2ZmFhZGE3MTc5ZTg0ZjNiOWNhYzJmYzYzMjU1MVwiLFxuICAgIFwiaFwiOiBcIjAxXCIsXG4gICAgXCJHeFwiOiBcIjZiMTdkMWYyZTEyYzQyNDdmOGJjZTZlNTYzYTQ0MGYyNzcwMzdkODEyZGViMzNhMGY0YTEzOTQ1ZDg5OGMyOTZcIixcbiAgICBcIkd5XCI6IFwiNGZlMzQyZTJmZTFhN2Y5YjhlZTdlYjRhN2MwZjllMTYyYmNlMzM1NzZiMzE1ZWNlY2JiNjQwNjgzN2JmNTFmNVwiXG4gIH1cbn1cbiIsInZhciBQb2ludCA9IHJlcXVpcmUoNjEpXG52YXIgQ3VydmUgPSByZXF1aXJlKDU3KVxuXG52YXIgZ2V0Q3VydmVCeU5hbWUgPSByZXF1aXJlKDYwKVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQ3VydmU6IEN1cnZlLFxuICBQb2ludDogUG9pbnQsXG4gIGdldEN1cnZlQnlOYW1lOiBnZXRDdXJ2ZUJ5TmFtZVxufVxuIiwidmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKDMyKVxuXG52YXIgY3VydmVzID0gcmVxdWlyZSg1OClcbnZhciBDdXJ2ZSA9IHJlcXVpcmUoNTcpXG5cbmZ1bmN0aW9uIGdldEN1cnZlQnlOYW1lIChuYW1lKSB7XG4gIHZhciBjdXJ2ZSA9IGN1cnZlc1tuYW1lXVxuICBpZiAoIWN1cnZlKSByZXR1cm4gbnVsbFxuXG4gIHZhciBwID0gbmV3IEJpZ0ludGVnZXIoY3VydmUucCwgMTYpXG4gIHZhciBhID0gbmV3IEJpZ0ludGVnZXIoY3VydmUuYSwgMTYpXG4gIHZhciBiID0gbmV3IEJpZ0ludGVnZXIoY3VydmUuYiwgMTYpXG4gIHZhciBuID0gbmV3IEJpZ0ludGVnZXIoY3VydmUubiwgMTYpXG4gIHZhciBoID0gbmV3IEJpZ0ludGVnZXIoY3VydmUuaCwgMTYpXG4gIHZhciBHeCA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLkd4LCAxNilcbiAgdmFyIEd5ID0gbmV3IEJpZ0ludGVnZXIoY3VydmUuR3ksIDE2KVxuXG4gIHJldHVybiBuZXcgQ3VydmUocCwgYSwgYiwgR3gsIEd5LCBuLCBoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldEN1cnZlQnlOYW1lXG4iLCJ2YXIgYXNzZXJ0ID0gcmVxdWlyZSgyNylcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgzMilcblxudmFyIFRIUkVFID0gQmlnSW50ZWdlci52YWx1ZU9mKDMpXG5cbmZ1bmN0aW9uIFBvaW50IChjdXJ2ZSwgeCwgeSwgeikge1xuICBhc3NlcnQubm90U3RyaWN0RXF1YWwoeiwgdW5kZWZpbmVkLCAnTWlzc2luZyBaIGNvb3JkaW5hdGUnKVxuXG4gIHRoaXMuY3VydmUgPSBjdXJ2ZVxuICB0aGlzLnggPSB4XG4gIHRoaXMueSA9IHlcbiAgdGhpcy56ID0gelxuICB0aGlzLl96SW52ID0gbnVsbFxuXG4gIHRoaXMuY29tcHJlc3NlZCA9IHRydWVcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFBvaW50LnByb3RvdHlwZSwgJ3pJbnYnLCB7XG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLl96SW52ID09PSBudWxsKSB7XG4gICAgICB0aGlzLl96SW52ID0gdGhpcy56Lm1vZEludmVyc2UodGhpcy5jdXJ2ZS5wKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl96SW52XG4gIH1cbn0pXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShQb2ludC5wcm90b3R5cGUsICdhZmZpbmVYJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy54Lm11bHRpcGx5KHRoaXMuekludikubW9kKHRoaXMuY3VydmUucClcbiAgfVxufSlcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFBvaW50LnByb3RvdHlwZSwgJ2FmZmluZVknLCB7XG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnkubXVsdGlwbHkodGhpcy56SW52KS5tb2QodGhpcy5jdXJ2ZS5wKVxuICB9XG59KVxuXG5Qb2ludC5mcm9tQWZmaW5lID0gZnVuY3Rpb24gKGN1cnZlLCB4LCB5KSB7XG4gIHJldHVybiBuZXcgUG9pbnQoY3VydmUsIHgsIHksIEJpZ0ludGVnZXIuT05FKVxufVxuXG5Qb2ludC5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIGlmIChvdGhlciA9PT0gdGhpcykgcmV0dXJuIHRydWVcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eSh0aGlzKSkgcmV0dXJuIHRoaXMuY3VydmUuaXNJbmZpbml0eShvdGhlcilcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eShvdGhlcikpIHJldHVybiB0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcylcblxuICAvLyB1ID0gWTIgKiBaMSAtIFkxICogWjJcbiAgdmFyIHUgPSBvdGhlci55Lm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QodGhpcy55Lm11bHRpcGx5KG90aGVyLnopKS5tb2QodGhpcy5jdXJ2ZS5wKVxuXG4gIGlmICh1LnNpZ251bSgpICE9PSAwKSByZXR1cm4gZmFsc2VcblxuICAvLyB2ID0gWDIgKiBaMSAtIFgxICogWjJcbiAgdmFyIHYgPSBvdGhlci54Lm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QodGhpcy54Lm11bHRpcGx5KG90aGVyLnopKS5tb2QodGhpcy5jdXJ2ZS5wKVxuXG4gIHJldHVybiB2LnNpZ251bSgpID09PSAwXG59XG5cblBvaW50LnByb3RvdHlwZS5uZWdhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB5ID0gdGhpcy5jdXJ2ZS5wLnN1YnRyYWN0KHRoaXMueSlcblxuICByZXR1cm4gbmV3IFBvaW50KHRoaXMuY3VydmUsIHRoaXMueCwgeSwgdGhpcy56KVxufVxuXG5Qb2ludC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGIpIHtcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eSh0aGlzKSkgcmV0dXJuIGJcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eShiKSkgcmV0dXJuIHRoaXNcblxuICB2YXIgeDEgPSB0aGlzLnhcbiAgdmFyIHkxID0gdGhpcy55XG4gIHZhciB4MiA9IGIueFxuICB2YXIgeTIgPSBiLnlcblxuICAvLyB1ID0gWTIgKiBaMSAtIFkxICogWjJcbiAgdmFyIHUgPSB5Mi5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHkxLm11bHRpcGx5KGIueikpLm1vZCh0aGlzLmN1cnZlLnApXG4gIC8vIHYgPSBYMiAqIFoxIC0gWDEgKiBaMlxuICB2YXIgdiA9IHgyLm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QoeDEubXVsdGlwbHkoYi56KSkubW9kKHRoaXMuY3VydmUucClcblxuICBpZiAodi5zaWdudW0oKSA9PT0gMCkge1xuICAgIGlmICh1LnNpZ251bSgpID09PSAwKSB7XG4gICAgICByZXR1cm4gdGhpcy50d2ljZSgpIC8vIHRoaXMgPT0gYiwgc28gZG91YmxlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuaW5maW5pdHkgLy8gdGhpcyA9IC1iLCBzbyBpbmZpbml0eVxuICB9XG5cbiAgdmFyIHYyID0gdi5zcXVhcmUoKVxuICB2YXIgdjMgPSB2Mi5tdWx0aXBseSh2KVxuICB2YXIgeDF2MiA9IHgxLm11bHRpcGx5KHYyKVxuICB2YXIgenUyID0gdS5zcXVhcmUoKS5tdWx0aXBseSh0aGlzLnopXG5cbiAgLy8geDMgPSB2ICogKHoyICogKHoxICogdV4yIC0gMiAqIHgxICogdl4yKSAtIHZeMylcbiAgdmFyIHgzID0genUyLnN1YnRyYWN0KHgxdjIuc2hpZnRMZWZ0KDEpKS5tdWx0aXBseShiLnopLnN1YnRyYWN0KHYzKS5tdWx0aXBseSh2KS5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB5MyA9IHoyICogKDMgKiB4MSAqIHUgKiB2XjIgLSB5MSAqIHZeMyAtIHoxICogdV4zKSArIHUgKiB2XjNcbiAgdmFyIHkzID0geDF2Mi5tdWx0aXBseShUSFJFRSkubXVsdGlwbHkodSkuc3VidHJhY3QoeTEubXVsdGlwbHkodjMpKS5zdWJ0cmFjdCh6dTIubXVsdGlwbHkodSkpLm11bHRpcGx5KGIueikuYWRkKHUubXVsdGlwbHkodjMpKS5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB6MyA9IHZeMyAqIHoxICogejJcbiAgdmFyIHozID0gdjMubXVsdGlwbHkodGhpcy56KS5tdWx0aXBseShiLnopLm1vZCh0aGlzLmN1cnZlLnApXG5cbiAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLmN1cnZlLCB4MywgeTMsIHozKVxufVxuXG5Qb2ludC5wcm90b3R5cGUudHdpY2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcykpIHJldHVybiB0aGlzXG4gIGlmICh0aGlzLnkuc2lnbnVtKCkgPT09IDApIHJldHVybiB0aGlzLmN1cnZlLmluZmluaXR5XG5cbiAgdmFyIHgxID0gdGhpcy54XG4gIHZhciB5MSA9IHRoaXMueVxuXG4gIHZhciB5MXoxID0geTEubXVsdGlwbHkodGhpcy56KS5tb2QodGhpcy5jdXJ2ZS5wKVxuICB2YXIgeTFzcXoxID0geTF6MS5tdWx0aXBseSh5MSkubW9kKHRoaXMuY3VydmUucClcbiAgdmFyIGEgPSB0aGlzLmN1cnZlLmFcblxuICAvLyB3ID0gMyAqIHgxXjIgKyBhICogejFeMlxuICB2YXIgdyA9IHgxLnNxdWFyZSgpLm11bHRpcGx5KFRIUkVFKVxuXG4gIGlmIChhLnNpZ251bSgpICE9PSAwKSB7XG4gICAgdyA9IHcuYWRkKHRoaXMuei5zcXVhcmUoKS5tdWx0aXBseShhKSlcbiAgfVxuXG4gIHcgPSB3Lm1vZCh0aGlzLmN1cnZlLnApXG4gIC8vIHgzID0gMiAqIHkxICogejEgKiAod14yIC0gOCAqIHgxICogeTFeMiAqIHoxKVxuICB2YXIgeDMgPSB3LnNxdWFyZSgpLnN1YnRyYWN0KHgxLnNoaWZ0TGVmdCgzKS5tdWx0aXBseSh5MXNxejEpKS5zaGlmdExlZnQoMSkubXVsdGlwbHkoeTF6MSkubW9kKHRoaXMuY3VydmUucClcbiAgLy8geTMgPSA0ICogeTFeMiAqIHoxICogKDMgKiB3ICogeDEgLSAyICogeTFeMiAqIHoxKSAtIHdeM1xuICB2YXIgeTMgPSB3Lm11bHRpcGx5KFRIUkVFKS5tdWx0aXBseSh4MSkuc3VidHJhY3QoeTFzcXoxLnNoaWZ0TGVmdCgxKSkuc2hpZnRMZWZ0KDIpLm11bHRpcGx5KHkxc3F6MSkuc3VidHJhY3Qody5wb3coMykpLm1vZCh0aGlzLmN1cnZlLnApXG4gIC8vIHozID0gOCAqICh5MSAqIHoxKV4zXG4gIHZhciB6MyA9IHkxejEucG93KDMpLnNoaWZ0TGVmdCgzKS5tb2QodGhpcy5jdXJ2ZS5wKVxuXG4gIHJldHVybiBuZXcgUG9pbnQodGhpcy5jdXJ2ZSwgeDMsIHkzLCB6Mylcbn1cblxuLy8gU2ltcGxlIE5BRiAoTm9uLUFkamFjZW50IEZvcm0pIG11bHRpcGxpY2F0aW9uIGFsZ29yaXRobVxuLy8gVE9ETzogbW9kdWxhcml6ZSB0aGUgbXVsdGlwbGljYXRpb24gYWxnb3JpdGhtXG5Qb2ludC5wcm90b3R5cGUubXVsdGlwbHkgPSBmdW5jdGlvbiAoaykge1xuICBpZiAodGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpKSByZXR1cm4gdGhpc1xuICBpZiAoay5zaWdudW0oKSA9PT0gMCkgcmV0dXJuIHRoaXMuY3VydmUuaW5maW5pdHlcblxuICB2YXIgZSA9IGtcbiAgdmFyIGggPSBlLm11bHRpcGx5KFRIUkVFKVxuXG4gIHZhciBuZWcgPSB0aGlzLm5lZ2F0ZSgpXG4gIHZhciBSID0gdGhpc1xuXG4gIGZvciAodmFyIGkgPSBoLmJpdExlbmd0aCgpIC0gMjsgaSA+IDA7IC0taSkge1xuICAgIHZhciBoQml0ID0gaC50ZXN0Qml0KGkpXG4gICAgdmFyIGVCaXQgPSBlLnRlc3RCaXQoaSlcblxuICAgIFIgPSBSLnR3aWNlKClcblxuICAgIGlmIChoQml0ICE9PSBlQml0KSB7XG4gICAgICBSID0gUi5hZGQoaEJpdCA/IHRoaXMgOiBuZWcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIFJcbn1cblxuLy8gQ29tcHV0ZSB0aGlzKmogKyB4KmsgKHNpbXVsdGFuZW91cyBtdWx0aXBsaWNhdGlvbilcblBvaW50LnByb3RvdHlwZS5tdWx0aXBseVR3byA9IGZ1bmN0aW9uIChqLCB4LCBrKSB7XG4gIHZhciBpID0gTWF0aC5tYXgoai5iaXRMZW5ndGgoKSwgay5iaXRMZW5ndGgoKSkgLSAxXG4gIHZhciBSID0gdGhpcy5jdXJ2ZS5pbmZpbml0eVxuICB2YXIgYm90aCA9IHRoaXMuYWRkKHgpXG5cbiAgd2hpbGUgKGkgPj0gMCkge1xuICAgIHZhciBqQml0ID0gai50ZXN0Qml0KGkpXG4gICAgdmFyIGtCaXQgPSBrLnRlc3RCaXQoaSlcblxuICAgIFIgPSBSLnR3aWNlKClcblxuICAgIGlmIChqQml0KSB7XG4gICAgICBpZiAoa0JpdCkge1xuICAgICAgICBSID0gUi5hZGQoYm90aClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIFIgPSBSLmFkZCh0aGlzKVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoa0JpdCkge1xuICAgICAgUiA9IFIuYWRkKHgpXG4gICAgfVxuICAgIC0taVxuICB9XG5cbiAgcmV0dXJuIFJcbn1cblxuUG9pbnQucHJvdG90eXBlLmdldEVuY29kZWQgPSBmdW5jdGlvbiAoY29tcHJlc3NlZCkge1xuICBpZiAoY29tcHJlc3NlZCA9PSBudWxsKSBjb21wcmVzc2VkID0gdGhpcy5jb21wcmVzc2VkXG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcykpIHJldHVybiBCdWZmZXIuYWxsb2MoMSwgMCkgLy8gSW5maW5pdHkgcG9pbnQgZW5jb2RlZCBpcyBzaW1wbHkgJzAwJ1xuXG4gIHZhciB4ID0gdGhpcy5hZmZpbmVYXG4gIHZhciB5ID0gdGhpcy5hZmZpbmVZXG4gIHZhciBieXRlTGVuZ3RoID0gdGhpcy5jdXJ2ZS5wTGVuZ3RoXG4gIHZhciBidWZmZXJcblxuICAvLyAweDAyLzB4MDMgfCBYXG4gIGlmIChjb21wcmVzc2VkKSB7XG4gICAgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKDEgKyBieXRlTGVuZ3RoKVxuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KHkuaXNFdmVuKCkgPyAweDAyIDogMHgwMywgMClcblxuICAvLyAweDA0IHwgWCB8IFlcbiAgfSBlbHNlIHtcbiAgICBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMSArIGJ5dGVMZW5ndGggKyBieXRlTGVuZ3RoKVxuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KDB4MDQsIDApXG5cbiAgICB5LnRvQnVmZmVyKGJ5dGVMZW5ndGgpLmNvcHkoYnVmZmVyLCAxICsgYnl0ZUxlbmd0aClcbiAgfVxuXG4gIHgudG9CdWZmZXIoYnl0ZUxlbmd0aCkuY29weShidWZmZXIsIDEpXG5cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5Qb2ludC5kZWNvZGVGcm9tID0gZnVuY3Rpb24gKGN1cnZlLCBidWZmZXIpIHtcbiAgdmFyIHR5cGUgPSBidWZmZXIucmVhZFVJbnQ4KDApXG4gIHZhciBjb21wcmVzc2VkID0gKHR5cGUgIT09IDQpXG5cbiAgdmFyIGJ5dGVMZW5ndGggPSBNYXRoLmZsb29yKChjdXJ2ZS5wLmJpdExlbmd0aCgpICsgNykgLyA4KVxuICB2YXIgeCA9IEJpZ0ludGVnZXIuZnJvbUJ1ZmZlcihidWZmZXIuc2xpY2UoMSwgMSArIGJ5dGVMZW5ndGgpKVxuXG4gIHZhciBRXG4gIGlmIChjb21wcmVzc2VkKSB7XG4gICAgYXNzZXJ0LmVxdWFsKGJ1ZmZlci5sZW5ndGgsIGJ5dGVMZW5ndGggKyAxLCAnSW52YWxpZCBzZXF1ZW5jZSBsZW5ndGgnKVxuICAgIGFzc2VydCh0eXBlID09PSAweDAyIHx8IHR5cGUgPT09IDB4MDMsICdJbnZhbGlkIHNlcXVlbmNlIHRhZycpXG5cbiAgICB2YXIgaXNPZGQgPSAodHlwZSA9PT0gMHgwMylcbiAgICBRID0gY3VydmUucG9pbnRGcm9tWChpc09kZCwgeClcbiAgfSBlbHNlIHtcbiAgICBhc3NlcnQuZXF1YWwoYnVmZmVyLmxlbmd0aCwgMSArIGJ5dGVMZW5ndGggKyBieXRlTGVuZ3RoLCAnSW52YWxpZCBzZXF1ZW5jZSBsZW5ndGgnKVxuXG4gICAgdmFyIHkgPSBCaWdJbnRlZ2VyLmZyb21CdWZmZXIoYnVmZmVyLnNsaWNlKDEgKyBieXRlTGVuZ3RoKSlcbiAgICBRID0gUG9pbnQuZnJvbUFmZmluZShjdXJ2ZSwgeCwgeSlcbiAgfVxuXG4gIFEuY29tcHJlc3NlZCA9IGNvbXByZXNzZWRcbiAgcmV0dXJuIFFcbn1cblxuUG9pbnQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpKSByZXR1cm4gJyhJTkZJTklUWSknXG5cbiAgcmV0dXJuICcoJyArIHRoaXMuYWZmaW5lWC50b1N0cmluZygpICsgJywnICsgdGhpcy5hZmZpbmVZLnRvU3RyaW5nKCkgKyAnKSdcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBQb2ludFxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG5FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gIGlmICghaXNOdW1iZXIobikgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICAgIGVyci5jb250ZXh0ID0gZXI7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc1VuZGVmaW5lZChoYW5kbGVyKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIGhhbmRsZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGhhbmRsZXIpKSB7XG4gICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgbGlzdGVuZXJzID0gaGFuZGxlci5zbGljZSgpO1xuICAgIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIG07XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgaWYgKHRoaXMuX2V2ZW50cy5uZXdMaXN0ZW5lcilcbiAgICB0aGlzLmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICAgICAgaXNGdW5jdGlvbihsaXN0ZW5lci5saXN0ZW5lcikgP1xuICAgICAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgZWxzZSBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuICBlbHNlXG4gICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuXG4gIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pICYmICF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKSB7XG4gICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9tYXhMaXN0ZW5lcnMpKSB7XG4gICAgICBtID0gdGhpcy5fbWF4TGlzdGVuZXJzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfVxuXG4gICAgaWYgKG0gJiYgbSA+IDAgJiYgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCA+IG0pIHtcbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQgPSB0cnVlO1xuICAgICAgY29uc29sZS5lcnJvcignKG5vZGUpIHdhcm5pbmc6IHBvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgJyArXG4gICAgICAgICAgICAgICAgICAgICdsZWFrIGRldGVjdGVkLiAlZCBsaXN0ZW5lcnMgYWRkZWQuICcgK1xuICAgICAgICAgICAgICAgICAgICAnVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gaW5jcmVhc2UgbGltaXQuJyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCk7XG4gICAgICBpZiAodHlwZW9mIGNvbnNvbGUudHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gbm90IHN1cHBvcnRlZCBpbiBJRSAxMFxuICAgICAgICBjb25zb2xlLnRyYWNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIHZhciBmaXJlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGcoKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBnKTtcblxuICAgIGlmICghZmlyZWQpIHtcbiAgICAgIGZpcmVkID0gdHJ1ZTtcbiAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9XG5cbiAgZy5saXN0ZW5lciA9IGxpc3RlbmVyO1xuICB0aGlzLm9uKHR5cGUsIGcpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWRcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbGlzdCwgcG9zaXRpb24sIGxlbmd0aCwgaTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXR1cm4gdGhpcztcblxuICBsaXN0ID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuICBsZW5ndGggPSBsaXN0Lmxlbmd0aDtcbiAgcG9zaXRpb24gPSAtMTtcblxuICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHxcbiAgICAgIChpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpICYmIGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG5cbiAgfSBlbHNlIGlmIChpc09iamVjdChsaXN0KSkge1xuICAgIGZvciAoaSA9IGxlbmd0aDsgaS0tID4gMDspIHtcbiAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fFxuICAgICAgICAgIChsaXN0W2ldLmxpc3RlbmVyICYmIGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgbGlzdC5sZW5ndGggPSAwO1xuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGlzdC5zcGxpY2UocG9zaXRpb24sIDEpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGtleSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgaWYgKCF0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIGVsc2UgaWYgKHRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGtleSBpbiB0aGlzLl9ldmVudHMpIHtcbiAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICB9XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzRnVuY3Rpb24obGlzdGVuZXJzKSkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAvLyBMSUZPIG9yZGVyXG4gICAgd2hpbGUgKGxpc3RlbmVycy5sZW5ndGgpXG4gICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV0pO1xuICB9XG4gIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIHJldDtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXQgPSBbXTtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IFt0aGlzLl9ldmVudHNbdHlwZV1dO1xuICBlbHNlXG4gICAgcmV0ID0gdGhpcy5fZXZlbnRzW3R5cGVdLnNsaWNlKCk7XG4gIHJldHVybiByZXQ7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIGlmICh0aGlzLl9ldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGV2bGlzdGVuZXIpKVxuICAgICAgcmV0dXJuIDE7XG4gICAgZWxzZSBpZiAoZXZsaXN0ZW5lcilcbiAgICAgIHJldHVybiBldmxpc3RlbmVyLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gMDtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xufTtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuIiwiJ3VzZSBzdHJpY3QnXG52YXIgQnVmZmVyID0gcmVxdWlyZSg5MykuQnVmZmVyXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgxMDMpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcblxuZnVuY3Rpb24gdGhyb3dJZk5vdFN0cmluZ09yQnVmZmVyICh2YWwsIHByZWZpeCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih2YWwpICYmIHR5cGVvZiB2YWwgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihwcmVmaXggKyAnIG11c3QgYmUgYSBzdHJpbmcgb3IgYSBidWZmZXInKVxuICB9XG59XG5cbmZ1bmN0aW9uIEhhc2hCYXNlIChibG9ja1NpemUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcblxuICB0aGlzLl9ibG9jayA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja1NpemUpXG4gIHRoaXMuX2Jsb2NrU2l6ZSA9IGJsb2NrU2l6ZVxuICB0aGlzLl9ibG9ja09mZnNldCA9IDBcbiAgdGhpcy5fbGVuZ3RoID0gWzAsIDAsIDAsIDBdXG5cbiAgdGhpcy5fZmluYWxpemVkID0gZmFsc2Vcbn1cblxuaW5oZXJpdHMoSGFzaEJhc2UsIFRyYW5zZm9ybSlcblxuSGFzaEJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYWxsYmFjaykge1xuICB2YXIgZXJyb3IgPSBudWxsXG4gIHRyeSB7XG4gICAgdGhpcy51cGRhdGUoY2h1bmssIGVuY29kaW5nKVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBlcnJvciA9IGVyclxuICB9XG5cbiAgY2FsbGJhY2soZXJyb3IpXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgdmFyIGVycm9yID0gbnVsbFxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLmRpZ2VzdCgpKVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBlcnJvciA9IGVyclxuICB9XG5cbiAgY2FsbGJhY2soZXJyb3IpXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jb2RpbmcpIHtcbiAgdGhyb3dJZk5vdFN0cmluZ09yQnVmZmVyKGRhdGEsICdEYXRhJylcbiAgaWYgKHRoaXMuX2ZpbmFsaXplZCkgdGhyb3cgbmV3IEVycm9yKCdEaWdlc3QgYWxyZWFkeSBjYWxsZWQnKVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkgZGF0YSA9IEJ1ZmZlci5mcm9tKGRhdGEsIGVuY29kaW5nKVxuXG4gIC8vIGNvbnN1bWUgZGF0YVxuICB2YXIgYmxvY2sgPSB0aGlzLl9ibG9ja1xuICB2YXIgb2Zmc2V0ID0gMFxuICB3aGlsZSAodGhpcy5fYmxvY2tPZmZzZXQgKyBkYXRhLmxlbmd0aCAtIG9mZnNldCA+PSB0aGlzLl9ibG9ja1NpemUpIHtcbiAgICBmb3IgKHZhciBpID0gdGhpcy5fYmxvY2tPZmZzZXQ7IGkgPCB0aGlzLl9ibG9ja1NpemU7KSBibG9ja1tpKytdID0gZGF0YVtvZmZzZXQrK11cbiAgICB0aGlzLl91cGRhdGUoKVxuICAgIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB9XG4gIHdoaWxlIChvZmZzZXQgPCBkYXRhLmxlbmd0aCkgYmxvY2tbdGhpcy5fYmxvY2tPZmZzZXQrK10gPSBkYXRhW29mZnNldCsrXVxuXG4gIC8vIHVwZGF0ZSBsZW5ndGhcbiAgZm9yICh2YXIgaiA9IDAsIGNhcnJ5ID0gZGF0YS5sZW5ndGggKiA4OyBjYXJyeSA+IDA7ICsraikge1xuICAgIHRoaXMuX2xlbmd0aFtqXSArPSBjYXJyeVxuICAgIGNhcnJ5ID0gKHRoaXMuX2xlbmd0aFtqXSAvIDB4MDEwMDAwMDAwMCkgfCAwXG4gICAgaWYgKGNhcnJ5ID4gMCkgdGhpcy5fbGVuZ3RoW2pdIC09IDB4MDEwMDAwMDAwMCAqIGNhcnJ5XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdXBkYXRlIGlzIG5vdCBpbXBsZW1lbnRlZCcpXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiAoZW5jb2RpbmcpIHtcbiAgaWYgKHRoaXMuX2ZpbmFsaXplZCkgdGhyb3cgbmV3IEVycm9yKCdEaWdlc3QgYWxyZWFkeSBjYWxsZWQnKVxuICB0aGlzLl9maW5hbGl6ZWQgPSB0cnVlXG5cbiAgdmFyIGRpZ2VzdCA9IHRoaXMuX2RpZ2VzdCgpXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSBkaWdlc3QgPSBkaWdlc3QudG9TdHJpbmcoZW5jb2RpbmcpXG5cbiAgLy8gcmVzZXQgc3RhdGVcbiAgdGhpcy5fYmxvY2suZmlsbCgwKVxuICB0aGlzLl9ibG9ja09mZnNldCA9IDBcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyArK2kpIHRoaXMuX2xlbmd0aFtpXSA9IDBcblxuICByZXR1cm4gZGlnZXN0XG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ19kaWdlc3QgaXMgbm90IGltcGxlbWVudGVkJylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBIYXNoQmFzZVxuIiwiZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSAoZSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSAobSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICgodmFsdWUgKiBjKSAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG4iLCIvKiFcbiAqIERldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBCdWZmZXJcbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbi8vIFRoZSBfaXNCdWZmZXIgY2hlY2sgaXMgZm9yIFNhZmFyaSA1LTcgc3VwcG9ydCwgYmVjYXVzZSBpdCdzIG1pc3Npbmdcbi8vIE9iamVjdC5wcm90b3R5cGUuY29uc3RydWN0b3IuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHlcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gb2JqICE9IG51bGwgJiYgKGlzQnVmZmVyKG9iaikgfHwgaXNTbG93QnVmZmVyKG9iaikgfHwgISFvYmouX2lzQnVmZmVyKVxufVxuXG5mdW5jdGlvbiBpc0J1ZmZlciAob2JqKSB7XG4gIHJldHVybiAhIW9iai5jb25zdHJ1Y3RvciAmJiB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopXG59XG5cbi8vIEZvciBOb2RlIHYwLjEwIHN1cHBvcnQuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHkuXG5mdW5jdGlvbiBpc1Nsb3dCdWZmZXIgKG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iai5yZWFkRmxvYXRMRSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2Ygb2JqLnNsaWNlID09PSAnZnVuY3Rpb24nICYmIGlzQnVmZmVyKG9iai5zbGljZSgwLCAwKSlcbn1cbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwiLypcclxuIENvcHlyaWdodCAyMDEzIERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcbiBDb3B5cmlnaHQgMjAwOSBUaGUgQ2xvc3VyZSBMaWJyYXJ5IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcblxyXG4gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcclxuIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cclxuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG5cclxuIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcclxuIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMtSVNcIiBCQVNJUyxcclxuIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxyXG4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxyXG4gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEBsaWNlbnNlIGxvbmcuanMgKGMpIDIwMTMgRGFuaWVsIFdpcnR6IDxkY29kZUBkY29kZS5pbz5cclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMFxyXG4gKiBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL2xvbmcuanMgZm9yIGRldGFpbHNcclxuICovXHJcbihmdW5jdGlvbihnbG9iYWwsIGZhY3RvcnkpIHtcclxuXHJcbiAgICAvKiBBTUQgKi8gaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lW1wiYW1kXCJdKVxyXG4gICAgICAgIGRlZmluZShbXSwgZmFjdG9yeSk7XHJcbiAgICAvKiBDb21tb25KUyAqLyBlbHNlIGlmICh0eXBlb2YgcmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIG1vZHVsZSAmJiBtb2R1bGVbXCJleHBvcnRzXCJdKVxyXG4gICAgICAgIG1vZHVsZVtcImV4cG9ydHNcIl0gPSBmYWN0b3J5KCk7XHJcbiAgICAvKiBHbG9iYWwgKi8gZWxzZVxyXG4gICAgICAgIChnbG9iYWxbXCJkY29kZUlPXCJdID0gZ2xvYmFsW1wiZGNvZGVJT1wiXSB8fCB7fSlbXCJMb25nXCJdID0gZmFjdG9yeSgpO1xyXG5cclxufSkodGhpcywgZnVuY3Rpb24oKSB7XHJcbiAgICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyLCBnaXZlbiBpdHMgbG93IGFuZCBoaWdoIDMyIGJpdCB2YWx1ZXMgYXMgKnNpZ25lZCogaW50ZWdlcnMuXHJcbiAgICAgKiAgU2VlIHRoZSBmcm9tKiBmdW5jdGlvbnMgYmVsb3cgZm9yIG1vcmUgY29udmVuaWVudCB3YXlzIG9mIGNvbnN0cnVjdGluZyBMb25ncy5cclxuICAgICAqIEBleHBvcnRzIExvbmdcclxuICAgICAqIEBjbGFzcyBBIExvbmcgY2xhc3MgZm9yIHJlcHJlc2VudGluZyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIgdmFsdWUuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93IFRoZSBsb3cgKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2ggVGhlIGhpZ2ggKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIExvbmcobG93LCBoaWdoLCB1bnNpZ25lZCkge1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgbG93IDMyIGJpdHMgYXMgYSBzaWduZWQgdmFsdWUuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmxvdyA9IGxvdyB8IDA7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgdmFsdWUuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmhpZ2ggPSBoaWdoIHwgMDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV2hldGhlciB1bnNpZ25lZCBvciBub3QuXHJcbiAgICAgICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy51bnNpZ25lZCA9ICEhdW5zaWduZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIGEgbG9uZyBpcyB0aGUgdHdvIGdpdmVuIHNpZ25lZCwgMzItYml0IHZhbHVlcy5cclxuICAgIC8vIFdlIHVzZSAzMi1iaXQgcGllY2VzIGJlY2F1c2UgdGhlc2UgYXJlIHRoZSBzaXplIG9mIGludGVnZXJzIG9uIHdoaWNoXHJcbiAgICAvLyBKYXZhc2NyaXB0IHBlcmZvcm1zIGJpdC1vcGVyYXRpb25zLiAgRm9yIG9wZXJhdGlvbnMgbGlrZSBhZGRpdGlvbiBhbmRcclxuICAgIC8vIG11bHRpcGxpY2F0aW9uLCB3ZSBzcGxpdCBlYWNoIG51bWJlciBpbnRvIDE2IGJpdCBwaWVjZXMsIHdoaWNoIGNhbiBlYXNpbHkgYmVcclxuICAgIC8vIG11bHRpcGxpZWQgd2l0aGluIEphdmFzY3JpcHQncyBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiB3aXRob3V0IG92ZXJmbG93XHJcbiAgICAvLyBvciBjaGFuZ2UgaW4gc2lnbi5cclxuICAgIC8vXHJcbiAgICAvLyBJbiB0aGUgYWxnb3JpdGhtcyBiZWxvdywgd2UgZnJlcXVlbnRseSByZWR1Y2UgdGhlIG5lZ2F0aXZlIGNhc2UgdG8gdGhlXHJcbiAgICAvLyBwb3NpdGl2ZSBjYXNlIGJ5IG5lZ2F0aW5nIHRoZSBpbnB1dChzKSBhbmQgdGhlbiBwb3N0LXByb2Nlc3NpbmcgdGhlIHJlc3VsdC5cclxuICAgIC8vIE5vdGUgdGhhdCB3ZSBtdXN0IEFMV0FZUyBjaGVjayBzcGVjaWFsbHkgd2hldGhlciB0aG9zZSB2YWx1ZXMgYXJlIE1JTl9WQUxVRVxyXG4gICAgLy8gKC0yXjYzKSBiZWNhdXNlIC1NSU5fVkFMVUUgPT0gTUlOX1ZBTFVFIChzaW5jZSAyXjYzIGNhbm5vdCBiZSByZXByZXNlbnRlZCBhc1xyXG4gICAgLy8gYSBwb3NpdGl2ZSBudW1iZXIsIGl0IG92ZXJmbG93cyBiYWNrIGludG8gYSBuZWdhdGl2ZSkuICBOb3QgaGFuZGxpbmcgdGhpc1xyXG4gICAgLy8gY2FzZSB3b3VsZCBvZnRlbiByZXN1bHQgaW4gaW5maW5pdGUgcmVjdXJzaW9uLlxyXG4gICAgLy9cclxuICAgIC8vIENvbW1vbiBjb25zdGFudCB2YWx1ZXMgWkVSTywgT05FLCBORUdfT05FLCBldGMuIGFyZSBkZWZpbmVkIGJlbG93IHRoZSBmcm9tKlxyXG4gICAgLy8gbWV0aG9kcyBvbiB3aGljaCB0aGV5IGRlcGVuZC5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFuIGluZGljYXRvciB1c2VkIHRvIHJlbGlhYmx5IGRldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBMb25nIG9yIG5vdC5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBMb25nLnByb3RvdHlwZS5fX2lzTG9uZ19fO1xyXG5cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShMb25nLnByb3RvdHlwZSwgXCJfX2lzTG9uZ19fXCIsIHtcclxuICAgICAgICB2YWx1ZTogdHJ1ZSxcclxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlXHJcbiAgICB9KTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBpc0xvbmcob2JqKSB7XHJcbiAgICAgICAgcmV0dXJuIChvYmogJiYgb2JqW1wiX19pc0xvbmdfX1wiXSkgPT09IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhIExvbmcuXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7Kn0gb2JqIE9iamVjdFxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmcuaXNMb25nID0gaXNMb25nO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjYWNoZSBvZiB0aGUgTG9uZyByZXByZXNlbnRhdGlvbnMgb2Ygc21hbGwgaW50ZWdlciB2YWx1ZXMuXHJcbiAgICAgKiBAdHlwZSB7IU9iamVjdH1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgSU5UX0NBQ0hFID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBIGNhY2hlIG9mIHRoZSBMb25nIHJlcHJlc2VudGF0aW9ucyBvZiBzbWFsbCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy5cclxuICAgICAqIEB0eXBlIHshT2JqZWN0fVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBVSU5UX0NBQ0hFID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbUludCh2YWx1ZSwgdW5zaWduZWQpIHtcclxuICAgICAgICB2YXIgb2JqLCBjYWNoZWRPYmosIGNhY2hlO1xyXG4gICAgICAgIGlmICh1bnNpZ25lZCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA+Pj49IDA7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSA9ICgwIDw9IHZhbHVlICYmIHZhbHVlIDwgMjU2KSkge1xyXG4gICAgICAgICAgICAgICAgY2FjaGVkT2JqID0gVUlOVF9DQUNIRVt2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICBpZiAoY2FjaGVkT2JqKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZWRPYmo7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb2JqID0gZnJvbUJpdHModmFsdWUsICh2YWx1ZSB8IDApIDwgMCA/IC0xIDogMCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSlcclxuICAgICAgICAgICAgICAgIFVJTlRfQ0FDSEVbdmFsdWVdID0gb2JqO1xyXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSA9ICgtMTI4IDw9IHZhbHVlICYmIHZhbHVlIDwgMTI4KSkge1xyXG4gICAgICAgICAgICAgICAgY2FjaGVkT2JqID0gSU5UX0NBQ0hFW3ZhbHVlXTtcclxuICAgICAgICAgICAgICAgIGlmIChjYWNoZWRPYmopXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlZE9iajtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvYmogPSBmcm9tQml0cyh2YWx1ZSwgdmFsdWUgPCAwID8gLTEgOiAwLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSlcclxuICAgICAgICAgICAgICAgIElOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XHJcbiAgICAgICAgICAgIHJldHVybiBvYmo7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiAzMiBiaXQgaW50ZWdlciB2YWx1ZS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSAzMiBiaXQgaW50ZWdlciBpbiBxdWVzdGlvblxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbUludCA9IGZyb21JbnQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSwgdW5zaWduZWQpIHtcclxuICAgICAgICBpZiAoaXNOYU4odmFsdWUpIHx8ICFpc0Zpbml0ZSh2YWx1ZSkpXHJcbiAgICAgICAgICAgIHJldHVybiB1bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcclxuICAgICAgICBpZiAodW5zaWduZWQpIHtcclxuICAgICAgICAgICAgaWYgKHZhbHVlIDwgMClcclxuICAgICAgICAgICAgICAgIHJldHVybiBVWkVSTztcclxuICAgICAgICAgICAgaWYgKHZhbHVlID49IFRXT19QV1JfNjRfREJMKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodmFsdWUgPD0gLVRXT19QV1JfNjNfREJMKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1JTl9WQUxVRTtcclxuICAgICAgICAgICAgaWYgKHZhbHVlICsgMSA+PSBUV09fUFdSXzYzX0RCTClcclxuICAgICAgICAgICAgICAgIHJldHVybiBNQVhfVkFMVUU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZSA8IDApXHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tTnVtYmVyKC12YWx1ZSwgdW5zaWduZWQpLm5lZygpO1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cygodmFsdWUgJSBUV09fUFdSXzMyX0RCTCkgfCAwLCAodmFsdWUgLyBUV09fUFdSXzMyX0RCTCkgfCAwLCB1bnNpZ25lZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHZhbHVlLCBwcm92aWRlZCB0aGF0IGl0IGlzIGEgZmluaXRlIG51bWJlci4gT3RoZXJ3aXNlLCB6ZXJvIGlzIHJldHVybmVkLlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIG51bWJlciBpbiBxdWVzdGlvblxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbU51bWJlciA9IGZyb21OdW1iZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93Qml0c1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGZyb21CaXRzKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgTG9uZyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSA2NCBiaXQgaW50ZWdlciB0aGF0IGNvbWVzIGJ5IGNvbmNhdGVuYXRpbmcgdGhlIGdpdmVuIGxvdyBhbmQgaGlnaCBiaXRzLiBFYWNoIGlzXHJcbiAgICAgKiAgYXNzdW1lZCB0byB1c2UgMzIgYml0cy5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHMgVGhlIGxvdyAzMiBiaXRzXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGlnaEJpdHMgVGhlIGhpZ2ggMzIgYml0c1xyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbUJpdHMgPSBmcm9tQml0cztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJhc2VcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBleHBvbmVudFxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgcG93X2RibCA9IE1hdGgucG93OyAvLyBVc2VkIDQgdGltZXMgKDQqOCB0byAxNSs0KVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxyXG4gICAgICogQHBhcmFtIHsoYm9vbGVhbnxudW1iZXIpPX0gdW5zaWduZWRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXhcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBmcm9tU3RyaW5nKHN0ciwgdW5zaWduZWQsIHJhZGl4KSB7XHJcbiAgICAgICAgaWYgKHN0ci5sZW5ndGggPT09IDApXHJcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdlbXB0eSBzdHJpbmcnKTtcclxuICAgICAgICBpZiAoc3RyID09PSBcIk5hTlwiIHx8IHN0ciA9PT0gXCJJbmZpbml0eVwiIHx8IHN0ciA9PT0gXCIrSW5maW5pdHlcIiB8fCBzdHIgPT09IFwiLUluZmluaXR5XCIpXHJcbiAgICAgICAgICAgIHJldHVybiBaRVJPO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdW5zaWduZWQgPT09ICdudW1iZXInKSB7XHJcbiAgICAgICAgICAgIC8vIEZvciBnb29nLm1hdGgubG9uZyBjb21wYXRpYmlsaXR5XHJcbiAgICAgICAgICAgIHJhZGl4ID0gdW5zaWduZWQsXHJcbiAgICAgICAgICAgIHVuc2lnbmVkID0gZmFsc2U7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdW5zaWduZWQgPSAhISB1bnNpZ25lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmFkaXggPSByYWRpeCB8fCAxMDtcclxuICAgICAgICBpZiAocmFkaXggPCAyIHx8IDM2IDwgcmFkaXgpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoJ3JhZGl4Jyk7XHJcblxyXG4gICAgICAgIHZhciBwO1xyXG4gICAgICAgIGlmICgocCA9IHN0ci5pbmRleE9mKCctJykpID4gMClcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2ludGVyaW9yIGh5cGhlbicpO1xyXG4gICAgICAgIGVsc2UgaWYgKHAgPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21TdHJpbmcoc3RyLnN1YnN0cmluZygxKSwgdW5zaWduZWQsIHJhZGl4KS5uZWcoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIERvIHNldmVyYWwgKDgpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cclxuICAgICAgICAvLyBtaW5pbWl6ZSB0aGUgY2FsbHMgdG8gdGhlIHZlcnkgZXhwZW5zaXZlIGVtdWxhdGVkIGRpdi5cclxuICAgICAgICB2YXIgcmFkaXhUb1Bvd2VyID0gZnJvbU51bWJlcihwb3dfZGJsKHJhZGl4LCA4KSk7XHJcblxyXG4gICAgICAgIHZhciByZXN1bHQgPSBaRVJPO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSArPSA4KSB7XHJcbiAgICAgICAgICAgIHZhciBzaXplID0gTWF0aC5taW4oOCwgc3RyLmxlbmd0aCAtIGkpLFxyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUludChzdHIuc3Vic3RyaW5nKGksIGkgKyBzaXplKSwgcmFkaXgpO1xyXG4gICAgICAgICAgICBpZiAoc2l6ZSA8IDgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBwb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgc2l6ZSkpO1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChwb3dlcikuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5tdWwocmFkaXhUb1Bvd2VyKTtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlc3VsdC51bnNpZ25lZCA9IHVuc2lnbmVkO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gc3RyaW5nLCB3cml0dGVuIHVzaW5nIHRoZSBzcGVjaWZpZWQgcmFkaXguXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIExvbmdcclxuICAgICAqIEBwYXJhbSB7KGJvb2xlYW58bnVtYmVyKT19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBgZmFsc2VgIGZvciBzaWduZWRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXggVGhlIHJhZGl4IGluIHdoaWNoIHRoZSB0ZXh0IGlzIHdyaXR0ZW4gKDItMzYpLCBkZWZhdWx0cyB0byAxMFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbVN0cmluZyA9IGZyb21TdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbVZhbHVlKHZhbCkge1xyXG4gICAgICAgIGlmICh2YWwgLyogaXMgY29tcGF0aWJsZSAqLyBpbnN0YW5jZW9mIExvbmcpXHJcbiAgICAgICAgICAgIHJldHVybiB2YWw7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbU51bWJlcih2YWwpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21TdHJpbmcodmFsKTtcclxuICAgICAgICAvLyBUaHJvd3MgZm9yIG5vbi1vYmplY3RzLCBjb252ZXJ0cyBub24taW5zdGFuY2VvZiBMb25nOlxyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh2YWwubG93LCB2YWwuaGlnaCwgdmFsLnVuc2lnbmVkKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgdmFsdWUgdG8gYSBMb25nLlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd8IXtsb3c6IG51bWJlciwgaGlnaDogbnVtYmVyLCB1bnNpZ25lZDogYm9vbGVhbn19IHZhbCBWYWx1ZVxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLmZyb21WYWx1ZSA9IGZyb21WYWx1ZTtcclxuXHJcbiAgICAvLyBOT1RFOiB0aGUgY29tcGlsZXIgc2hvdWxkIGlubGluZSB0aGVzZSBjb25zdGFudCB2YWx1ZXMgYmVsb3cgYW5kIHRoZW4gcmVtb3ZlIHRoZXNlIHZhcmlhYmxlcywgc28gdGhlcmUgc2hvdWxkIGJlXHJcbiAgICAvLyBubyBydW50aW1lIHBlbmFsdHkgZm9yIHRoZXNlLlxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBUV09fUFdSXzE2X0RCTCA9IDEgPDwgMTY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfMjRfREJMID0gMSA8PCAyNDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgVFdPX1BXUl8zMl9EQkwgPSBUV09fUFdSXzE2X0RCTCAqIFRXT19QV1JfMTZfREJMO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBUV09fUFdSXzY0X0RCTCA9IFRXT19QV1JfMzJfREJMICogVFdPX1BXUl8zMl9EQkw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfNjNfREJMID0gVFdPX1BXUl82NF9EQkwgLyAyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfMjQgPSBmcm9tSW50KFRXT19QV1JfMjRfREJMKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgWkVSTyA9IGZyb21JbnQoMCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTaWduZWQgemVyby5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5aRVJPID0gWkVSTztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgVVpFUk8gPSBmcm9tSW50KDAsIHRydWUpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVW5zaWduZWQgemVyby5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5VWkVSTyA9IFVaRVJPO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBPTkUgPSBmcm9tSW50KDEpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2lnbmVkIG9uZS5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5PTkUgPSBPTkU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFVPTkUgPSBmcm9tSW50KDEsIHRydWUpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVW5zaWduZWQgb25lLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLlVPTkUgPSBVT05FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBORUdfT05FID0gZnJvbUludCgtMSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTaWduZWQgbmVnYXRpdmUgb25lLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLk5FR19PTkUgPSBORUdfT05FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBNQVhfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGfDAsIDB4N0ZGRkZGRkZ8MCwgZmFsc2UpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWF4aW11bSBzaWduZWQgdmFsdWUuXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmcuTUFYX1ZBTFVFID0gTUFYX1ZBTFVFO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBNQVhfVU5TSUdORURfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGfDAsIDB4RkZGRkZGRkZ8MCwgdHJ1ZSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYXhpbXVtIHVuc2lnbmVkIHZhbHVlLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLk1BWF9VTlNJR05FRF9WQUxVRSA9IE1BWF9VTlNJR05FRF9WQUxVRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgTUlOX1ZBTFVFID0gZnJvbUJpdHMoMCwgMHg4MDAwMDAwMHwwLCBmYWxzZSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNaW5pbXVtIHNpZ25lZCB2YWx1ZS5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5NSU5fVkFMVUUgPSBNSU5fVkFMVUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAYWxpYXMgTG9uZy5wcm90b3R5cGVcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgTG9uZ1Byb3RvdHlwZSA9IExvbmcucHJvdG90eXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSAzMiBiaXQgaW50ZWdlciwgYXNzdW1pbmcgaXQgaXMgYSAzMiBiaXQgaW50ZWdlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUudG9JbnQgPSBmdW5jdGlvbiB0b0ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IHRoaXMubG93ID4+PiAwIDogdGhpcy5sb3c7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSB0aGUgbmVhcmVzdCBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZhbHVlIChkb3VibGUsIDUzIGJpdCBtYW50aXNzYSkuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgICAgIHJldHVybiAoKHRoaXMuaGlnaCA+Pj4gMCkgKiBUV09fUFdSXzMyX0RCTCkgKyAodGhpcy5sb3cgPj4+IDApO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2ggKiBUV09fUFdSXzMyX0RCTCArICh0aGlzLmxvdyA+Pj4gMCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSBzdHJpbmcgd3JpdHRlbiBpbiB0aGUgc3BlY2lmaWVkIHJhZGl4LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSByYWRpeCBSYWRpeCAoMi0zNiksIGRlZmF1bHRzIHRvIDEwXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxyXG4gICAgICogQG92ZXJyaWRlXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgcmFkaXhgIGlzIG91dCBvZiByYW5nZVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcocmFkaXgpIHtcclxuICAgICAgICByYWRpeCA9IHJhZGl4IHx8IDEwO1xyXG4gICAgICAgIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeClcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcigncmFkaXgnKTtcclxuICAgICAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuICcwJztcclxuICAgICAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHsgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcclxuICAgICAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gY2hhbmdlIHRoZSBMb25nIHZhbHVlIGJlZm9yZSBpdCBjYW4gYmUgbmVnYXRlZCwgc28gd2UgcmVtb3ZlXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgYm90dG9tLW1vc3QgZGlnaXQgaW4gdGhpcyBiYXNlIGFuZCB0aGVuIHJlY3Vyc2UgdG8gZG8gdGhlIHJlc3QuXHJcbiAgICAgICAgICAgICAgICB2YXIgcmFkaXhMb25nID0gZnJvbU51bWJlcihyYWRpeCksXHJcbiAgICAgICAgICAgICAgICAgICAgZGl2ID0gdGhpcy5kaXYocmFkaXhMb25nKSxcclxuICAgICAgICAgICAgICAgICAgICByZW0xID0gZGl2Lm11bChyYWRpeExvbmcpLnN1Yih0aGlzKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkaXYudG9TdHJpbmcocmFkaXgpICsgcmVtMS50b0ludCgpLnRvU3RyaW5nKHJhZGl4KTtcclxuICAgICAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJy0nICsgdGhpcy5uZWcoKS50b1N0cmluZyhyYWRpeCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEbyBzZXZlcmFsICg2KSBkaWdpdHMgZWFjaCB0aW1lIHRocm91Z2ggdGhlIGxvb3AsIHNvIGFzIHRvXHJcbiAgICAgICAgLy8gbWluaW1pemUgdGhlIGNhbGxzIHRvIHRoZSB2ZXJ5IGV4cGVuc2l2ZSBlbXVsYXRlZCBkaXYuXHJcbiAgICAgICAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgNiksIHRoaXMudW5zaWduZWQpLFxyXG4gICAgICAgICAgICByZW0gPSB0aGlzO1xyXG4gICAgICAgIHZhciByZXN1bHQgPSAnJztcclxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xyXG4gICAgICAgICAgICB2YXIgcmVtRGl2ID0gcmVtLmRpdihyYWRpeFRvUG93ZXIpLFxyXG4gICAgICAgICAgICAgICAgaW50dmFsID0gcmVtLnN1YihyZW1EaXYubXVsKHJhZGl4VG9Qb3dlcikpLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgICAgICBkaWdpdHMgPSBpbnR2YWwudG9TdHJpbmcocmFkaXgpO1xyXG4gICAgICAgICAgICByZW0gPSByZW1EaXY7XHJcbiAgICAgICAgICAgIGlmIChyZW0uaXNaZXJvKCkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZGlnaXRzICsgcmVzdWx0O1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChkaWdpdHMubGVuZ3RoIDwgNilcclxuICAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAnMCcgKyBkaWdpdHM7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSAnJyArIGRpZ2l0cyArIHJlc3VsdDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFNpZ25lZCBoaWdoIGJpdHNcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0cyA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2g7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgaGlnaCAzMiBiaXRzIGFzIGFuIHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBoaWdoIGJpdHNcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0SGlnaEJpdHNVbnNpZ25lZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWdoID4+PiAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgbG93IGJpdHNcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzID0gZnVuY3Rpb24gZ2V0TG93Qml0cygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sb3c7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFVuc2lnbmVkIGxvdyBiaXRzXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ2V0TG93Qml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0TG93Qml0c1Vuc2lnbmVkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxvdyA+Pj4gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgYml0cyBuZWVkZWQgdG8gcmVwcmVzZW50IHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGlzIExvbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmdldE51bUJpdHNBYnMgPSBmdW5jdGlvbiBnZXROdW1CaXRzQWJzKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVxKE1JTl9WQUxVRSkgPyA2NCA6IHRoaXMubmVnKCkuZ2V0TnVtQml0c0FicygpO1xyXG4gICAgICAgIHZhciB2YWwgPSB0aGlzLmhpZ2ggIT0gMCA/IHRoaXMuaGlnaCA6IHRoaXMubG93O1xyXG4gICAgICAgIGZvciAodmFyIGJpdCA9IDMxOyBiaXQgPiAwOyBiaXQtLSlcclxuICAgICAgICAgICAgaWYgKCh2YWwgJiAoMSA8PCBiaXQpKSAhPSAwKVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaGlnaCAhPSAwID8gYml0ICsgMzMgOiBiaXQgKyAxO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB6ZXJvLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuaXNaZXJvID0gZnVuY3Rpb24gaXNaZXJvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2ggPT09IDAgJiYgdGhpcy5sb3cgPT09IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbmVnYXRpdmUuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5pc05lZ2F0aXZlID0gZnVuY3Rpb24gaXNOZWdhdGl2ZSgpIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMudW5zaWduZWQgJiYgdGhpcy5oaWdoIDwgMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBwb3NpdGl2ZS5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmlzUG9zaXRpdmUgPSBmdW5jdGlvbiBpc1Bvc2l0aXZlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnVuc2lnbmVkIHx8IHRoaXMuaGlnaCA+PSAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG9kZC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmlzT2RkID0gZnVuY3Rpb24gaXNPZGQoKSB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAxO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGV2ZW4uXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5pc0V2ZW4gPSBmdW5jdGlvbiBpc0V2ZW4oKSB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMob3RoZXIpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgICAgICBpZiAodGhpcy51bnNpZ25lZCAhPT0gb3RoZXIudW5zaWduZWQgJiYgKHRoaXMuaGlnaCA+Pj4gMzEpID09PSAxICYmIChvdGhlci5oaWdoID4+PiAzMSkgPT09IDEpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWdoID09PSBvdGhlci5oaWdoICYmIHRoaXMubG93ID09PSBvdGhlci5sb3c7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNlcXVhbHN9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5lcSA9IExvbmdQcm90b3R5cGUuZXF1YWxzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBzcGVjaWZpZWQncy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm5vdEVxdWFscyA9IGZ1bmN0aW9uIG5vdEVxdWFscyhvdGhlcikge1xyXG4gICAgICAgIHJldHVybiAhdGhpcy5lcSgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubmVxID0gTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubGVzc1RoYW4gPSBmdW5jdGlvbiBsZXNzVGhhbihvdGhlcikge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA8IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmx0ID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBsZXNzVGhhbk9yRXF1YWwob3RoZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPD0gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFuT3JFcXVhbH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmx0ZSA9IExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQncy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuID0gZnVuY3Rpb24gZ3JlYXRlclRoYW4ob3RoZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPiAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW59LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5ndCA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsID0gZnVuY3Rpb24gZ3JlYXRlclRoYW5PckVxdWFsKG90aGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID49IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbk9yRXF1YWx9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5ndGUgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbXBhcmVzIHRoaXMgTG9uZydzIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxyXG4gICAgICogIGlmIHRoZSBnaXZlbiBvbmUgaXMgZ3JlYXRlclxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICAgICAgaWYgKHRoaXMuZXEob3RoZXIpKVxyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB2YXIgdGhpc05lZyA9IHRoaXMuaXNOZWdhdGl2ZSgpLFxyXG4gICAgICAgICAgICBvdGhlck5lZyA9IG90aGVyLmlzTmVnYXRpdmUoKTtcclxuICAgICAgICBpZiAodGhpc05lZyAmJiAhb3RoZXJOZWcpXHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICBpZiAoIXRoaXNOZWcgJiYgb3RoZXJOZWcpXHJcbiAgICAgICAgICAgIHJldHVybiAxO1xyXG4gICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHNpZ24gYml0cyBhcmUgdGhlIHNhbWVcclxuICAgICAgICBpZiAoIXRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN1YihvdGhlcikuaXNOZWdhdGl2ZSgpID8gLTEgOiAxO1xyXG4gICAgICAgIC8vIEJvdGggYXJlIHBvc2l0aXZlIGlmIGF0IGxlYXN0IG9uZSBpcyB1bnNpZ25lZFxyXG4gICAgICAgIHJldHVybiAob3RoZXIuaGlnaCA+Pj4gMCkgPiAodGhpcy5oaWdoID4+PiAwKSB8fCAob3RoZXIuaGlnaCA9PT0gdGhpcy5oaWdoICYmIChvdGhlci5sb3cgPj4+IDApID4gKHRoaXMubG93ID4+PiAwKSkgPyAtMSA6IDE7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY29tcGFyZX0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcclxuICAgICAqICBpZiB0aGUgZ2l2ZW4gb25lIGlzIGdyZWF0ZXJcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5jb21wID0gTG9uZ1Byb3RvdHlwZS5jb21wYXJlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS5cclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubmVnYXRlID0gZnVuY3Rpb24gbmVnYXRlKCkge1xyXG4gICAgICAgIGlmICghdGhpcy51bnNpZ25lZCAmJiB0aGlzLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgIHJldHVybiBNSU5fVkFMVUU7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubm90KCkuYWRkKE9ORSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNuZWdhdGV9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IE5lZ2F0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm5lZyA9IExvbmdQcm90b3R5cGUubmVnYXRlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgc3VtIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gYWRkZW5kIEFkZGVuZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTdW1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQoYWRkZW5kKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcoYWRkZW5kKSlcclxuICAgICAgICAgICAgYWRkZW5kID0gZnJvbVZhbHVlKGFkZGVuZCk7XHJcblxyXG4gICAgICAgIC8vIERpdmlkZSBlYWNoIG51bWJlciBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIHN1bSB0aGUgY2h1bmtzLlxyXG5cclxuICAgICAgICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xyXG4gICAgICAgIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYjQ4ID0gYWRkZW5kLmhpZ2ggPj4+IDE2O1xyXG4gICAgICAgIHZhciBiMzIgPSBhZGRlbmQuaGlnaCAmIDB4RkZGRjtcclxuICAgICAgICB2YXIgYjE2ID0gYWRkZW5kLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGIwMCA9IGFkZGVuZC5sb3cgJiAweEZGRkY7XHJcblxyXG4gICAgICAgIHZhciBjNDggPSAwLCBjMzIgPSAwLCBjMTYgPSAwLCBjMDAgPSAwO1xyXG4gICAgICAgIGMwMCArPSBhMDAgKyBiMDA7XHJcbiAgICAgICAgYzE2ICs9IGMwMCA+Pj4gMTY7XHJcbiAgICAgICAgYzAwICY9IDB4RkZGRjtcclxuICAgICAgICBjMTYgKz0gYTE2ICsgYjE2O1xyXG4gICAgICAgIGMzMiArPSBjMTYgPj4+IDE2O1xyXG4gICAgICAgIGMxNiAmPSAweEZGRkY7XHJcbiAgICAgICAgYzMyICs9IGEzMiArIGIzMjtcclxuICAgICAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgICAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgICAgIGM0OCArPSBhNDggKyBiNDg7XHJcbiAgICAgICAgYzQ4ICY9IDB4RkZGRjtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMoKGMxNiA8PCAxNikgfCBjMDAsIChjNDggPDwgMTYpIHwgYzMyLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gc3VidHJhaGVuZCBTdWJ0cmFoZW5kXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IERpZmZlcmVuY2VcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdCA9IGZ1bmN0aW9uIHN1YnRyYWN0KHN1YnRyYWhlbmQpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhzdWJ0cmFoZW5kKSlcclxuICAgICAgICAgICAgc3VidHJhaGVuZCA9IGZyb21WYWx1ZShzdWJ0cmFoZW5kKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5hZGQoc3VidHJhaGVuZC5uZWcoKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc3VidHJhY3R9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc3ViID0gTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUHJvZHVjdFxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm11bHRpcGx5ID0gZnVuY3Rpb24gbXVsdGlwbHkobXVsdGlwbGllcikge1xyXG4gICAgICAgIGlmICh0aGlzLmlzWmVybygpKVxyXG4gICAgICAgICAgICByZXR1cm4gWkVSTztcclxuICAgICAgICBpZiAoIWlzTG9uZyhtdWx0aXBsaWVyKSlcclxuICAgICAgICAgICAgbXVsdGlwbGllciA9IGZyb21WYWx1ZShtdWx0aXBsaWVyKTtcclxuICAgICAgICBpZiAobXVsdGlwbGllci5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuIFpFUk87XHJcbiAgICAgICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgcmV0dXJuIG11bHRpcGxpZXIuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XHJcbiAgICAgICAgaWYgKG11bHRpcGxpZXIuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xyXG4gICAgICAgICAgICBpZiAobXVsdGlwbGllci5pc05lZ2F0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5tdWwobXVsdGlwbGllci5uZWcoKSk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5lZygpLm11bChtdWx0aXBsaWVyKS5uZWcoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKG11bHRpcGxpZXIuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5tdWwobXVsdGlwbGllci5uZWcoKSkubmVnKCk7XHJcblxyXG4gICAgICAgIC8vIElmIGJvdGggbG9uZ3MgYXJlIHNtYWxsLCB1c2UgZmxvYXQgbXVsdGlwbGljYXRpb25cclxuICAgICAgICBpZiAodGhpcy5sdChUV09fUFdSXzI0KSAmJiBtdWx0aXBsaWVyLmx0KFRXT19QV1JfMjQpKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLnRvTnVtYmVyKCkgKiBtdWx0aXBsaWVyLnRvTnVtYmVyKCksIHRoaXMudW5zaWduZWQpO1xyXG5cclxuICAgICAgICAvLyBEaXZpZGUgZWFjaCBsb25nIGludG8gNCBjaHVua3Mgb2YgMTYgYml0cywgYW5kIHRoZW4gYWRkIHVwIDR4NCBwcm9kdWN0cy5cclxuICAgICAgICAvLyBXZSBjYW4gc2tpcCBwcm9kdWN0cyB0aGF0IHdvdWxkIG92ZXJmbG93LlxyXG5cclxuICAgICAgICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xyXG4gICAgICAgIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYjQ4ID0gbXVsdGlwbGllci5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYjMyID0gbXVsdGlwbGllci5oaWdoICYgMHhGRkZGO1xyXG4gICAgICAgIHZhciBiMTYgPSBtdWx0aXBsaWVyLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGIwMCA9IG11bHRpcGxpZXIubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYzQ4ID0gMCwgYzMyID0gMCwgYzE2ID0gMCwgYzAwID0gMDtcclxuICAgICAgICBjMDAgKz0gYTAwICogYjAwO1xyXG4gICAgICAgIGMxNiArPSBjMDAgPj4+IDE2O1xyXG4gICAgICAgIGMwMCAmPSAweEZGRkY7XHJcbiAgICAgICAgYzE2ICs9IGExNiAqIGIwMDtcclxuICAgICAgICBjMzIgKz0gYzE2ID4+PiAxNjtcclxuICAgICAgICBjMTYgJj0gMHhGRkZGO1xyXG4gICAgICAgIGMxNiArPSBhMDAgKiBiMTY7XHJcbiAgICAgICAgYzMyICs9IGMxNiA+Pj4gMTY7XHJcbiAgICAgICAgYzE2ICY9IDB4RkZGRjtcclxuICAgICAgICBjMzIgKz0gYTMyICogYjAwO1xyXG4gICAgICAgIGM0OCArPSBjMzIgPj4+IDE2O1xyXG4gICAgICAgIGMzMiAmPSAweEZGRkY7XHJcbiAgICAgICAgYzMyICs9IGExNiAqIGIxNjtcclxuICAgICAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgICAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgICAgIGMzMiArPSBhMDAgKiBiMzI7XHJcbiAgICAgICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICAgICAgYzMyICY9IDB4RkZGRjtcclxuICAgICAgICBjNDggKz0gYTQ4ICogYjAwICsgYTMyICogYjE2ICsgYTE2ICogYjMyICsgYTAwICogYjQ4O1xyXG4gICAgICAgIGM0OCAmPSAweEZGRkY7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKChjMTYgPDwgMTYpIHwgYzAwLCAoYzQ4IDw8IDE2KSB8IGMzMiwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgcHJvZHVjdCBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbXVsdGlwbHl9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG11bHRpcGxpZXIgTXVsdGlwbGllclxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBQcm9kdWN0XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubXVsID0gTG9uZ1Byb3RvdHlwZS5tdWx0aXBseTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhlIHJlc3VsdCBpcyBzaWduZWQgaWYgdGhpcyBMb25nIGlzIHNpZ25lZCBvclxyXG4gICAgICogIHVuc2lnbmVkIGlmIHRoaXMgTG9uZyBpcyB1bnNpZ25lZC5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZGl2aWRlID0gZnVuY3Rpb24gZGl2aWRlKGRpdmlzb3IpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhkaXZpc29yKSlcclxuICAgICAgICAgICAgZGl2aXNvciA9IGZyb21WYWx1ZShkaXZpc29yKTtcclxuICAgICAgICBpZiAoZGl2aXNvci5pc1plcm8oKSlcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2RpdmlzaW9uIGJ5IHplcm8nKTtcclxuICAgICAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XHJcbiAgICAgICAgdmFyIGFwcHJveCwgcmVtLCByZXM7XHJcbiAgICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkKSB7XHJcbiAgICAgICAgICAgIC8vIFRoaXMgc2VjdGlvbiBpcyBvbmx5IHJlbGV2YW50IGZvciBzaWduZWQgbG9uZ3MgYW5kIGlzIGRlcml2ZWQgZnJvbSB0aGVcclxuICAgICAgICAgICAgLy8gY2xvc3VyZSBsaWJyYXJ5IGFzIGEgd2hvbGUuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChkaXZpc29yLmVxKE9ORSkgfHwgZGl2aXNvci5lcShORUdfT05FKSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTUlOX1ZBTFVFOyAgLy8gcmVjYWxsIHRoYXQgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUVcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRpdmlzb3IuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gT05FO1xyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgd2UgaGF2ZSB8b3RoZXJ8ID49IDIsIHNvIHx0aGlzL290aGVyfCA8IHxNSU5fVkFMVUV8LlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYWxmVGhpcyA9IHRoaXMuc2hyKDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFwcHJveCA9IGhhbGZUaGlzLmRpdihkaXZpc29yKS5zaGwoMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFwcHJveC5lcShaRVJPKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGl2aXNvci5pc05lZ2F0aXZlKCkgPyBPTkUgOiBORUdfT05FO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbSA9IHRoaXMuc3ViKGRpdmlzb3IubXVsKGFwcHJveCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXMgPSBhcHByb3guYWRkKHJlbS5kaXYoZGl2aXNvcikpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkuZGl2KGRpdmlzb3IubmVnKCkpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkuZGl2KGRpdmlzb3IpLm5lZygpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGl2KGRpdmlzb3IubmVnKCkpLm5lZygpO1xyXG4gICAgICAgICAgICByZXMgPSBaRVJPO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFRoZSBhbGdvcml0aG0gYmVsb3cgaGFzIG5vdCBiZWVuIG1hZGUgZm9yIHVuc2lnbmVkIGxvbmdzLiBJdCdzIHRoZXJlZm9yZVxyXG4gICAgICAgICAgICAvLyByZXF1aXJlZCB0byB0YWtlIHNwZWNpYWwgY2FyZSBvZiB0aGUgTVNCIHByaW9yIHRvIHJ1bm5pbmcgaXQuXHJcbiAgICAgICAgICAgIGlmICghZGl2aXNvci51bnNpZ25lZClcclxuICAgICAgICAgICAgICAgIGRpdmlzb3IgPSBkaXZpc29yLnRvVW5zaWduZWQoKTtcclxuICAgICAgICAgICAgaWYgKGRpdmlzb3IuZ3QodGhpcykpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVVpFUk87XHJcbiAgICAgICAgICAgIGlmIChkaXZpc29yLmd0KHRoaXMuc2hydSgxKSkpIC8vIDE1ID4+PiAxID0gNyA7IHdpdGggZGl2aXNvciA9IDggOyB0cnVlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVU9ORTtcclxuICAgICAgICAgICAgcmVzID0gVVpFUk87XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZXBlYXQgdGhlIGZvbGxvd2luZyB1bnRpbCB0aGUgcmVtYWluZGVyIGlzIGxlc3MgdGhhbiBvdGhlcjogIGZpbmQgYVxyXG4gICAgICAgIC8vIGZsb2F0aW5nLXBvaW50IHRoYXQgYXBwcm94aW1hdGVzIHJlbWFpbmRlciAvIG90aGVyICpmcm9tIGJlbG93KiwgYWRkIHRoaXNcclxuICAgICAgICAvLyBpbnRvIHRoZSByZXN1bHQsIGFuZCBzdWJ0cmFjdCBpdCBmcm9tIHRoZSByZW1haW5kZXIuICBJdCBpcyBjcml0aWNhbCB0aGF0XHJcbiAgICAgICAgLy8gdGhlIGFwcHJveGltYXRlIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgcmVhbCB2YWx1ZSBzbyB0aGF0IHRoZVxyXG4gICAgICAgIC8vIHJlbWFpbmRlciBuZXZlciBiZWNvbWVzIG5lZ2F0aXZlLlxyXG4gICAgICAgIHJlbSA9IHRoaXM7XHJcbiAgICAgICAgd2hpbGUgKHJlbS5ndGUoZGl2aXNvcikpIHtcclxuICAgICAgICAgICAgLy8gQXBwcm94aW1hdGUgdGhlIHJlc3VsdCBvZiBkaXZpc2lvbi4gVGhpcyBtYXkgYmUgYSBsaXR0bGUgZ3JlYXRlciBvclxyXG4gICAgICAgICAgICAvLyBzbWFsbGVyIHRoYW4gdGhlIGFjdHVhbCB2YWx1ZS5cclxuICAgICAgICAgICAgYXBwcm94ID0gTWF0aC5tYXgoMSwgTWF0aC5mbG9vcihyZW0udG9OdW1iZXIoKSAvIGRpdmlzb3IudG9OdW1iZXIoKSkpO1xyXG5cclxuICAgICAgICAgICAgLy8gV2Ugd2lsbCB0d2VhayB0aGUgYXBwcm94aW1hdGUgcmVzdWx0IGJ5IGNoYW5naW5nIGl0IGluIHRoZSA0OC10aCBkaWdpdCBvclxyXG4gICAgICAgICAgICAvLyB0aGUgc21hbGxlc3Qgbm9uLWZyYWN0aW9uYWwgZGlnaXQsIHdoaWNoZXZlciBpcyBsYXJnZXIuXHJcbiAgICAgICAgICAgIHZhciBsb2cyID0gTWF0aC5jZWlsKE1hdGgubG9nKGFwcHJveCkgLyBNYXRoLkxOMiksXHJcbiAgICAgICAgICAgICAgICBkZWx0YSA9IChsb2cyIDw9IDQ4KSA/IDEgOiBwb3dfZGJsKDIsIGxvZzIgLSA0OCksXHJcblxyXG4gICAgICAgICAgICAvLyBEZWNyZWFzZSB0aGUgYXBwcm94aW1hdGlvbiB1bnRpbCBpdCBpcyBzbWFsbGVyIHRoYW4gdGhlIHJlbWFpbmRlci4gIE5vdGVcclxuICAgICAgICAgICAgLy8gdGhhdCBpZiBpdCBpcyB0b28gbGFyZ2UsIHRoZSBwcm9kdWN0IG92ZXJmbG93cyBhbmQgaXMgbmVnYXRpdmUuXHJcbiAgICAgICAgICAgICAgICBhcHByb3hSZXMgPSBmcm9tTnVtYmVyKGFwcHJveCksXHJcbiAgICAgICAgICAgICAgICBhcHByb3hSZW0gPSBhcHByb3hSZXMubXVsKGRpdmlzb3IpO1xyXG4gICAgICAgICAgICB3aGlsZSAoYXBwcm94UmVtLmlzTmVnYXRpdmUoKSB8fCBhcHByb3hSZW0uZ3QocmVtKSkge1xyXG4gICAgICAgICAgICAgICAgYXBwcm94IC09IGRlbHRhO1xyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVzID0gZnJvbU51bWJlcihhcHByb3gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gV2Uga25vdyB0aGUgYW5zd2VyIGNhbid0IGJlIHplcm8uLi4gYW5kIGFjdHVhbGx5LCB6ZXJvIHdvdWxkIGNhdXNlXHJcbiAgICAgICAgICAgIC8vIGluZmluaXRlIHJlY3Vyc2lvbiBzaW5jZSB3ZSB3b3VsZCBtYWtlIG5vIHByb2dyZXNzLlxyXG4gICAgICAgICAgICBpZiAoYXBwcm94UmVzLmlzWmVybygpKVxyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVzID0gT05FO1xyXG5cclxuICAgICAgICAgICAgcmVzID0gcmVzLmFkZChhcHByb3hSZXMpO1xyXG4gICAgICAgICAgICByZW0gPSByZW0uc3ViKGFwcHJveFJlbSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgZGl2aWRlZCBieSB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2RpdmlkZX0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZGl2ID0gTG9uZ1Byb3RvdHlwZS5kaXZpZGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm1vZHVsbyA9IGZ1bmN0aW9uIG1vZHVsbyhkaXZpc29yKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcoZGl2aXNvcikpXHJcbiAgICAgICAgICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViKHRoaXMuZGl2KGRpdmlzb3IpLm11bChkaXZpc29yKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbW9kdWxvfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubW9kID0gTG9uZ1Byb3RvdHlwZS5tb2R1bG87XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBiaXR3aXNlIE5PVCBvZiB0aGlzIExvbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubm90ID0gZnVuY3Rpb24gbm90KCkge1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh+dGhpcy5sb3csIH50aGlzLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGJpdHdpc2UgQU5EIG9mIHRoaXMgTG9uZyBhbmQgdGhlIHNwZWNpZmllZC5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmFuZCA9IGZ1bmN0aW9uIGFuZChvdGhlcikge1xyXG4gICAgICAgIGlmICghaXNMb25nKG90aGVyKSlcclxuICAgICAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyAmIG90aGVyLmxvdywgdGhpcy5oaWdoICYgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgYml0d2lzZSBPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5vciA9IGZ1bmN0aW9uIG9yKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IHwgb3RoZXIubG93LCB0aGlzLmhpZ2ggfCBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBiaXR3aXNlIFhPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBnaXZlbiBvbmUuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS54b3IgPSBmdW5jdGlvbiB4b3Iob3RoZXIpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgXiBvdGhlci5sb3csIHRoaXMuaGlnaCBeIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQgPSBmdW5jdGlvbiBzaGlmdExlZnQobnVtQml0cykge1xyXG4gICAgICAgIGlmIChpc0xvbmcobnVtQml0cykpXHJcbiAgICAgICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICAgICAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgPDwgbnVtQml0cywgKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gKDMyIC0gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tQml0cygwLCB0aGlzLmxvdyA8PCAobnVtQml0cyAtIDMyKSwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHNoaWZ0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdExlZnR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaGwgPSBMb25nUHJvdG90eXBlLnNoaWZ0TGVmdDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc2hpZnRSaWdodCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHQobnVtQml0cykge1xyXG4gICAgICAgIGlmIChpc0xvbmcobnVtQml0cykpXHJcbiAgICAgICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICAgICAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoKHRoaXMubG93ID4+PiBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPDwgKDMyIC0gbnVtQml0cykpLCB0aGlzLmhpZ2ggPj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoID4+IChudW1CaXRzIC0gMzIpLCB0aGlzLmhpZ2ggPj0gMCA/IDAgOiAtMSwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnNociA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHRVbnNpZ25lZChudW1CaXRzKSB7XHJcbiAgICAgICAgaWYgKGlzTG9uZyhudW1CaXRzKSlcclxuICAgICAgICAgICAgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcclxuICAgICAgICBudW1CaXRzICY9IDYzO1xyXG4gICAgICAgIGlmIChudW1CaXRzID09PSAwKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdmFyIGhpZ2ggPSB0aGlzLmhpZ2g7XHJcbiAgICAgICAgICAgIGlmIChudW1CaXRzIDwgMzIpIHtcclxuICAgICAgICAgICAgICAgIHZhciBsb3cgPSB0aGlzLmxvdztcclxuICAgICAgICAgICAgICAgIHJldHVybiBmcm9tQml0cygobG93ID4+PiBudW1CaXRzKSB8IChoaWdoIDw8ICgzMiAtIG51bUJpdHMpKSwgaGlnaCA+Pj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobnVtQml0cyA9PT0gMzIpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoaGlnaCwgMCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiBmcm9tQml0cyhoaWdoID4+PiAobnVtQml0cyAtIDMyKSwgMCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdFJpZ2h0VW5zaWduZWR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaHJ1ID0gTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gc2lnbmVkLlxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvU2lnbmVkID0gZnVuY3Rpb24gdG9TaWduZWQoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgZmFsc2UpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byB1bnNpZ25lZC5cclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gVW5zaWduZWQgbG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvVW5zaWduZWQgPSBmdW5jdGlvbiB0b1Vuc2lnbmVkKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgdHJ1ZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGUgV2hldGhlciBsaXR0bGUgb3IgYmlnIGVuZGlhbiwgZGVmYXVsdHMgdG8gYmlnIGVuZGlhblxyXG4gICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQnl0ZSByZXByZXNlbnRhdGlvblxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvQnl0ZXMgPSBmdW5jdGlvbihsZSkge1xyXG4gICAgICAgIHJldHVybiBsZSA/IHRoaXMudG9CeXRlc0xFKCkgOiB0aGlzLnRvQnl0ZXNCRSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBsaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b0J5dGVzTEUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgaGkgPSB0aGlzLmhpZ2gsXHJcbiAgICAgICAgICAgIGxvID0gdGhpcy5sb3c7XHJcbiAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgIGxvICAgICAgICAgJiAweGZmLFxyXG4gICAgICAgICAgICAobG8gPj4+ICA4KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChsbyA+Pj4gMTYpICYgMHhmZixcclxuICAgICAgICAgICAgKGxvID4+PiAyNCkgJiAweGZmLFxyXG4gICAgICAgICAgICAgaGkgICAgICAgICAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChoaSA+Pj4gIDgpICYgMHhmZixcclxuICAgICAgICAgICAgKGhpID4+PiAxNikgJiAweGZmLFxyXG4gICAgICAgICAgICAoaGkgPj4+IDI0KSAmIDB4ZmZcclxuICAgICAgICBdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBiaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBCaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b0J5dGVzQkUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgaGkgPSB0aGlzLmhpZ2gsXHJcbiAgICAgICAgICAgIGxvID0gdGhpcy5sb3c7XHJcbiAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgKGhpID4+PiAyNCkgJiAweGZmLFxyXG4gICAgICAgICAgICAoaGkgPj4+IDE2KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChoaSA+Pj4gIDgpICYgMHhmZixcclxuICAgICAgICAgICAgIGhpICAgICAgICAgJiAweGZmLFxyXG4gICAgICAgICAgICAobG8gPj4+IDI0KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChsbyA+Pj4gMTYpICYgMHhmZixcclxuICAgICAgICAgICAgKGxvID4+PiAgOCkgJiAweGZmLFxyXG4gICAgICAgICAgICAgbG8gICAgICAgICAmIDB4ZmZcclxuICAgICAgICBdO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBMb25nO1xyXG59KTtcclxuIiwiJ3VzZSBzdHJpY3QnXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaEJhc2UgPSByZXF1aXJlKCdoYXNoLWJhc2UnKVxuXG52YXIgQVJSQVkxNiA9IG5ldyBBcnJheSgxNilcblxuZnVuY3Rpb24gTUQ1ICgpIHtcbiAgSGFzaEJhc2UuY2FsbCh0aGlzLCA2NClcblxuICAvLyBzdGF0ZVxuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxufVxuXG5pbmhlcml0cyhNRDUsIEhhc2hCYXNlKVxuXG5NRDUucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBNID0gQVJSQVkxNlxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIE1baV0gPSB0aGlzLl9ibG9jay5yZWFkSW50MzJMRShpICogNClcblxuICB2YXIgYSA9IHRoaXMuX2FcbiAgdmFyIGIgPSB0aGlzLl9iXG4gIHZhciBjID0gdGhpcy5fY1xuICB2YXIgZCA9IHRoaXMuX2RcblxuICBhID0gZm5GKGEsIGIsIGMsIGQsIE1bMF0sIDB4ZDc2YWE0NzgsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxXSwgMHhlOGM3Yjc1NiwgMTIpXG4gIGMgPSBmbkYoYywgZCwgYSwgYiwgTVsyXSwgMHgyNDIwNzBkYiwgMTcpXG4gIGIgPSBmbkYoYiwgYywgZCwgYSwgTVszXSwgMHhjMWJkY2VlZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVs0XSwgMHhmNTdjMGZhZiwgNylcbiAgZCA9IGZuRihkLCBhLCBiLCBjLCBNWzVdLCAweDQ3ODdjNjJhLCAxMilcbiAgYyA9IGZuRihjLCBkLCBhLCBiLCBNWzZdLCAweGE4MzA0NjEzLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzddLCAweGZkNDY5NTAxLCAyMilcbiAgYSA9IGZuRihhLCBiLCBjLCBkLCBNWzhdLCAweDY5ODA5OGQ4LCA3KVxuICBkID0gZm5GKGQsIGEsIGIsIGMsIE1bOV0sIDB4OGI0NGY3YWYsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTBdLCAweGZmZmY1YmIxLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzExXSwgMHg4OTVjZDdiZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVsxMl0sIDB4NmI5MDExMjIsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxM10sIDB4ZmQ5ODcxOTMsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTRdLCAweGE2Nzk0MzhlLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzE1XSwgMHg0OWI0MDgyMSwgMjIpXG5cbiAgYSA9IGZuRyhhLCBiLCBjLCBkLCBNWzFdLCAweGY2MWUyNTYyLCA1KVxuICBkID0gZm5HKGQsIGEsIGIsIGMsIE1bNl0sIDB4YzA0MGIzNDAsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxMV0sIDB4MjY1ZTVhNTEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bMF0sIDB4ZTliNmM3YWEsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bNV0sIDB4ZDYyZjEwNWQsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxMF0sIDB4MDI0NDE0NTMsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxNV0sIDB4ZDhhMWU2ODEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bNF0sIDB4ZTdkM2ZiYzgsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bOV0sIDB4MjFlMWNkZTYsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxNF0sIDB4YzMzNzA3ZDYsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVszXSwgMHhmNGQ1MGQ4NywgMTQpXG4gIGIgPSBmbkcoYiwgYywgZCwgYSwgTVs4XSwgMHg0NTVhMTRlZCwgMjApXG4gIGEgPSBmbkcoYSwgYiwgYywgZCwgTVsxM10sIDB4YTllM2U5MDUsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsyXSwgMHhmY2VmYTNmOCwgOSlcbiAgYyA9IGZuRyhjLCBkLCBhLCBiLCBNWzddLCAweDY3NmYwMmQ5LCAxNClcbiAgYiA9IGZuRyhiLCBjLCBkLCBhLCBNWzEyXSwgMHg4ZDJhNGM4YSwgMjApXG5cbiAgYSA9IGZuSChhLCBiLCBjLCBkLCBNWzVdLCAweGZmZmEzOTQyLCA0KVxuICBkID0gZm5IKGQsIGEsIGIsIGMsIE1bOF0sIDB4ODc3MWY2ODEsIDExKVxuICBjID0gZm5IKGMsIGQsIGEsIGIsIE1bMTFdLCAweDZkOWQ2MTIyLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzE0XSwgMHhmZGU1MzgwYywgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxXSwgMHhhNGJlZWE0NCwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzRdLCAweDRiZGVjZmE5LCAxMSlcbiAgYyA9IGZuSChjLCBkLCBhLCBiLCBNWzddLCAweGY2YmI0YjYwLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzEwXSwgMHhiZWJmYmM3MCwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxM10sIDB4Mjg5YjdlYzYsIDQpXG4gIGQgPSBmbkgoZCwgYSwgYiwgYywgTVswXSwgMHhlYWExMjdmYSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVszXSwgMHhkNGVmMzA4NSwgMTYpXG4gIGIgPSBmbkgoYiwgYywgZCwgYSwgTVs2XSwgMHgwNDg4MWQwNSwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVs5XSwgMHhkOWQ0ZDAzOSwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzEyXSwgMHhlNmRiOTllNSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVsxNV0sIDB4MWZhMjdjZjgsIDE2KVxuICBiID0gZm5IKGIsIGMsIGQsIGEsIE1bMl0sIDB4YzRhYzU2NjUsIDIzKVxuXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVswXSwgMHhmNDI5MjI0NCwgNilcbiAgZCA9IGZuSShkLCBhLCBiLCBjLCBNWzddLCAweDQzMmFmZjk3LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzE0XSwgMHhhYjk0MjNhNywgMTUpXG4gIGIgPSBmbkkoYiwgYywgZCwgYSwgTVs1XSwgMHhmYzkzYTAzOSwgMjEpXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVsxMl0sIDB4NjU1YjU5YzMsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVszXSwgMHg4ZjBjY2M5MiwgMTApXG4gIGMgPSBmbkkoYywgZCwgYSwgYiwgTVsxMF0sIDB4ZmZlZmY0N2QsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMV0sIDB4ODU4NDVkZDEsIDIxKVxuICBhID0gZm5JKGEsIGIsIGMsIGQsIE1bOF0sIDB4NmZhODdlNGYsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVsxNV0sIDB4ZmUyY2U2ZTAsIDEwKVxuICBjID0gZm5JKGMsIGQsIGEsIGIsIE1bNl0sIDB4YTMwMTQzMTQsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMTNdLCAweDRlMDgxMWExLCAyMSlcbiAgYSA9IGZuSShhLCBiLCBjLCBkLCBNWzRdLCAweGY3NTM3ZTgyLCA2KVxuICBkID0gZm5JKGQsIGEsIGIsIGMsIE1bMTFdLCAweGJkM2FmMjM1LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzJdLCAweDJhZDdkMmJiLCAxNSlcbiAgYiA9IGZuSShiLCBjLCBkLCBhLCBNWzldLCAweGViODZkMzkxLCAyMSlcblxuICB0aGlzLl9hID0gKHRoaXMuX2EgKyBhKSB8IDBcbiAgdGhpcy5fYiA9ICh0aGlzLl9iICsgYikgfCAwXG4gIHRoaXMuX2MgPSAodGhpcy5fYyArIGMpIHwgMFxuICB0aGlzLl9kID0gKHRoaXMuX2QgKyBkKSB8IDBcbn1cblxuTUQ1LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gKCkge1xuICAvLyBjcmVhdGUgcGFkZGluZyBhbmQgaGFuZGxlIGJsb2Nrc1xuICB0aGlzLl9ibG9ja1t0aGlzLl9ibG9ja09mZnNldCsrXSA9IDB4ODBcbiAgaWYgKHRoaXMuX2Jsb2NrT2Zmc2V0ID4gNTYpIHtcbiAgICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA2NClcbiAgICB0aGlzLl91cGRhdGUoKVxuICAgIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB9XG5cbiAgdGhpcy5fYmxvY2suZmlsbCgwLCB0aGlzLl9ibG9ja09mZnNldCwgNTYpXG4gIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyTEUodGhpcy5fbGVuZ3RoWzBdLCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMV0sIDYwKVxuICB0aGlzLl91cGRhdGUoKVxuXG4gIC8vIHByb2R1Y2UgcmVzdWx0XG4gIHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKDE2KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2EsIDApXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYiwgNClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9jLCA4KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2QsIDEyKVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIHJvdGwgKHgsIG4pIHtcbiAgcmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKVxufVxuXG5mdW5jdGlvbiBmbkYgKGEsIGIsIGMsIGQsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiICYgYykgfCAoKH5iKSAmIGQpKSArIG0gKyBrKSB8IDAsIHMpICsgYikgfCAwXG59XG5cbmZ1bmN0aW9uIGZuRyAoYSwgYiwgYywgZCwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgJiBkKSB8IChjICYgKH5kKSkpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxuZnVuY3Rpb24gZm5IIChhLCBiLCBjLCBkLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArIChiIF4gYyBeIGQpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxuZnVuY3Rpb24gZm5JIChhLCBiLCBjLCBkLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYyBeIChiIHwgKH5kKSkpKSArIG0gKyBrKSB8IDAsIHMpICsgYikgfCAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gTUQ1XG4iLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLk1hbmFnZXIgPSBleHBvcnRzLkNoYWluQ29uZmlnID0gZXhwb3J0cy5BcGlzID0gdW5kZWZpbmVkO1xuXG52YXIgX0FwaUluc3RhbmNlcyA9IHJlcXVpcmUoNzEpO1xuXG52YXIgX0FwaUluc3RhbmNlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9BcGlJbnN0YW5jZXMpO1xuXG52YXIgX0Nvbm5lY3Rpb25NYW5hZ2VyID0gcmVxdWlyZSg3NCk7XG5cbnZhciBfQ29ubmVjdGlvbk1hbmFnZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ29ubmVjdGlvbk1hbmFnZXIpO1xuXG52YXIgX0NoYWluQ29uZmlnID0gcmVxdWlyZSg3Mik7XG5cbnZhciBfQ2hhaW5Db25maWcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2hhaW5Db25maWcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5leHBvcnRzLkFwaXMgPSBfQXBpSW5zdGFuY2VzMi5kZWZhdWx0O1xuZXhwb3J0cy5DaGFpbkNvbmZpZyA9IF9DaGFpbkNvbmZpZzIuZGVmYXVsdDtcbmV4cG9ydHMuTWFuYWdlciA9IF9Db25uZWN0aW9uTWFuYWdlcjIuZGVmYXVsdDsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfQ2hhaW5XZWJTb2NrZXQgPSByZXF1aXJlKDczKTtcblxudmFyIF9DaGFpbldlYlNvY2tldDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpbldlYlNvY2tldCk7XG5cbnZhciBfR3JhcGhlbmVBcGkgPSByZXF1aXJlKDc1KTtcblxudmFyIF9HcmFwaGVuZUFwaTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9HcmFwaGVuZUFwaSk7XG5cbnZhciBfQ2hhaW5Db25maWcgPSByZXF1aXJlKDcyKTtcblxudmFyIF9DaGFpbkNvbmZpZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpbkNvbmZpZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBpbnN0ID0gdm9pZCAwO1xuXG52YXIgQXBpc0luc3RhbmNlID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBBcGlzSW5zdGFuY2UoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEFwaXNJbnN0YW5jZSk7XG4gIH1cblxuICAvKiogQGFyZyB7c3RyaW5nfSBjb25uZWN0aW9uIC4uICovXG4gIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uIGNvbm5lY3QoY3MsIGNvbm5lY3RUaW1lb3V0KSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBycGNfdXNlciA9ICcnO1xuICAgIHZhciBycGNfcGFzc3dvcmQgPSAnJztcblxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cubG9jYXRpb24gJiYgd2luZG93LmxvY2F0aW9uLnByb3RvY29sID09PSAnaHR0cHM6JyAmJiBjcy5pbmRleE9mKCd3c3M6Ly8nKSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2VjdXJlIGRvbWFpbnMgcmVxdWlyZSB3c3MgY29ubmVjdGlvbicpO1xuICAgIH1cblxuICAgIHRoaXMud3NfcnBjID0gbmV3IF9DaGFpbldlYlNvY2tldDIuZGVmYXVsdChjcywgdGhpcy5zdGF0dXNDYiwgY29ubmVjdFRpbWVvdXQpO1xuXG4gICAgdGhpcy5pbml0X3Byb21pc2UgPSB0aGlzLndzX3JwYy5sb2dpbihycGNfdXNlciwgcnBjX3Bhc3N3b3JkKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdDb25uZWN0ZWQgdG8gQVBJIG5vZGU6JywgY3MpO1xuICAgICAgX3RoaXMuX2RiID0gbmV3IF9HcmFwaGVuZUFwaTIuZGVmYXVsdChfdGhpcy53c19ycGMsICdkYXRhYmFzZScpO1xuICAgICAgX3RoaXMuX25ldCA9IG5ldyBfR3JhcGhlbmVBcGkyLmRlZmF1bHQoX3RoaXMud3NfcnBjLCAnbmV0d29ya19icm9hZGNhc3QnKTtcbiAgICAgIF90aGlzLl9oaXN0ID0gbmV3IF9HcmFwaGVuZUFwaTIuZGVmYXVsdChfdGhpcy53c19ycGMsICdoaXN0b3J5Jyk7XG4gICAgICBfdGhpcy5fY3J5cHRvID0gbmV3IF9HcmFwaGVuZUFwaTIuZGVmYXVsdChfdGhpcy53c19ycGMsICdjcnlwdG8nKTtcbiAgICAgIF90aGlzLl9ib29raWUgPSBuZXcgX0dyYXBoZW5lQXBpMi5kZWZhdWx0KF90aGlzLndzX3JwYywgJ2Jvb2tpZScpO1xuICAgICAgdmFyIGRiX3Byb21pc2UgPSBfdGhpcy5fZGIuaW5pdCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gX3RoaXMuX2RiLmV4ZWMoJ2dldF9jaGFpbl9pZCcsIFtdKS50aGVuKGZ1bmN0aW9uIChfY2hhaW5faWQpIHtcbiAgICAgICAgICBfdGhpcy5jaGFpbl9pZCA9IF9jaGFpbl9pZDtcbiAgICAgICAgICByZXR1cm4gX0NoYWluQ29uZmlnMi5kZWZhdWx0LnNldENoYWluSWQoX2NoYWluX2lkKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgX3RoaXMud3NfcnBjLm9uX3JlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3RoaXMud3NfcnBjLmxvZ2luKCcnLCAnJykudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgX3RoaXMuX2RiLmluaXQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5zdGF0dXNDYikge1xuICAgICAgICAgICAgICBfdGhpcy5zdGF0dXNDYihfQ2hhaW5XZWJTb2NrZXQyLmRlZmF1bHQuc3RhdHVzLlJFQ09OTkVDVEVEKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBfdGhpcy5fbmV0LmluaXQoKTtcbiAgICAgICAgICBfdGhpcy5faGlzdC5pbml0KCk7XG4gICAgICAgICAgX3RoaXMuX2NyeXB0by5pbml0KCk7XG4gICAgICAgICAgX3RoaXMuX2Jvb2tpZS5pbml0KCk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtkYl9wcm9taXNlLCBfdGhpcy5fbmV0LmluaXQoKSwgX3RoaXMuX2hpc3QuaW5pdCgpLFxuICAgICAgLy8gVGVtcG9yYXJ5IHNxdWFzaCBjcnlwdG8gQVBJIGVycm9yIHVudGlsIHRoZSBBUEkgaXMgdXBncmFkZWQgZXZlcnl3aGVyZVxuICAgICAgX3RoaXMuX2NyeXB0by5pbml0KCkuY2F0Y2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoJ0FwaUluc3RhbmNlXFx0Q3J5cHRvIEFQSSBFcnJvcicsIGUpO1xuICAgICAgfSksIF90aGlzLl9ib29raWUuaW5pdCgpXSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uIGNsb3NlKCkge1xuICAgIGlmICh0aGlzLndzX3JwYykge1xuICAgICAgdGhpcy53c19ycGMuY2xvc2UoKTtcbiAgICB9XG5cbiAgICB0aGlzLndzX3JwYyA9IG51bGw7XG4gIH07XG5cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5kYl9hcGkgPSBmdW5jdGlvbiBkYl9hcGkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RiO1xuICB9O1xuXG4gIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUubmV0d29ya19hcGkgPSBmdW5jdGlvbiBuZXR3b3JrX2FwaSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbmV0O1xuICB9O1xuXG4gIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUuaGlzdG9yeV9hcGkgPSBmdW5jdGlvbiBoaXN0b3J5X2FwaSgpIHtcbiAgICByZXR1cm4gdGhpcy5faGlzdDtcbiAgfTtcblxuICBBcGlzSW5zdGFuY2UucHJvdG90eXBlLmNyeXB0b19hcGkgPSBmdW5jdGlvbiBjcnlwdG9fYXBpKCkge1xuICAgIHJldHVybiB0aGlzLl9jcnlwdG87XG4gIH07XG5cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5ib29raWVfYXBpID0gZnVuY3Rpb24gYm9va2llX2FwaSgpIHtcbiAgICByZXR1cm4gdGhpcy5fYm9va2llO1xuICB9O1xuXG4gIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUuc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrID0gZnVuY3Rpb24gc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5zdGF0dXNDYiA9IGNhbGxiYWNrO1xuICB9O1xuXG4gIHJldHVybiBBcGlzSW5zdGFuY2U7XG59KCk7XG5cbi8qKlxuICAgIENvbmZpZ3VyZTogY29uZmlndXJlIGFzIGZvbGxvd3MgYEFwaXMuaW5zdGFuY2UoXCJ3czovL2xvY2FsaG9zdDo4MDkwXCIpLmluaXRfcHJvbWlzZWAuICBUaGlzXG4gICAgcmV0dXJucyBhIHByb21pc2UsIG9uY2UgcmVzb2x2ZWQgdGhlIGNvbm5lY3Rpb24gaXMgcmVhZHkuXG5cbiAgICBJbXBvcnQ6IGltcG9ydCB7IEFwaXMgfSBmcm9tIFwiQGdyYXBoZW5lL2NoYWluXCJcblxuICAgIFNob3J0LWhhbmQ6IEFwaXMuZGIoXCJtZXRob2RcIiwgXCJwYXJtMVwiLCAyLCAzLCAuLi4pLiAgUmV0dXJucyBhIHByb21pc2Ugd2l0aCByZXN1bHRzLlxuXG4gICAgQWRkaXRpb25hbCB1c2FnZTogQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoXCJtZXRob2RcIiwgW1wibWV0aG9kXCIsIFwicGFybTFcIiwgMiwgMywgLi4uXSkuXG4gICAgUmV0dXJucyBhIHByb21pc2Ugd2l0aCByZXN1bHRzLlxuKi9cblxuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICBzZXRScGNDb25uZWN0aW9uU3RhdHVzQ2FsbGJhY2s6IGZ1bmN0aW9uIHNldFJwY0Nvbm5lY3Rpb25TdGF0dXNDYWxsYmFjayhjYWxsYmFjaykge1xuICAgIHRoaXMuc3RhdHVzQ2IgPSBjYWxsYmFjaztcblxuICAgIGlmIChpbnN0KSB7XG4gICAgICBpbnN0LnNldFJwY0Nvbm5lY3Rpb25TdGF0dXNDYWxsYmFjayhjYWxsYmFjayk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgICAgICBAYXJnIHtzdHJpbmd9IGNzIGlzIG9ubHkgcHJvdmlkZWQgaW4gdGhlIGZpcnN0IGNhbGxcbiAgICAgICAgQHJldHVybiB7QXBpc30gc2luZ2xldG9uIC4uIENoZWNrIEFwaXMuaW5zdGFuY2UoKS5pbml0X3Byb21pc2UgdG9cbiAgICAgICAga25vdyB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkXG4gICAgKi9cbiAgcmVzZXQ6IGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgIHZhciBjcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJ3dzOi8vbG9jYWxob3N0OjgwOTAnO1xuICAgIHZhciBjb25uZWN0ID0gYXJndW1lbnRzWzFdO1xuICAgIHZhciBjb25uZWN0VGltZW91dCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogNDAwMDtcblxuICAgIGlmIChpbnN0KSB7XG4gICAgICBpbnN0LmNsb3NlKCk7XG4gICAgICBpbnN0ID0gbnVsbDtcbiAgICB9XG5cbiAgICBpbnN0ID0gbmV3IEFwaXNJbnN0YW5jZSgpO1xuICAgIGluc3Quc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKHRoaXMuc3RhdHVzQ2IpO1xuXG4gICAgaWYgKGluc3QgJiYgY29ubmVjdCkge1xuICAgICAgaW5zdC5jb25uZWN0KGNzLCBjb25uZWN0VGltZW91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGluc3Q7XG4gIH0sXG4gIGluc3RhbmNlOiBmdW5jdGlvbiBpbnN0YW5jZSgpIHtcbiAgICB2YXIgY3MgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6ICd3czovL2xvY2FsaG9zdDo4MDkwJztcbiAgICB2YXIgY29ubmVjdCA9IGFyZ3VtZW50c1sxXTtcbiAgICB2YXIgY29ubmVjdFRpbWVvdXQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IDQwMDA7XG5cbiAgICBpZiAoIWluc3QpIHtcbiAgICAgIGluc3QgPSBuZXcgQXBpc0luc3RhbmNlKCk7XG4gICAgICBpbnN0LnNldFJwY0Nvbm5lY3Rpb25TdGF0dXNDYWxsYmFjayh0aGlzLnN0YXR1c0NiKTtcbiAgICB9XG5cbiAgICBpZiAoaW5zdCAmJiBjb25uZWN0KSB7XG4gICAgICBpbnN0LmNvbm5lY3QoY3MsIGNvbm5lY3RUaW1lb3V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gaW5zdDtcbiAgfSxcbiAgY2hhaW5JZDogZnVuY3Rpb24gY2hhaW5JZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnN0YW5jZSgpLmNoYWluX2lkO1xuICB9LFxuICBjbG9zZTogZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgaWYgKGluc3QpIHtcbiAgICAgIGluc3QuY2xvc2UoKTtcbiAgICAgIGluc3QgPSBudWxsO1xuICAgIH1cbiAgfVxuICAvLyBkYjogKG1ldGhvZCwgLi4uYXJncykgPT4gQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMobWV0aG9kLCB0b1N0cmluZ3MoYXJncykpLFxuICAvLyBuZXR3b3JrOiAobWV0aG9kLCAuLi5hcmdzKSA9PiBBcGlzLmluc3RhbmNlKCkubmV0d29ya19hcGkoKS5leGVjKG1ldGhvZCwgdG9TdHJpbmdzKGFyZ3MpKSxcbiAgLy8gaGlzdG9yeTogKG1ldGhvZCwgLi4uYXJncykgPT4gQXBpcy5pbnN0YW5jZSgpLmhpc3RvcnlfYXBpKCkuZXhlYyhtZXRob2QsIHRvU3RyaW5ncyhhcmdzKSksXG4gIC8vIGNyeXB0bzogKG1ldGhvZCwgLi4uYXJncykgPT4gQXBpcy5pbnN0YW5jZSgpLmNyeXB0b19hcGkoKS5leGVjKG1ldGhvZCwgdG9TdHJpbmdzKGFyZ3MpKVxuXG59OyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIGRlZmF1bHRzID0ge1xuICBjb3JlX2Fzc2V0OiAnUFBZJyxcbiAgYWRkcmVzc19wcmVmaXg6ICdQUFknLFxuICBleHBpcmVfaW5fc2VjczogMTUsXG4gIGV4cGlyZV9pbl9zZWNzX3Byb3Bvc2FsOiAyNCAqIDYwICogNjAsXG4gIHJldmlld19pbl9zZWNzX2NvbW1pdHRlZTogMjQgKiA2MCAqIDYwXG59O1xuXG52YXIgbmV0d29ya3MgPSB7XG4gIG5ldHdvcmtzOiB7XG4gICAgUGVlcnBsYXlzOiB7XG4gICAgICBjb3JlX2Fzc2V0OiAnUFBZJyxcbiAgICAgIGFkZHJlc3NfcHJlZml4OiAnUFBZJyxcbiAgICAgIGNoYWluX2lkOiAnNmI2YjVmMGNlN2EzNmQzMjM3NjhlNTM0ZjNlZGI0MWM2ZDYzMzJhNTQxYTk1NzI1Yjk4ZTI4ZDE0MDg1MDEzNCdcbiAgICB9LFxuICAgIFBlZXJwbGF5c1Rlc3RuZXQ6IHtcbiAgICAgIGNvcmVfYXNzZXQ6ICdQUFlURVNUJyxcbiAgICAgIGFkZHJlc3NfcHJlZml4OiAnUFBZVEVTVCcsXG4gICAgICBjaGFpbl9pZDogJ2JlNmI3OTI5NWU3Mjg0MDZjYmI3NDk0YmNiNjI2ZTYyYWQyNzhmYTQwMTg2OTljZjhmNzU3MzlmNGMxYTgxZmQnXG4gICAgfVxuICB9XG59O1xuXG52YXIgQ2hhaW5Db25maWcgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIENoYWluQ29uZmlnKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDaGFpbkNvbmZpZyk7XG5cbiAgICB0aGlzLnJlc2V0KCk7XG4gIH1cblxuICBDaGFpbkNvbmZpZy5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiByZXNldCgpIHtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMsIGRlZmF1bHRzKTtcbiAgfTtcblxuICBDaGFpbkNvbmZpZy5wcm90b3R5cGUuc2V0Q2hhaW5JZCA9IGZ1bmN0aW9uIHNldENoYWluSWQoY2hhaW5JRCkge1xuICAgIHZhciByZWYgPSBPYmplY3Qua2V5cyhuZXR3b3Jrcyk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmVmLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB2YXIgbmV0d29ya19uYW1lID0gcmVmW2ldO1xuICAgICAgdmFyIG5ldHdvcmsgPSBuZXR3b3Jrc1tuZXR3b3JrX25hbWVdO1xuXG4gICAgICBpZiAobmV0d29yay5jaGFpbl9pZCA9PT0gY2hhaW5JRCkge1xuICAgICAgICB0aGlzLm5ldHdvcmtfbmFtZSA9IG5ldHdvcmtfbmFtZTtcblxuICAgICAgICBpZiAobmV0d29yay5hZGRyZXNzX3ByZWZpeCkge1xuICAgICAgICAgIHRoaXMuYWRkcmVzc19wcmVmaXggPSBuZXR3b3JrLmFkZHJlc3NfcHJlZml4O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuZXR3b3JrX25hbWU6IG5ldHdvcmtfbmFtZSxcbiAgICAgICAgICBuZXR3b3JrOiBuZXR3b3JrXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLm5ldHdvcmtfbmFtZSkge1xuICAgICAgY29uc29sZS5sb2coJ1Vua25vd24gY2hhaW4gaWQgKHRoaXMgbWF5IGJlIGEgdGVzdG5ldCknLCBjaGFpbklEKTtcbiAgICB9XG4gIH07XG5cbiAgQ2hhaW5Db25maWcucHJvdG90eXBlLnNldFByZWZpeCA9IGZ1bmN0aW9uIHNldFByZWZpeCgpIHtcbiAgICB2YXIgcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiAnUFBZJztcblxuICAgIHRoaXMuYWRkcmVzc19wcmVmaXggPSBwcmVmaXg7XG4gIH07XG5cbiAgcmV0dXJuIENoYWluQ29uZmlnO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBuZXcgQ2hhaW5Db25maWcoKTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBTT0NLRVRfREVCVUcgPSBmYWxzZTtcbnZhciBXZWJTb2NrZXRDbGllbnQgPSBudWxsO1xuXG5pZiAodHlwZW9mIFdlYlNvY2tldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgV2ViU29ja2V0Q2xpZW50ID0gV2ViU29ja2V0O1xufSBlbHNlIHtcbiAgV2ViU29ja2V0Q2xpZW50ID0gcmVxdWlyZSgzNCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcbn1cblxudmFyIFNVQlNDUklCRV9PUEVSQVRJT05TID0gWydzZXRfc3Vic2NyaWJlX2NhbGxiYWNrJywgJ3N1YnNjcmliZV90b19tYXJrZXQnLCAnYnJvYWRjYXN0X3RyYW5zYWN0aW9uX3dpdGhfY2FsbGJhY2snLCAnc2V0X3BlbmRpbmdfdHJhbnNhY3Rpb25fY2FsbGJhY2snXTtcblxudmFyIFVOU1VCU0NSSUJFX09QRVJBVElPTlMgPSBbJ3Vuc3Vic2NyaWJlX2Zyb21fbWFya2V0JywgJ3Vuc3Vic2NyaWJlX2Zyb21fYWNjb3VudHMnXTtcblxudmFyIEhFQUxUSF9DSEVDS19JTlRFUlZBTCA9IDEwMDAwO1xuXG52YXIgQ2hhaW5XZWJTb2NrZXQgPSBmdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKkNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgQ2hhaW5XZWJTb2NrZXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSAgICBzZXJ2ZXJBZGRyZXNzICAgICAgICAgICBUaGUgYWRkcmVzcyBvZiB0aGUgd2Vic29ja2V0IHRvIGNvbm5lY3QgdG8uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259ICBzdGF0dXNDYiAgICAgICAgICAgICAgICBDYWxsZWQgd2hlbiBzdGF0dXMgZXZlbnRzIG9jY3VyLlxuICAgKiBAcGFyYW0ge251bWJlcn0gICAgW2Nvbm5lY3RUaW1lb3V0PTEwMDAwXSAgVGhlIHRpbWUgZm9yIGEgY29ubmVjdGlvbiBhdHRlbXB0IHRvIGNvbXBsZXRlLlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG4gIGZ1bmN0aW9uIENoYWluV2ViU29ja2V0KHNlcnZlckFkZHJlc3MsIHN0YXR1c0NiKSB7XG4gICAgdmFyIGNvbm5lY3RUaW1lb3V0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAxMDAwMDtcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDaGFpbldlYlNvY2tldCk7XG5cbiAgICB0aGlzLnN0YXR1c0NiID0gc3RhdHVzQ2I7XG4gICAgdGhpcy5zZXJ2ZXJBZGRyZXNzID0gc2VydmVyQWRkcmVzcztcbiAgICB0aGlzLnRpbWVvdXRJbnRlcnZhbCA9IGNvbm5lY3RUaW1lb3V0O1xuXG4gICAgLy8gVGhlIGN1cnJlbmN0IGNvbm5lY3Rpb24gc3RhdGUgb2YgdGhlIHdlYnNvY2tldC5cbiAgICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICAgIHRoaXMucmVjb25uZWN0VGltZW91dCA9IG51bGw7XG5cbiAgICAvLyBDYWxsYmFjayB0byBleGVjdXRlIHdoZW4gdGhlIHdlYnNvY2tldCBpcyByZWNvbm5lY3RlZC5cbiAgICB0aGlzLm9uX3JlY29ubmVjdCA9IG51bGw7XG5cbiAgICAvLyBBbiBpbmNyZW1lbnRpbmcgSUQgZm9yIGVhY2ggcmVxdWVzdCBzbyB0aGF0IHdlIGNhbiBwYWlyIGl0IHdpdGggdGhlXG4gICAgLy8gcmVzcG9uc2UgZnJvbSB0aGUgd2Vic29ja2V0LlxuICAgIHRoaXMuY2JJZCA9IDA7XG5cbiAgICAvLyBPYmplY3RzIHRvIHN0b3JlIGtleS92YWx1ZSBwYWlycyBmb3IgY2FsbGJhY2tzLCBzdWJzY3JpcHRpb24gY2FsbGJhY2tzXG4gICAgLy8gYW5kIHVuc3Vic2NyaWJlIGNhbGxiYWNrcy5cbiAgICB0aGlzLmNicyA9IHt9O1xuICAgIHRoaXMuc3VicyA9IHt9O1xuICAgIHRoaXMudW5zdWIgPSB7fTtcblxuICAgIC8vIEN1cnJlbnQgY29ubmVjdGlvbiBwcm9taXNlcycgcmVqZWN0aW9uXG4gICAgdGhpcy5jdXJyZW50UmVzb2x2ZSA9IG51bGw7XG4gICAgdGhpcy5jdXJyZW50UmVqZWN0ID0gbnVsbDtcblxuICAgIC8vIEhlYWx0aCBjaGVjayBmb3IgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIEJsb2NrQ2hhaW4uXG4gICAgdGhpcy5oZWFsdGhDaGVjayA9IG51bGw7XG5cbiAgICAvLyBDb3B5IHRoZSBjb25zdGFudHMgdG8gdGhpcyBpbnN0YW5jZS5cbiAgICB0aGlzLnN0YXR1cyA9IENoYWluV2ViU29ja2V0LnN0YXR1cztcblxuICAgIC8vIEJpbmQgdGhlIGZ1bmN0aW9ucyB0byB0aGUgaW5zdGFuY2UuXG4gICAgdGhpcy5vbkNvbm5lY3Rpb25PcGVuID0gdGhpcy5vbkNvbm5lY3Rpb25PcGVuLmJpbmQodGhpcyk7XG4gICAgdGhpcy5vbkNvbm5lY3Rpb25DbG9zZSA9IHRoaXMub25Db25uZWN0aW9uQ2xvc2UuYmluZCh0aGlzKTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvblRlcm1pbmF0ZSA9IHRoaXMub25Db25uZWN0aW9uVGVybWluYXRlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5vbkNvbm5lY3Rpb25FcnJvciA9IHRoaXMub25Db25uZWN0aW9uRXJyb3IuYmluZCh0aGlzKTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvblRpbWVvdXQgPSB0aGlzLm9uQ29ubmVjdGlvblRpbWVvdXQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmNyZWF0ZUNvbm5lY3Rpb24gPSB0aGlzLmNyZWF0ZUNvbm5lY3Rpb24uYmluZCh0aGlzKTtcbiAgICB0aGlzLmNyZWF0ZUNvbm5lY3Rpb25Qcm9taXNlID0gdGhpcy5jcmVhdGVDb25uZWN0aW9uUHJvbWlzZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMubGlzdGVuZXIgPSB0aGlzLmxpc3RlbmVyLmJpbmQodGhpcyk7XG5cbiAgICAvLyBDcmVhdGUgdGhlIGluaXRpYWwgY29ubmVjdGlvbiB0aGUgYmxvY2tjaGFpbi5cbiAgICB0aGlzLmNyZWF0ZUNvbm5lY3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIEJsb2NrY2hhaW4uXG4gICAqXG4gICAqIEByZXR1cm5zXG4gICAqIEBtZW1iZXJvZiBDaGFpbldlYlNvY2tldFxuICAgKi9cblxuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5jcmVhdGVDb25uZWN0aW9uID0gZnVuY3Rpb24gY3JlYXRlQ29ubmVjdGlvbigpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgY3JlYXRlIGNvbm5lY3Rpb24nKTtcblxuICAgIC8vIENsZWFyIGFueSBwb3NzaWJsZSByZWNvbm5lY3QgdGltZXJzLlxuICAgIHRoaXMucmVjb25uZWN0VGltZW91dCA9IG51bGw7XG5cbiAgICAvLyBDcmVhdGUgdGhlIHByb21pc2UgZm9yIHRoaXMgY29ubmVjdGlvblxuICAgIGlmICghdGhpcy5jb25uZWN0X3Byb21pc2UpIHtcbiAgICAgIHRoaXMuY29ubmVjdF9wcm9taXNlID0gbmV3IFByb21pc2UodGhpcy5jcmVhdGVDb25uZWN0aW9uUHJvbWlzZSk7XG4gICAgfVxuXG4gICAgLy8gQXR0ZW1wdCB0byBjcmVhdGUgdGhlIHdlYnNvY2tldFxuICAgIHRyeSB7XG4gICAgICB0aGlzLndzID0gbmV3IFdlYlNvY2tldENsaWVudCh0aGlzLnNlcnZlckFkZHJlc3MpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBTZXQgYSB0aW1lb3V0IHRvIHRyeSBhbmQgcmVjb25uZWN0IGhlcmUuXG4gICAgICByZXR1cm4gdGhpcy5yZXNldENvbm5lY3Rpb24oKTtcbiAgICB9XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXJzKCk7XG5cbiAgICAvLyBIYW5kbGUgdGltZW91dHMgdG8gdGhlIHdlYnNvY2tldCdzIGluaXRpYWwgY29ubmVjdGlvbi5cbiAgICB0aGlzLmNvbm5lY3Rpb25UaW1lb3V0ID0gc2V0VGltZW91dCh0aGlzLm9uQ29ubmVjdGlvblRpbWVvdXQsIHRoaXMudGltZW91dEludGVydmFsKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVzZXQgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIEJsb2NrQ2hhaW4uXG4gICAqXG4gICAqIEBtZW1iZXJvZiBDaGFpbldlYlNvY2tldFxuICAgKi9cblxuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5yZXNldENvbm5lY3Rpb24gPSBmdW5jdGlvbiByZXNldENvbm5lY3Rpb24oKSB7XG4gICAgLy8gQ2xvc2UgdGhlIFdlYnNvY2tldCBpZiBpdHMgc3RpbGwgJ2hhbGYtb3BlbidcbiAgICB0aGlzLmNsb3NlKCk7XG5cbiAgICAvLyBNYWtlIHN1cmUgd2Ugb25seSBldmVyIGhhdmUgb25lIHRpbWVvdXQgcnVubmluZyB0byByZWNvbm5lY3QuXG4gICAgaWYgKCF0aGlzLnJlY29ubmVjdFRpbWVvdXQpIHtcbiAgICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCByZXNldCBjb25uZWN0aW9uJywgdGhpcy50aW1lb3V0SW50ZXJ2YWwpO1xuICAgICAgdGhpcy5yZWNvbm5lY3RUaW1lb3V0ID0gc2V0VGltZW91dCh0aGlzLmNyZWF0ZUNvbm5lY3Rpb24sIHRoaXMudGltZW91dEludGVydmFsKTtcbiAgICB9XG5cbiAgICAvLyBSZWplY3QgdGhlIGN1cnJlbnQgcHJvbWlzZSBpZiB0aGVyZSBpcyBvbmUuXG4gICAgaWYgKHRoaXMuY3VycmVudFJlamVjdCkge1xuICAgICAgdGhpcy5jdXJyZW50UmVqZWN0KG5ldyBFcnJvcignQ29ubmVjdGlvbiBhdHRlbXB0IGZhaWxlZDogJyArIHRoaXMuc2VydmVyQWRkcmVzcykpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQWRkIGV2ZW50IGxpc3RlbmVycyB0byB0aGUgV2ViU29ja2V0LlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRFdmVudExpc3RlbmVycygpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgYWRkIGV2ZW50IGxpc3RlbmVycycpO1xuICAgIHRoaXMud3MuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIHRoaXMub25Db25uZWN0aW9uT3Blbik7XG4gICAgdGhpcy53cy5hZGRFdmVudExpc3RlbmVyKCdjbG9zZScsIHRoaXMub25Db25uZWN0aW9uQ2xvc2UpO1xuICAgIHRoaXMud3MuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCB0aGlzLm9uQ29ubmVjdGlvbkVycm9yKTtcbiAgICB0aGlzLndzLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0aGlzLmxpc3RlbmVyKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVtb3ZlIHRoZSBldmVudCBsaXN0ZXJzIGZyb20gdGhlIFdlYlNvY2tldC4gSXRzIGltcG9ydGFudCB0byByZW1vdmUgdGhlIGV2ZW50IGxpc3RlcmVyc1xuICAgKiBmb3IgZ2FyYmFhZ2UgY29sbGVjdGlvbi4gQmVjYXVzZSB3ZSBhcmUgY3JlYXRpbmcgYSBuZXcgV2ViU29ja2V0IG9uIGVhY2ggY29ubmVjdGlvbiBhdHRlbXB0XG4gICAqIGFueSBsaXN0ZW5lcnMgdGhhdCBhcmUgc3RpbGwgYXR0YWNoZWQgY291bGQgcHJldmVudCB0aGUgb2xkIHNvY2tldHMgZnJvbVxuICAgKiBiZWluZyBnYXJiYWdlIGNvbGxlY3RlZC5cbiAgICpcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLnJlbW92ZUV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IHJlbW92ZSBldmVudCBsaXN0ZW5lcnMnKTtcbiAgICB0aGlzLndzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ29wZW4nLCB0aGlzLm9uQ29ubmVjdGlvbk9wZW4pO1xuICAgIHRoaXMud3MucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xvc2UnLCB0aGlzLm9uQ29ubmVjdGlvbkNsb3NlKTtcbiAgICB0aGlzLndzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgdGhpcy5vbkNvbm5lY3Rpb25FcnJvcik7XG4gICAgdGhpcy53cy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5saXN0ZW5lcik7XG4gIH07XG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCBpcyBwYXNzZWQgdG8gYSBuZXcgcHJvbWlzZSB0aGF0IHN0b3JlcyB0aGUgcmVzb2x2ZSBhbmQgcmVqZWN0IGNhbGxiYWNrc1xuICAgKiBpbiB0aGUgc3RhdGUuXG4gICAqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IHJlc29sdmUgQSBjYWxsYmFjayB0byBiZSBleGVjdXRlZCB3aGVuIHRoZSBwcm9taXNlIGlzIHJlc29sdmVkLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSByZWplY3QgQSBjYWxsYmFjayB0byBiZSBleGVjdXRlZCB3aGVuIHRoZSBwcm9taXNlIGlzIHJlamVjdGVkLlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvblByb21pc2UgPSBmdW5jdGlvbiBjcmVhdGVDb25uZWN0aW9uUHJvbWlzZShyZXNvbHZlLCByZWplY3QpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgY3JlYXRlUHJvbWlzZScpO1xuICAgIHRoaXMuY3VycmVudFJlc29sdmUgPSByZXNvbHZlO1xuICAgIHRoaXMuY3VycmVudFJlamVjdCA9IHJlamVjdDtcbiAgfTtcblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gYSBuZXcgV2Vic29ja2V0IGNvbm5lY3Rpb24gaXMgb3BlbmVkLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUub25Db25uZWN0aW9uT3BlbiA9IGZ1bmN0aW9uIG9uQ29ubmVjdGlvbk9wZW4oKSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IENvbm5lY3RlZCAnKTtcblxuICAgIHRoaXMuY29ubmVjdGVkID0gdHJ1ZTtcblxuICAgIGNsZWFyVGltZW91dCh0aGlzLmNvbm5lY3Rpb25UaW1lb3V0KTtcbiAgICB0aGlzLmNvbm5lY3Rpb25UaW1lb3V0ID0gbnVsbDtcblxuICAgIC8vIFRoaXMgd2lsbCB0cmlnZ2VyIHRoZSBsb2dpbiBwcm9jZXNzIGFzIHdlbGwgYXMgc29tZSBhZGRpdGlvbmFsIHNldHVwIGluIEFwaUluc3RhbmNlc1xuICAgIGlmICh0aGlzLm9uX3JlY29ubmVjdCkge1xuICAgICAgdGhpcy5vbl9yZWNvbm5lY3QoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jdXJyZW50UmVzb2x2ZSkge1xuICAgICAgdGhpcy5jdXJyZW50UmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXR1c0NiKSB7XG4gICAgICB0aGlzLnN0YXR1c0NiKENoYWluV2ViU29ja2V0LnN0YXR1cy5PUEVOKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIGNhbGxlZCB3aGVuIHRoZSBjb25uZWN0aW9uIGF0dGVtcHQgdGltZXMgb3V0LlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUub25Db25uZWN0aW9uVGltZW91dCA9IGZ1bmN0aW9uIG9uQ29ubmVjdGlvblRpbWVvdXQoKSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IHRpbWVvdXQnKTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvbkNsb3NlKG5ldyBFcnJvcignQ29ubmVjdGlvbiB0aW1lZCBvdXQuJykpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgV2Vic29ja2V0IGlzIG5vdCByZXNwb25kaW5nIHRvIHRoZSBoZWFsdGggY2hlY2tzLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUub25Db25uZWN0aW9uVGVybWluYXRlID0gZnVuY3Rpb24gb25Db25uZWN0aW9uVGVybWluYXRlKCkge1xuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCB0ZXJtaW5hdGUnKTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvbkNsb3NlKG5ldyBFcnJvcignQ29ubmVjdGlvbiB3YXMgdGVybWluYXRlZC4nKSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBCbG9ja2NoYWluIGlzIGNsb3NlZC5cbiAgICpcbiAgICogQHBhcmFtIHsqfSBlcnJvclxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUub25Db25uZWN0aW9uQ2xvc2UgPSBmdW5jdGlvbiBvbkNvbm5lY3Rpb25DbG9zZShlcnJvcikge1xuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCBDbG9zZSAnLCBlcnJvcik7XG5cbiAgICB0aGlzLnJlc2V0Q29ubmVjdGlvbigpO1xuXG4gICAgaWYgKHRoaXMuc3RhdHVzQ2IpIHtcbiAgICAgIHRoaXMuc3RhdHVzQ2IoQ2hhaW5XZWJTb2NrZXQuc3RhdHVzLkNMT1NFRCk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgV2Vic29ja2V0IGVuY291bnRlcnMgYW4gZXJyb3IuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gZXJyb3JcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLm9uQ29ubmVjdGlvbkVycm9yID0gZnVuY3Rpb24gb25Db25uZWN0aW9uRXJyb3IoZXJyb3IpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgT24gQ29ubmVjdGlvbiBFcnJvciAnLCBlcnJvcik7XG5cbiAgICB0aGlzLnJlc2V0Q29ubmVjdGlvbigpO1xuXG4gICAgaWYgKHRoaXMuc3RhdHVzQ2IpIHtcbiAgICAgIHRoaXMuc3RhdHVzQ2IoQ2hhaW5XZWJTb2NrZXQuc3RhdHVzLkVSUk9SKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEVudHJ5IHBvaW50IHRvIG1ha2UgUlBDIGNhbGxzIG9uIHRoZSBCbG9ja0NoYWluLlxuICAgKlxuICAgKiBAcGFyYW0ge2FycmF5fSBwYXJhbXMgQW4gYXJyYXkgb2YgcGFyYW1zIHRvIGJlIHBhc3NlZCB0byB0aGUgcnBjIGNhbGwuIFttZXRob2QsIC4uLnBhcmFtc11cbiAgICogQHJldHVybnMgQSBuZXcgcHJvbWlzZSBmb3IgdGhpcyBzcGVjaWZpYyBjYWxsLlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuY2FsbCA9IGZ1bmN0aW9uIGNhbGwocGFyYW1zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIGlmICghdGhpcy5jb25uZWN0ZWQpIHtcbiAgICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCBDYWxsIG5vdCBjb25uZWN0ZWQuICcpO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignRGlzY29ubmVjdGVkIGZyb20gdGhlIEJsb2NrQ2hhaW4uJykpO1xuICAgIH1cblxuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCBDYWxsIGNvbm5lY3RlZC4gJywgcGFyYW1zKTtcblxuICAgIHZhciByZXF1ZXN0ID0ge1xuICAgICAgbWV0aG9kOiBwYXJhbXNbMV0sXG4gICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgIGlkOiB0aGlzLmNiSWQgKyAxXG4gICAgfTtcblxuICAgIHRoaXMuY2JJZCA9IHJlcXVlc3QuaWQ7XG5cbiAgICBpZiAoU1VCU0NSSUJFX09QRVJBVElPTlMuaW5jbHVkZXMocmVxdWVzdC5tZXRob2QpKSB7XG4gICAgICAvLyBTdG9yZSBjYWxsYmFjayBpbiBzdWJzIG1hcFxuICAgICAgdGhpcy5zdWJzW3JlcXVlc3QuaWRdID0ge1xuICAgICAgICBjYWxsYmFjazogcmVxdWVzdC5wYXJhbXNbMl1bMF1cbiAgICAgIH07XG5cbiAgICAgIC8vIFJlcGxhY2UgY2FsbGJhY2sgd2l0aCB0aGUgY2FsbGJhY2sgaWRcbiAgICAgIHJlcXVlc3QucGFyYW1zWzJdWzBdID0gcmVxdWVzdC5pZDtcbiAgICB9XG5cbiAgICBpZiAoVU5TVUJTQ1JJQkVfT1BFUkFUSU9OUy5pbmNsdWRlcyhyZXF1ZXN0Lm1ldGhvZCkpIHtcbiAgICAgIGlmICh0eXBlb2YgcmVxdWVzdC5wYXJhbXNbMl1bMF0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBwYXJhbWV0ZXIgb2YgdW5zdWIgbXVzdCBiZSB0aGUgb3JpZ2luYWwgY2FsbGJhY2snKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHVuU3ViQ2IgPSByZXF1ZXN0LnBhcmFtc1syXS5zcGxpY2UoMCwgMSlbMF07XG5cbiAgICAgIC8vIEZpbmQgdGhlIGNvcnJlc3BvbmRpbmcgc3Vic2NyaXB0aW9uXG4gICAgICBmb3IgKHZhciBpZCBpbiB0aGlzLnN1YnMpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgICBpZiAodGhpcy5zdWJzW2lkXS5jYWxsYmFjayA9PT0gdW5TdWJDYikge1xuICAgICAgICAgIHRoaXMudW5zdWJbcmVxdWVzdC5pZF0gPSBpZDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGhpcy5oZWFsdGhDaGVjaykge1xuICAgICAgdGhpcy5oZWFsdGhDaGVjayA9IHNldFRpbWVvdXQodGhpcy5vbkNvbm5lY3Rpb25UZXJtaW5hdGUuYmluZCh0aGlzKSwgSEVBTFRIX0NIRUNLX0lOVEVSVkFMKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgX3RoaXMuY2JzW3JlcXVlc3QuaWRdID0ge1xuICAgICAgICB0aW1lOiBuZXcgRGF0ZSgpLFxuICAgICAgICByZXNvbHZlOiByZXNvbHZlLFxuICAgICAgICByZWplY3Q6IHJlamVjdFxuICAgICAgfTtcblxuICAgICAgLy8gU2V0IGFsbCByZXF1ZXN0cyB0byBiZSAnY2FsbCcgbWV0aG9kcy5cbiAgICAgIHJlcXVlc3QubWV0aG9kID0gJ2NhbGwnO1xuXG4gICAgICB0cnkge1xuICAgICAgICBfdGhpcy53cy5zZW5kKEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIF90aGlzLmRlYnVnKCdDYXVnaHQgYSBuYXN0eSBlcnJvciA6ICcsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gbWVzc2FnZXMgYXJlIHJlY2VpdmVkIG9uIHRoZSBXZWJzb2NrZXQuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gcmVzcG9uc2UgVGhlIG1lc3NhZ2UgcmVjZWl2ZWQuXG4gICAqIEBtZW1iZXJvZiBDaGFpbldlYlNvY2tldFxuICAgKi9cblxuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5saXN0ZW5lciA9IGZ1bmN0aW9uIGxpc3RlbmVyKHJlc3BvbnNlKSB7XG4gICAgdmFyIHJlc3BvbnNlSlNPTiA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgcmVzcG9uc2VKU09OID0gSlNPTi5wYXJzZShyZXNwb25zZS5kYXRhKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmVzcG9uc2VKU09OLmVycm9yID0gJ0Vycm9yIHBhcnNpbmcgcmVzcG9uc2U6ICcgKyBlcnJvci5zdGFjaztcbiAgICAgIHRoaXMuZGVidWcoJ0Vycm9yIHBhcnNpbmcgcmVzcG9uc2U6ICcsIHJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICAvLyBDbGVhciB0aGUgaGVhbHRoIGNoZWNrIHRpbWVvdXQsIHdlJ3ZlIGp1c3QgcmVjZWl2ZWQgYSBoZWFsdGh5IHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlci5cbiAgICBpZiAodGhpcy5oZWFsdGhDaGVjaykge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuaGVhbHRoQ2hlY2spO1xuICAgICAgdGhpcy5oZWFsdGhDaGVjayA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIHN1YiA9IGZhbHNlO1xuICAgIHZhciBjYWxsYmFjayA9IG51bGw7XG5cbiAgICBpZiAocmVzcG9uc2VKU09OLm1ldGhvZCA9PT0gJ25vdGljZScpIHtcbiAgICAgIHN1YiA9IHRydWU7XG4gICAgICByZXNwb25zZUpTT04uaWQgPSByZXNwb25zZUpTT04ucGFyYW1zWzBdO1xuICAgIH1cblxuICAgIGlmICghc3ViKSB7XG4gICAgICBjYWxsYmFjayA9IHRoaXMuY2JzW3Jlc3BvbnNlSlNPTi5pZF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhbGxiYWNrID0gdGhpcy5zdWJzW3Jlc3BvbnNlSlNPTi5pZF0uY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgaWYgKGNhbGxiYWNrICYmICFzdWIpIHtcbiAgICAgIGlmIChyZXNwb25zZUpTT04uZXJyb3IpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZygnLS0tLT4gcmVzcG9uc2VKU09OIDogJywgcmVzcG9uc2VKU09OKTtcbiAgICAgICAgY2FsbGJhY2sucmVqZWN0KHJlc3BvbnNlSlNPTi5lcnJvcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYWxsYmFjay5yZXNvbHZlKHJlc3BvbnNlSlNPTi5yZXN1bHQpO1xuICAgICAgfVxuXG4gICAgICBkZWxldGUgdGhpcy5jYnNbcmVzcG9uc2VKU09OLmlkXTtcblxuICAgICAgaWYgKHRoaXMudW5zdWJbcmVzcG9uc2VKU09OLmlkXSkge1xuICAgICAgICBkZWxldGUgdGhpcy5zdWJzW3RoaXMudW5zdWJbcmVzcG9uc2VKU09OLmlkXV07XG4gICAgICAgIGRlbGV0ZSB0aGlzLnVuc3ViW3Jlc3BvbnNlSlNPTi5pZF07XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjYWxsYmFjayAmJiBzdWIpIHtcbiAgICAgIGNhbGxiYWNrKHJlc3BvbnNlSlNPTi5wYXJhbXNbMV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlYnVnKCdXYXJuaW5nOiB1bmtub3duIHdlYnNvY2tldCByZXNwb25zZUpTT046ICcsIHJlc3BvbnNlSlNPTik7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBMb2dpbiB0byB0aGUgQmxvY2tjaGFpbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXIgVXNlcm5hbWVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFBhc3N3b3JkXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCBhZnRlciBsb2dpbi5cbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLmxvZ2luID0gZnVuY3Rpb24gbG9naW4odXNlciwgcGFzc3dvcmQpIHtcbiAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCBsb2dpbi4nLCB1c2VyLCBwYXNzd29yZCk7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdF9wcm9taXNlLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzMi5jYWxsKFsxLCAnbG9naW4nLCBbdXNlciwgcGFzc3dvcmRdXSk7XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENsb3NlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBCbG9ja2NoYWluLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICBpZiAodGhpcy53cykge1xuICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVycygpO1xuXG4gICAgICAvLyBUcnkgYW5kIGZpcmUgY2xvc2Ugb24gdGhlIGNvbm5lY3Rpb24uXG4gICAgICB0aGlzLndzLmNsb3NlKCk7XG5cbiAgICAgIC8vIENsZWFyIG91ciByZWZlcmVuY2VzIHNvIHRoYXQgaXQgY2FuIGJlIGdhcmJhZ2UgY29sbGVjdGVkLlxuICAgICAgdGhpcy53cyA9IG51bGw7XG4gICAgfVxuXG4gICAgLy8gQ2xlYXIgb3VyIHRpbWVvdXRzIGZvciBjb25uZWN0aW9uIHRpbWVvdXQgYW5kIGhlYWx0aCBjaGVjay5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5jb25uZWN0aW9uVGltZW91dCk7XG4gICAgdGhpcy5jb25uZWN0aW9uVGltZW91dCA9IG51bGw7XG5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5oZWFsdGhDaGVjayk7XG4gICAgdGhpcy5oZWFsdGhDaGVjayA9IG51bGw7XG5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5yZWNvbm5lY3RUaW1lb3V0KTtcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVvdXQgPSBudWxsO1xuXG4gICAgLy8gVG9nZ2xlIHRoZSBjb25uZWN0ZWQgZmxhZy5cbiAgICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICB9O1xuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5kZWJ1ZyA9IGZ1bmN0aW9uIGRlYnVnKCkge1xuICAgIGlmIChTT0NLRVRfREVCVUcpIHtcbiAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBwYXJhbXMgPSBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgcGFyYW1zW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgICAgfVxuXG4gICAgICBjb25zb2xlLmxvZy5hcHBseShudWxsLCBwYXJhbXMpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gQ2hhaW5XZWJTb2NrZXQ7XG59KCk7XG5cbi8vIENvbnN0YW50cyBmb3IgU1RBVEVcblxuXG5DaGFpbldlYlNvY2tldC5zdGF0dXMgPSB7XG4gIFJFQ09OTkVDVEVEOiAncmVjb25uZWN0ZWQnLFxuICBPUEVOOiAnb3BlbicsXG4gIENMT1NFRDogJ2Nsb3NlZCcsXG4gIEVSUk9SOiAnZXJyb3InXG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBDaGFpbldlYlNvY2tldDsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfQXBpSW5zdGFuY2VzID0gcmVxdWlyZSg3MSk7XG5cbnZhciBfQXBpSW5zdGFuY2VzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0FwaUluc3RhbmNlcyk7XG5cbnZhciBfQ2hhaW5XZWJTb2NrZXQgPSByZXF1aXJlKDczKTtcblxudmFyIF9DaGFpbldlYlNvY2tldDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpbldlYlNvY2tldCk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBNYW5hZ2VyID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBNYW5hZ2VyKF9yZWYpIHtcbiAgICB2YXIgdXJsID0gX3JlZi51cmwsXG4gICAgICAgIHVybHMgPSBfcmVmLnVybHM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTWFuYWdlcik7XG5cbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICB0aGlzLnVybHMgPSB1cmxzLmZpbHRlcihmdW5jdGlvbiAoYSkge1xuICAgICAgcmV0dXJuIGEgIT09IHVybDtcbiAgICB9KTtcbiAgfVxuXG4gIE1hbmFnZXIucHJvdG90eXBlLmxvZ0ZhaWx1cmUgPSBmdW5jdGlvbiBsb2dGYWlsdXJlKHVybCkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1VuYWJsZSB0byBjb25uZWN0IHRvJywgdXJsICsgJywgc2tpcHBpbmcgdG8gbmV4dCBmdWxsIG5vZGUgQVBJIHNlcnZlcicpO1xuICB9O1xuXG4gIE1hbmFnZXIucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbiBjb25uZWN0KCkge1xuICAgIHZhciBfY29ubmVjdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogdHJ1ZTtcblxuICAgIHZhciB1cmwgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHRoaXMudXJsO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIF9BcGlJbnN0YW5jZXMyLmRlZmF1bHQuaW5zdGFuY2UodXJsLCBfY29ubmVjdCkuaW5pdF9wcm9taXNlLnRoZW4ocmVzb2x2ZSkuY2F0Y2goZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIF9BcGlJbnN0YW5jZXMyLmRlZmF1bHQuaW5zdGFuY2UoKS5jbG9zZSgpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdFdpdGhGYWxsYmFjayA9IGZ1bmN0aW9uIGNvbm5lY3RXaXRoRmFsbGJhY2soKSB7XG4gICAgdmFyIGNvbm5lY3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRydWU7XG4gICAgdmFyIHVybCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogdGhpcy51cmw7XG4gICAgdmFyIGluZGV4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAwO1xuXG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciByZXNvbHZlID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiBudWxsO1xuICAgIHZhciByZWplY3QgPSBhcmd1bWVudHMubGVuZ3RoID4gNCAmJiBhcmd1bWVudHNbNF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1s0XSA6IG51bGw7XG5cbiAgICBpZiAocmVqZWN0ICYmIGluZGV4ID4gdGhpcy51cmxzLmxlbmd0aCAtIDEpIHtcbiAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdUcmllZCAnICsgKGluZGV4ICsgMSkgKyAnIGNvbm5lY3Rpb25zLCBub25lIG9mIHdoaWNoIHdvcmtlZDogJyArIEpTT04uc3RyaW5naWZ5KHRoaXMudXJscy5jb25jYXQodGhpcy51cmwpKSkpO1xuICAgIH1cblxuICAgIHZhciBmYWxsYmFjayA9IGZ1bmN0aW9uIGZhbGxiYWNrKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgX3RoaXMubG9nRmFpbHVyZSh1cmwpO1xuICAgICAgcmV0dXJuIF90aGlzLmNvbm5lY3RXaXRoRmFsbGJhY2soY29ubmVjdCwgX3RoaXMudXJsc1tpbmRleF0sIGluZGV4ICsgMSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9O1xuXG4gICAgaWYgKHJlc29sdmUgJiYgcmVqZWN0KSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25uZWN0KGNvbm5lY3QsIHVybCkudGhlbihyZXNvbHZlKS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZhbGxiYWNrKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgX3RoaXMuY29ubmVjdChjb25uZWN0KS50aGVuKHJlc29sdmUpLmNhdGNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZmFsbGJhY2socmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIE1hbmFnZXIucHJvdG90eXBlLmNoZWNrQ29ubmVjdGlvbnMgPSBmdW5jdGlvbiBjaGVja0Nvbm5lY3Rpb25zKCkge1xuICAgIHZhciBycGNfdXNlciA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJyc7XG4gICAgdmFyIHJwY19wYXNzd29yZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgIHZhciByZXNvbHZlID0gYXJndW1lbnRzWzJdO1xuICAgIHZhciByZWplY3QgPSBhcmd1bWVudHNbM107XG5cbiAgICB2YXIgY29ubmVjdGlvblN0YXJ0VGltZXMgPSB7fTtcblxuICAgIHZhciBjaGVja0Z1bmN0aW9uID0gZnVuY3Rpb24gY2hlY2tGdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciBmdWxsTGlzdCA9IF90aGlzMi51cmxzLmNvbmNhdChfdGhpczIudXJsKTtcbiAgICAgIHZhciBjb25uZWN0aW9uUHJvbWlzZXMgPSBbXTtcblxuICAgICAgZnVsbExpc3QuZm9yRWFjaChmdW5jdGlvbiAodXJsKSB7XG4gICAgICAgIHZhciBjb25uID0gbmV3IF9DaGFpbldlYlNvY2tldDIuZGVmYXVsdCh1cmwsIGZ1bmN0aW9uICgpIHt9KTtcbiAgICAgICAgY29ubmVjdGlvblN0YXJ0VGltZXNbdXJsXSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBjb25uZWN0aW9uUHJvbWlzZXMucHVzaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbm4ubG9naW4ocnBjX3VzZXIsIHJwY19wYXNzd29yZCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgX3JlZjI7XG5cbiAgICAgICAgICAgIGNvbm4uY2xvc2UoKTtcbiAgICAgICAgICAgIHJldHVybiBfcmVmMiA9IHt9LCBfcmVmMlt1cmxdID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBjb25uZWN0aW9uU3RhcnRUaW1lc1t1cmxdLCBfcmVmMjtcbiAgICAgICAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodXJsID09PSBfdGhpczIudXJsKSB7XG4gICAgICAgICAgICAgIF90aGlzMi51cmwgPSBfdGhpczIudXJsc1swXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIF90aGlzMi51cmxzID0gX3RoaXMyLnVybHMuZmlsdGVyKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGEgIT09IHVybDtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbm4uY2xvc2UoKTtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBQcm9taXNlLmFsbChjb25uZWN0aW9uUHJvbWlzZXMubWFwKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgIHJldHVybiBhKCk7XG4gICAgICB9KSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgIHJlc29sdmUocmVzLmZpbHRlcihmdW5jdGlvbiAoYSkge1xuICAgICAgICAgIHJldHVybiAhIWE7XG4gICAgICAgIH0pLnJlZHVjZShmdW5jdGlvbiAoZiwgYSkge1xuICAgICAgICAgIHZhciBrZXkgPSBPYmplY3Qua2V5cyhhKVswXTtcbiAgICAgICAgICBmW2tleV0gPSBhW2tleV07XG4gICAgICAgICAgcmV0dXJuIGY7XG4gICAgICAgIH0sIHt9KSk7XG4gICAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBfdGhpczIuY2hlY2tDb25uZWN0aW9ucyhycGNfdXNlciwgcnBjX3Bhc3N3b3JkLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGlmIChyZXNvbHZlICYmIHJlamVjdCkge1xuICAgICAgY2hlY2tGdW5jdGlvbihyZXNvbHZlLCByZWplY3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoY2hlY2tGdW5jdGlvbik7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBNYW5hZ2VyO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBNYW5hZ2VyOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIEdyYXBoZW5lQXBpID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBHcmFwaGVuZUFwaSh3c19ycGMsIGFwaV9uYW1lKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEdyYXBoZW5lQXBpKTtcblxuICAgIHRoaXMud3NfcnBjID0gd3NfcnBjO1xuICAgIHRoaXMuYXBpX25hbWUgPSBhcGlfbmFtZTtcbiAgfVxuXG4gIEdyYXBoZW5lQXBpLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gaW5pdCgpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgcmV0dXJuIHRoaXMud3NfcnBjLmNhbGwoWzEsIHRoaXMuYXBpX25hbWUsIFtdXSkudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgIF90aGlzLmFwaV9pZCA9IHJlc3BvbnNlO1xuICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH0pO1xuICB9O1xuXG4gIEdyYXBoZW5lQXBpLnByb3RvdHlwZS5leGVjID0gZnVuY3Rpb24gZXhlYyhtZXRob2QsIHBhcmFtcykge1xuICAgIHJldHVybiB0aGlzLndzX3JwYy5jYWxsKFt0aGlzLmFwaV9pZCwgbWV0aG9kLCBwYXJhbXNdKS5jYXRjaChmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUubG9nKCchISEgR3JhcGhlbmVBcGkgZXJyb3I6ICcsIG1ldGhvZCwgcGFyYW1zLCBlcnJvciwgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiBHcmFwaGVuZUFwaTtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gR3JhcGhlbmVBcGk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAoIXByb2Nlc3MudmVyc2lvbiB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MC4nKSA9PT0gMCB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS4nKSA9PT0gMCAmJiBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuOC4nKSAhPT0gMCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IHsgbmV4dFRpY2s6IG5leHRUaWNrIH07XG59IGVsc2Uge1xuICBtb2R1bGUuZXhwb3J0cyA9IHByb2Nlc3Ncbn1cblxuZnVuY3Rpb24gbmV4dFRpY2soZm4sIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiY2FsbGJhY2tcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuICB2YXIgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgdmFyIGFyZ3MsIGk7XG4gIHN3aXRjaCAobGVuKSB7XG4gIGNhc2UgMDpcbiAgY2FzZSAxOlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZuKTtcbiAgY2FzZSAyOlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja09uZSgpIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgYXJnMSk7XG4gICAgfSk7XG4gIGNhc2UgMzpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tUd28oKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEsIGFyZzIpO1xuICAgIH0pO1xuICBjYXNlIDQ6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVGhyZWUoKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICAgIH0pO1xuICBkZWZhdWx0OlxuICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBhcmdzLmxlbmd0aCkge1xuICAgICAgYXJnc1tpKytdID0gYXJndW1lbnRzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2soKSB7XG4gICAgICBmbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICB9KTtcbiAgfVxufVxuXG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKDc5KTtcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBwbmEgPSByZXF1aXJlKDc2KTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBrZXlzLnB1c2goa2V5KTtcbiAgfXJldHVybiBrZXlzO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IER1cGxleDtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSg0MCk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSg4Nyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIFJlYWRhYmxlID0gcmVxdWlyZSg4MSk7XG52YXIgV3JpdGFibGUgPSByZXF1aXJlKDgzKTtcblxudXRpbC5pbmhlcml0cyhEdXBsZXgsIFJlYWRhYmxlKTtcblxue1xuICAvLyBhdm9pZCBzY29wZSBjcmVlcCwgdGhlIGtleXMgYXJyYXkgY2FuIHRoZW4gYmUgY29sbGVjdGVkXG4gIHZhciBrZXlzID0gb2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO1xuICBmb3IgKHZhciB2ID0gMDsgdiA8IGtleXMubGVuZ3RoOyB2KyspIHtcbiAgICB2YXIgbWV0aG9kID0ga2V5c1t2XTtcbiAgICBpZiAoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSkgRHVwbGV4LnByb3RvdHlwZVttZXRob2RdID0gV3JpdGFibGUucHJvdG90eXBlW21ldGhvZF07XG4gIH1cbn1cblxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpIHRoaXMucmVhZGFibGUgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gIHRoaXMuYWxsb3dIYWxmT3BlbiA9IHRydWU7XG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYWxsb3dIYWxmT3BlbiA9PT0gZmFsc2UpIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRHVwbGV4LnByb3RvdHlwZSwgJ3dyaXRhYmxlSGlnaFdhdGVyTWFyaycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgfVxufSk7XG5cbi8vIHRoZSBuby1oYWxmLW9wZW4gZW5mb3JjZXJcbmZ1bmN0aW9uIG9uZW5kKCkge1xuICAvLyBpZiB3ZSBhbGxvdyBoYWxmLW9wZW4gc3RhdGUsIG9yIGlmIHRoZSB3cml0YWJsZSBzaWRlIGVuZGVkLFxuICAvLyB0aGVuIHdlJ3JlIG9rLlxuICBpZiAodGhpcy5hbGxvd0hhbGZPcGVuIHx8IHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kZWQpIHJldHVybjtcblxuICAvLyBubyBtb3JlIGRhdGEgY2FuIGJlIHdyaXR0ZW4uXG4gIC8vIEJ1dCBhbGxvdyBtb3JlIHdyaXRlcyB0byBoYXBwZW4gaW4gdGhpcyB0aWNrLlxuICBwbmEubmV4dFRpY2sob25FbmROVCwgdGhpcyk7XG59XG5cbmZ1bmN0aW9uIG9uRW5kTlQoc2VsZikge1xuICBzZWxmLmVuZCgpO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRHVwbGV4LnByb3RvdHlwZSwgJ2Rlc3Ryb3llZCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCB8fCB0aGlzLl93cml0YWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkICYmIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIC8vIHdlIGlnbm9yZSB0aGUgdmFsdWUgaWYgdGhlIHN0cmVhbVxuICAgIC8vIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCB5ZXRcbiAgICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkIHx8IHRoaXMuX3dyaXRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZSB1c2VyIGlzIGV4cGxpY2l0bHlcbiAgICAvLyBtYW5hZ2luZyBkZXN0cm95ZWRcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdmFsdWU7XG4gIH1cbn0pO1xuXG5EdXBsZXgucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgdGhpcy5wdXNoKG51bGwpO1xuICB0aGlzLmVuZCgpO1xuXG4gIHBuYS5uZXh0VGljayhjYiwgZXJyKTtcbn07IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUGFzc1Rocm91Z2g7XG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKDgyKTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSg0MCk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSg4Nyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCwgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKSByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG51bGwsIGNodW5rKTtcbn07IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBSZWFkYWJsZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRHVwbGV4O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgRUVsaXN0ZW5lckNvdW50ID0gZnVuY3Rpb24gKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW0gPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvc3RyZWFtJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyO1xudmFyIE91clVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheSB8fCBmdW5jdGlvbiAoKSB7fTtcbmZ1bmN0aW9uIF91aW50OEFycmF5VG9CdWZmZXIoY2h1bmspIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKGNodW5rKTtcbn1cbmZ1bmN0aW9uIF9pc1VpbnQ4QXJyYXkob2JqKSB7XG4gIHJldHVybiBCdWZmZXIuaXNCdWZmZXIob2JqKSB8fCBvYmogaW5zdGFuY2VvZiBPdXJVaW50OEFycmF5O1xufVxuXG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGRlYnVnVXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBkZWJ1ZyA9IHZvaWQgMDtcbmlmIChkZWJ1Z1V0aWwgJiYgZGVidWdVdGlsLmRlYnVnbG9nKSB7XG4gIGRlYnVnID0gZGVidWdVdGlsLmRlYnVnbG9nKCdzdHJlYW0nKTtcbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge307XG59XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdCcpO1xudmFyIGRlc3Ryb3lJbXBsID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL2Rlc3Ryb3knKTtcbnZhciBTdHJpbmdEZWNvZGVyO1xuXG51dGlsLmluaGVyaXRzKFJlYWRhYmxlLCBTdHJlYW0pO1xuXG52YXIga1Byb3h5RXZlbnRzID0gWydlcnJvcicsICdjbG9zZScsICdkZXN0cm95JywgJ3BhdXNlJywgJ3Jlc3VtZSddO1xuXG5mdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIoZW1pdHRlciwgZXZlbnQsIGZuKSB7XG4gIC8vIFNhZGx5IHRoaXMgaXMgbm90IGNhY2hlYWJsZSBhcyBzb21lIGxpYnJhcmllcyBidW5kbGUgdGhlaXIgb3duXG4gIC8vIGV2ZW50IGVtaXR0ZXIgaW1wbGVtZW50YXRpb24gd2l0aCB0aGVtLlxuICBpZiAodHlwZW9mIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSByZXR1cm4gZW1pdHRlci5wcmVwZW5kTGlzdGVuZXIoZXZlbnQsIGZuKTtcblxuICAvLyBUaGlzIGlzIGEgaGFjayB0byBtYWtlIHN1cmUgdGhhdCBvdXIgZXJyb3IgaGFuZGxlciBpcyBhdHRhY2hlZCBiZWZvcmUgYW55XG4gIC8vIHVzZXJsYW5kIG9uZXMuICBORVZFUiBETyBUSElTLiBUaGlzIGlzIGhlcmUgb25seSBiZWNhdXNlIHRoaXMgY29kZSBuZWVkc1xuICAvLyB0byBjb250aW51ZSB0byB3b3JrIHdpdGggb2xkZXIgdmVyc2lvbnMgb2YgTm9kZS5qcyB0aGF0IGRvIG5vdCBpbmNsdWRlXG4gIC8vIHRoZSBwcmVwZW5kTGlzdGVuZXIoKSBtZXRob2QuIFRoZSBnb2FsIGlzIHRvIGV2ZW50dWFsbHkgcmVtb3ZlIHRoaXMgaGFjay5cbiAgaWYgKCFlbWl0dGVyLl9ldmVudHMgfHwgIWVtaXR0ZXIuX2V2ZW50c1tldmVudF0pIGVtaXR0ZXIub24oZXZlbnQsIGZuKTtlbHNlIGlmIChpc0FycmF5KGVtaXR0ZXIuX2V2ZW50c1tldmVudF0pKSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdLnVuc2hpZnQoZm4pO2Vsc2UgZW1pdHRlci5fZXZlbnRzW2V2ZW50XSA9IFtmbiwgZW1pdHRlci5fZXZlbnRzW2V2ZW50XV07XG59XG5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gRHVwbGV4IHN0cmVhbXMgYXJlIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLCBidXQgc2hhcmVcbiAgLy8gdGhlIHNhbWUgb3B0aW9ucyBvYmplY3QuXG4gIC8vIEhvd2V2ZXIsIHNvbWUgY2FzZXMgcmVxdWlyZSBzZXR0aW5nIG9wdGlvbnMgdG8gZGlmZmVyZW50XG4gIC8vIHZhbHVlcyBmb3IgdGhlIHJlYWRhYmxlIGFuZCB0aGUgd3JpdGFibGUgc2lkZXMgb2YgdGhlIGR1cGxleCBzdHJlYW0uXG4gIC8vIFRoZXNlIG9wdGlvbnMgY2FuIGJlIHByb3ZpZGVkIHNlcGFyYXRlbHkgYXMgcmVhZGFibGVYWFggYW5kIHdyaXRhYmxlWFhYLlxuICB2YXIgaXNEdXBsZXggPSBzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXg7XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnLiBVc2VkIHRvIG1ha2UgcmVhZChuKSBpZ25vcmUgbiBhbmQgdG9cbiAgLy8gbWFrZSBhbGwgdGhlIGJ1ZmZlciBtZXJnaW5nIGFuZCBsZW5ndGggY2hlY2tzIGdvIGF3YXlcbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgaWYgKGlzRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciByZWFkYWJsZUh3bSA9IG9wdGlvbnMucmVhZGFibGVIaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuXG4gIGlmIChod20gfHwgaHdtID09PSAwKSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod207ZWxzZSBpZiAoaXNEdXBsZXggJiYgKHJlYWRhYmxlSHdtIHx8IHJlYWRhYmxlSHdtID09PSAwKSkgdGhpcy5oaWdoV2F0ZXJNYXJrID0gcmVhZGFibGVId207ZWxzZSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gTWF0aC5mbG9vcih0aGlzLmhpZ2hXYXRlck1hcmspO1xuXG4gIC8vIEEgbGlua2VkIGxpc3QgaXMgdXNlZCB0byBzdG9yZSBkYXRhIGNodW5rcyBpbnN0ZWFkIG9mIGFuIGFycmF5IGJlY2F1c2UgdGhlXG4gIC8vIGxpbmtlZCBsaXN0IGNhbiByZW1vdmUgZWxlbWVudHMgZnJvbSB0aGUgYmVnaW5uaW5nIGZhc3RlciB0aGFuXG4gIC8vIGFycmF5LnNoaWZ0KClcbiAgdGhpcy5idWZmZXIgPSBuZXcgQnVmZmVyTGlzdCgpO1xuICB0aGlzLmxlbmd0aCA9IDA7XG4gIHRoaXMucGlwZXMgPSBudWxsO1xuICB0aGlzLnBpcGVzQ291bnQgPSAwO1xuICB0aGlzLmZsb3dpbmcgPSBudWxsO1xuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIHRoaXMuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB0aGlzLnJlYWRpbmcgPSBmYWxzZTtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBldmVudCAncmVhZGFibGUnLydkYXRhJyBpcyBlbWl0dGVkXG4gIC8vIGltbWVkaWF0ZWx5LCBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlXG4gIC8vIGFueSBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCByZWFkIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gd2hlbmV2ZXIgd2UgcmV0dXJuIG51bGwsIHRoZW4gd2Ugc2V0IGEgZmxhZyB0byBzYXlcbiAgLy8gdGhhdCB3ZSdyZSBhd2FpdGluZyBhICdyZWFkYWJsZScgZXZlbnQgZW1pc3Npb24uXG4gIHRoaXMubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGVMaXN0ZW5pbmcgPSBmYWxzZTtcbiAgdGhpcy5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcblxuICAvLyBoYXMgaXQgYmVlbiBkZXN0cm95ZWRcbiAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyB0aGUgbnVtYmVyIG9mIHdyaXRlcnMgdGhhdCBhcmUgYXdhaXRpbmcgYSBkcmFpbiBldmVudCBpbiAucGlwZSgpc1xuICB0aGlzLmF3YWl0RHJhaW4gPSAwO1xuXG4gIC8vIGlmIHRydWUsIGEgbWF5YmVSZWFkTW9yZSBoYXMgYmVlbiBzY2hlZHVsZWRcbiAgdGhpcy5yZWFkaW5nTW9yZSA9IGZhbHNlO1xuXG4gIHRoaXMuZGVjb2RlciA9IG51bGw7XG4gIHRoaXMuZW5jb2RpbmcgPSBudWxsO1xuICBpZiAob3B0aW9ucy5lbmNvZGluZykge1xuICAgIGlmICghU3RyaW5nRGVjb2RlcikgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyLycpLlN0cmluZ0RlY29kZXI7XG4gICAgdGhpcy5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIob3B0aW9ucy5lbmNvZGluZyk7XG4gICAgdGhpcy5lbmNvZGluZyA9IG9wdGlvbnMuZW5jb2Rpbmc7XG4gIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSZWFkYWJsZSkpIHJldHVybiBuZXcgUmVhZGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZSA9IG5ldyBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeVxuICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5yZWFkID09PSAnZnVuY3Rpb24nKSB0aGlzLl9yZWFkID0gb3B0aW9ucy5yZWFkO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHRoaXMuX2Rlc3Ryb3kgPSBvcHRpb25zLmRlc3Ryb3k7XG4gIH1cblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ2Rlc3Ryb3llZCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgLy8gd2UgaWdub3JlIHRoZSB2YWx1ZSBpZiB0aGUgc3RyZWFtXG4gICAgLy8gaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIHlldFxuICAgIGlmICghdGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZSB1c2VyIGlzIGV4cGxpY2l0bHlcbiAgICAvLyBtYW5hZ2luZyBkZXN0cm95ZWRcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTtcblxuUmVhZGFibGUucHJvdG90eXBlLmRlc3Ryb3kgPSBkZXN0cm95SW1wbC5kZXN0cm95O1xuUmVhZGFibGUucHJvdG90eXBlLl91bmRlc3Ryb3kgPSBkZXN0cm95SW1wbC51bmRlc3Ryb3k7XG5SZWFkYWJsZS5wcm90b3R5cGUuX2Rlc3Ryb3kgPSBmdW5jdGlvbiAoZXJyLCBjYikge1xuICB0aGlzLnB1c2gobnVsbCk7XG4gIGNiKGVycik7XG59O1xuXG4vLyBNYW51YWxseSBzaG92ZSBzb21ldGhpbmcgaW50byB0aGUgcmVhZCgpIGJ1ZmZlci5cbi8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIHRoZSBoaWdoV2F0ZXJNYXJrIGhhcyBub3QgYmVlbiBoaXQgeWV0LFxuLy8gc2ltaWxhciB0byBob3cgV3JpdGFibGUud3JpdGUoKSByZXR1cm5zIHRydWUgaWYgeW91IHNob3VsZFxuLy8gd3JpdGUoKSBzb21lIG1vcmUuXG5SZWFkYWJsZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHNraXBDaHVua0NoZWNrO1xuXG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGlmICh0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuY29kaW5nIHx8IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgICAgIGlmIChlbmNvZGluZyAhPT0gc3RhdGUuZW5jb2RpbmcpIHtcbiAgICAgICAgY2h1bmsgPSBCdWZmZXIuZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgICBlbmNvZGluZyA9ICcnO1xuICAgICAgfVxuICAgICAgc2tpcENodW5rQ2hlY2sgPSB0cnVlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBza2lwQ2h1bmtDaGVjayA9IHRydWU7XG4gIH1cblxuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBjaHVuaywgZW5jb2RpbmcsIGZhbHNlLCBza2lwQ2h1bmtDaGVjayk7XG59O1xuXG4vLyBVbnNoaWZ0IHNob3VsZCAqYWx3YXlzKiBiZSBzb21ldGhpbmcgZGlyZWN0bHkgb3V0IG9mIHJlYWQoKVxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgY2h1bmssIG51bGwsIHRydWUsIGZhbHNlKTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQsIHNraXBDaHVua0NoZWNrKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGVyO1xuICAgIGlmICghc2tpcENodW5rQ2hlY2spIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gICAgaWYgKGVyKSB7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rICYmIGNodW5rLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICh0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmICFzdGF0ZS5vYmplY3RNb2RlICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihjaHVuaykgIT09IEJ1ZmZlci5wcm90b3R5cGUpIHtcbiAgICAgICAgY2h1bmsgPSBfdWludDhBcnJheVRvQnVmZmVyKGNodW5rKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFkZFRvRnJvbnQpIHtcbiAgICAgICAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignc3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnQnKSk7ZWxzZSBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgdHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZGVkKSB7XG4gICAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignc3RyZWFtLnB1c2goKSBhZnRlciBFT0YnKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFlbmNvZGluZykge1xuICAgICAgICAgIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG4gICAgICAgICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsubGVuZ3RoICE9PSAwKSBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO2Vsc2UgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghYWRkVG9Gcm9udCkge1xuICAgICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZWVkTW9yZURhdGEoc3RhdGUpO1xufVxuXG5mdW5jdGlvbiBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgYWRkVG9Gcm9udCkge1xuICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLnN5bmMpIHtcbiAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGNodW5rKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB1cGRhdGUgdGhlIGJ1ZmZlciBpbmZvLlxuICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICBpZiAoYWRkVG9Gcm9udCkgc3RhdGUuYnVmZmVyLnVuc2hpZnQoY2h1bmspO2Vsc2Ugc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuXG4gICAgaWYgKHN0YXRlLm5lZWRSZWFkYWJsZSkgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG4gIH1cbiAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbn1cblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXI7XG4gIGlmICghX2lzVWludDhBcnJheShjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG4vLyBpZiBpdCdzIHBhc3QgdGhlIGhpZ2ggd2F0ZXIgbWFyaywgd2UgY2FuIHB1c2ggaW4gc29tZSBtb3JlLlxuLy8gQWxzbywgaWYgd2UgaGF2ZSBubyBkYXRhIHlldCwgd2UgY2FuIHN0YW5kIHNvbWVcbi8vIG1vcmUgYnl0ZXMuICBUaGlzIGlzIHRvIHdvcmsgYXJvdW5kIGNhc2VzIHdoZXJlIGh3bT0wLFxuLy8gc3VjaCBhcyB0aGUgcmVwbC4gIEFsc28sIGlmIHRoZSBwdXNoKCkgdHJpZ2dlcmVkIGFcbi8vIHJlYWRhYmxlIGV2ZW50LCBhbmQgdGhlIHVzZXIgY2FsbGVkIHJlYWQobGFyZ2VOdW1iZXIpIHN1Y2ggdGhhdFxuLy8gbmVlZFJlYWRhYmxlIHdhcyBzZXQsIHRoZW4gd2Ugb3VnaHQgdG8gcHVzaCBtb3JlLCBzbyB0aGF0IGFub3RoZXJcbi8vICdyZWFkYWJsZScgZXZlbnQgd2lsbCBiZSB0cmlnZ2VyZWQuXG5mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpIHtcbiAgcmV0dXJuICFzdGF0ZS5lbmRlZCAmJiAoc3RhdGUubmVlZFJlYWRhYmxlIHx8IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUubGVuZ3RoID09PSAwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLmlzUGF1c2VkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID09PSBmYWxzZTtcbn07XG5cbi8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24gKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihlbmMpO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuY29kaW5nID0gZW5jO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIERvbid0IHJhaXNlIHRoZSBod20gPiA4TUJcbnZhciBNQVhfSFdNID0gMHg4MDAwMDA7XG5mdW5jdGlvbiBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKSB7XG4gIGlmIChuID49IE1BWF9IV00pIHtcbiAgICBuID0gTUFYX0hXTTtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIG5leHQgaGlnaGVzdCBwb3dlciBvZiAyIHRvIHByZXZlbnQgaW5jcmVhc2luZyBod20gZXhjZXNzaXZlbHkgaW5cbiAgICAvLyB0aW55IGFtb3VudHNcbiAgICBuLS07XG4gICAgbiB8PSBuID4+PiAxO1xuICAgIG4gfD0gbiA+Pj4gMjtcbiAgICBuIHw9IG4gPj4+IDQ7XG4gICAgbiB8PSBuID4+PiA4O1xuICAgIG4gfD0gbiA+Pj4gMTY7XG4gICAgbisrO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobiwgc3RhdGUpIHtcbiAgaWYgKG4gPD0gMCB8fCBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIHJldHVybiAwO1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0dXJuIDE7XG4gIGlmIChuICE9PSBuKSB7XG4gICAgLy8gT25seSBmbG93IG9uZSBidWZmZXIgYXQgYSB0aW1lXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoKSByZXR1cm4gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YS5sZW5ndGg7ZWxzZSByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9XG4gIC8vIElmIHdlJ3JlIGFza2luZyBmb3IgbW9yZSB0aGFuIHRoZSBjdXJyZW50IGh3bSwgdGhlbiByYWlzZSB0aGUgaHdtLlxuICBpZiAobiA+IHN0YXRlLmhpZ2hXYXRlck1hcmspIHN0YXRlLmhpZ2hXYXRlck1hcmsgPSBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKTtcbiAgaWYgKG4gPD0gc3RhdGUubGVuZ3RoKSByZXR1cm4gbjtcbiAgLy8gRG9uJ3QgaGF2ZSBlbm91Z2hcbiAgaWYgKCFzdGF0ZS5lbmRlZCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbn1cblxuLy8geW91IGNhbiBvdmVycmlkZSBlaXRoZXIgdGhpcyBtZXRob2QsIG9yIHRoZSBhc3luYyBfcmVhZChuKSBiZWxvdy5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgZGVidWcoJ3JlYWQnLCBuKTtcbiAgbiA9IHBhcnNlSW50KG4sIDEwKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIG5PcmlnID0gbjtcblxuICBpZiAobiAhPT0gMCkgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgLy8gaWYgd2UncmUgZG9pbmcgcmVhZCgwKSB0byB0cmlnZ2VyIGEgcmVhZGFibGUgZXZlbnQsIGJ1dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYSBidW5jaCBvZiBkYXRhIGluIHRoZSBidWZmZXIsIHRoZW4ganVzdCB0cmlnZ2VyXG4gIC8vIHRoZSAncmVhZGFibGUnIGV2ZW50IGFuZCBtb3ZlIG9uLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5uZWVkUmVhZGFibGUgJiYgKHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmVuZGVkKSkge1xuICAgIGRlYnVnKCdyZWFkOiBlbWl0UmVhZGFibGUnLCBzdGF0ZS5sZW5ndGgsIHN0YXRlLmVuZGVkKTtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSBlbmRSZWFkYWJsZSh0aGlzKTtlbHNlIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIG4gPSBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKTtcblxuICAvLyBpZiB3ZSd2ZSBlbmRlZCwgYW5kIHdlJ3JlIG5vdyBjbGVhciwgdGhlbiBmaW5pc2ggaXQgdXAuXG4gIGlmIChuID09PSAwICYmIHN0YXRlLmVuZGVkKSB7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgZW5kUmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBbGwgdGhlIGFjdHVhbCBjaHVuayBnZW5lcmF0aW9uIGxvZ2ljIG5lZWRzIHRvIGJlXG4gIC8vICpiZWxvdyogdGhlIGNhbGwgdG8gX3JlYWQuICBUaGUgcmVhc29uIGlzIHRoYXQgaW4gY2VydGFpblxuICAvLyBzeW50aGV0aWMgc3RyZWFtIGNhc2VzLCBzdWNoIGFzIHBhc3N0aHJvdWdoIHN0cmVhbXMsIF9yZWFkXG4gIC8vIG1heSBiZSBhIGNvbXBsZXRlbHkgc3luY2hyb25vdXMgb3BlcmF0aW9uIHdoaWNoIG1heSBjaGFuZ2VcbiAgLy8gdGhlIHN0YXRlIG9mIHRoZSByZWFkIGJ1ZmZlciwgcHJvdmlkaW5nIGVub3VnaCBkYXRhIHdoZW5cbiAgLy8gYmVmb3JlIHRoZXJlIHdhcyAqbm90KiBlbm91Z2guXG4gIC8vXG4gIC8vIFNvLCB0aGUgc3RlcHMgYXJlOlxuICAvLyAxLiBGaWd1cmUgb3V0IHdoYXQgdGhlIHN0YXRlIG9mIHRoaW5ncyB3aWxsIGJlIGFmdGVyIHdlIGRvXG4gIC8vIGEgcmVhZCBmcm9tIHRoZSBidWZmZXIuXG4gIC8vXG4gIC8vIDIuIElmIHRoYXQgcmVzdWx0aW5nIHN0YXRlIHdpbGwgdHJpZ2dlciBhIF9yZWFkLCB0aGVuIGNhbGwgX3JlYWQuXG4gIC8vIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBhc3luY2hyb25vdXMsIG9yIHN5bmNocm9ub3VzLiAgWWVzLCBpdCBpc1xuICAvLyBkZWVwbHkgdWdseSB0byB3cml0ZSBBUElzIHRoaXMgd2F5LCBidXQgdGhhdCBzdGlsbCBkb2Vzbid0IG1lYW5cbiAgLy8gdGhhdCB0aGUgUmVhZGFibGUgY2xhc3Mgc2hvdWxkIGJlaGF2ZSBpbXByb3Blcmx5LCBhcyBzdHJlYW1zIGFyZVxuICAvLyBkZXNpZ25lZCB0byBiZSBzeW5jL2FzeW5jIGFnbm9zdGljLlxuICAvLyBUYWtlIG5vdGUgaWYgdGhlIF9yZWFkIGNhbGwgaXMgc3luYyBvciBhc3luYyAoaWUsIGlmIHRoZSByZWFkIGNhbGxcbiAgLy8gaGFzIHJldHVybmVkIHlldCksIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIG9yIG5vdCBpdCdzIHNhZmUgdG8gZW1pdFxuICAvLyAncmVhZGFibGUnIGV0Yy5cbiAgLy9cbiAgLy8gMy4gQWN0dWFsbHkgcHVsbCB0aGUgcmVxdWVzdGVkIGNodW5rcyBvdXQgb2YgdGhlIGJ1ZmZlciBhbmQgcmV0dXJuLlxuXG4gIC8vIGlmIHdlIG5lZWQgYSByZWFkYWJsZSBldmVudCwgdGhlbiB3ZSBuZWVkIHRvIGRvIHNvbWUgcmVhZGluZy5cbiAgdmFyIGRvUmVhZCA9IHN0YXRlLm5lZWRSZWFkYWJsZTtcbiAgZGVidWcoJ25lZWQgcmVhZGFibGUnLCBkb1JlYWQpO1xuXG4gIC8vIGlmIHdlIGN1cnJlbnRseSBoYXZlIGxlc3MgdGhhbiB0aGUgaGlnaFdhdGVyTWFyaywgdGhlbiBhbHNvIHJlYWQgc29tZVxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwIHx8IHN0YXRlLmxlbmd0aCAtIG4gPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZG9SZWFkID0gdHJ1ZTtcbiAgICBkZWJ1ZygnbGVuZ3RoIGxlc3MgdGhhbiB3YXRlcm1hcmsnLCBkb1JlYWQpO1xuICB9XG5cbiAgLy8gaG93ZXZlciwgaWYgd2UndmUgZW5kZWQsIHRoZW4gdGhlcmUncyBubyBwb2ludCwgYW5kIGlmIHdlJ3JlIGFscmVhZHlcbiAgLy8gcmVhZGluZywgdGhlbiBpdCdzIHVubmVjZXNzYXJ5LlxuICBpZiAoc3RhdGUuZW5kZWQgfHwgc3RhdGUucmVhZGluZykge1xuICAgIGRvUmVhZCA9IGZhbHNlO1xuICAgIGRlYnVnKCdyZWFkaW5nIG9yIGVuZGVkJywgZG9SZWFkKTtcbiAgfSBlbHNlIGlmIChkb1JlYWQpIHtcbiAgICBkZWJ1ZygnZG8gcmVhZCcpO1xuICAgIHN0YXRlLnJlYWRpbmcgPSB0cnVlO1xuICAgIHN0YXRlLnN5bmMgPSB0cnVlO1xuICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgY3VycmVudGx5IHplcm8sIHRoZW4gd2UgKm5lZWQqIGEgcmVhZGFibGUgZXZlbnQuXG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAvLyBjYWxsIGludGVybmFsIHJlYWQgbWV0aG9kXG4gICAgdGhpcy5fcmVhZChzdGF0ZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICBzdGF0ZS5zeW5jID0gZmFsc2U7XG4gICAgLy8gSWYgX3JlYWQgcHVzaGVkIGRhdGEgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2Agd2lsbCBiZSBmYWxzZSxcbiAgICAvLyBhbmQgd2UgbmVlZCB0byByZS1ldmFsdWF0ZSBob3cgbXVjaCBkYXRhIHdlIGNhbiByZXR1cm4gdG8gdGhlIHVzZXIuXG4gICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSBuID0gaG93TXVjaFRvUmVhZChuT3JpZywgc3RhdGUpO1xuICB9XG5cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKSByZXQgPSBmcm9tTGlzdChuLCBzdGF0ZSk7ZWxzZSByZXQgPSBudWxsO1xuXG4gIGlmIChyZXQgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIG4gPSAwO1xuICB9IGVsc2Uge1xuICAgIHN0YXRlLmxlbmd0aCAtPSBuO1xuICB9XG5cbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIElmIHdlIGhhdmUgbm90aGluZyBpbiB0aGUgYnVmZmVyLCB0aGVuIHdlIHdhbnQgdG8ga25vd1xuICAgIC8vIGFzIHNvb24gYXMgd2UgKmRvKiBnZXQgc29tZXRoaW5nIGludG8gdGhlIGJ1ZmZlci5cbiAgICBpZiAoIXN0YXRlLmVuZGVkKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gICAgLy8gSWYgd2UgdHJpZWQgdG8gcmVhZCgpIHBhc3QgdGhlIEVPRiwgdGhlbiBlbWl0IGVuZCBvbiB0aGUgbmV4dCB0aWNrLlxuICAgIGlmIChuT3JpZyAhPT0gbiAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7XG4gIH1cblxuICBpZiAocmV0ICE9PSBudWxsKSB0aGlzLmVtaXQoJ2RhdGEnLCByZXQpO1xuXG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG4gIGlmIChzdGF0ZS5kZWNvZGVyKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICAvLyBlbWl0ICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmICghc3RhdGUuZW1pdHRlZFJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ2VtaXRSZWFkYWJsZScsIHN0YXRlLmZsb3dpbmcpO1xuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgaWYgKHN0YXRlLnN5bmMpIHBuYS5uZXh0VGljayhlbWl0UmVhZGFibGVfLCBzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIGRlYnVnKCdlbWl0IHJlYWRhYmxlJyk7XG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICBmbG93KHN0cmVhbSk7XG59XG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgcG5hLm5leHRUaWNrKG1heWJlUmVhZE1vcmVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRlYnVnKCdtYXliZVJlYWRNb3JlIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICAgIGlmIChsZW4gPT09IHN0YXRlLmxlbmd0aClcbiAgICAgIC8vIGRpZG4ndCBnZXQgYW55IGRhdGEsIHN0b3Agc3Bpbm5pbmcuXG4gICAgICBicmVhaztlbHNlIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ19yZWFkKCkgaXMgbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoZGVzdCwgcGlwZU9wdHMpIHtcbiAgdmFyIHNyYyA9IHRoaXM7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgc3dpdGNoIChzdGF0ZS5waXBlc0NvdW50KSB7XG4gICAgY2FzZSAwOlxuICAgICAgc3RhdGUucGlwZXMgPSBkZXN0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAxOlxuICAgICAgc3RhdGUucGlwZXMgPSBbc3RhdGUucGlwZXMsIGRlc3RdO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHN0YXRlLnBpcGVzLnB1c2goZGVzdCk7XG4gICAgICBicmVhaztcbiAgfVxuICBzdGF0ZS5waXBlc0NvdW50ICs9IDE7XG4gIGRlYnVnKCdwaXBlIGNvdW50PSVkIG9wdHM9JWonLCBzdGF0ZS5waXBlc0NvdW50LCBwaXBlT3B0cyk7XG5cbiAgdmFyIGRvRW5kID0gKCFwaXBlT3B0cyB8fCBwaXBlT3B0cy5lbmQgIT09IGZhbHNlKSAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZG91dCAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZGVycjtcblxuICB2YXIgZW5kRm4gPSBkb0VuZCA/IG9uZW5kIDogdW5waXBlO1xuICBpZiAoc3RhdGUuZW5kRW1pdHRlZCkgcG5hLm5leHRUaWNrKGVuZEZuKTtlbHNlIHNyYy5vbmNlKCdlbmQnLCBlbmRGbik7XG5cbiAgZGVzdC5vbigndW5waXBlJywgb251bnBpcGUpO1xuICBmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSwgdW5waXBlSW5mbykge1xuICAgIGRlYnVnKCdvbnVucGlwZScpO1xuICAgIGlmIChyZWFkYWJsZSA9PT0gc3JjKSB7XG4gICAgICBpZiAodW5waXBlSW5mbyAmJiB1bnBpcGVJbmZvLmhhc1VucGlwZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHVucGlwZUluZm8uaGFzVW5waXBlZCA9IHRydWU7XG4gICAgICAgIGNsZWFudXAoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBkZWJ1Zygnb25lbmQnKTtcbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cbiAgLy8gd2hlbiB0aGUgZGVzdCBkcmFpbnMsIGl0IHJlZHVjZXMgdGhlIGF3YWl0RHJhaW4gY291bnRlclxuICAvLyBvbiB0aGUgc291cmNlLiAgVGhpcyB3b3VsZCBiZSBtb3JlIGVsZWdhbnQgd2l0aCBhIC5vbmNlKClcbiAgLy8gaGFuZGxlciBpbiBmbG93KCksIGJ1dCBhZGRpbmcgYW5kIHJlbW92aW5nIHJlcGVhdGVkbHkgaXNcbiAgLy8gdG9vIHNsb3cuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICB2YXIgY2xlYW5lZFVwID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgZGVidWcoJ2NsZWFudXAnKTtcbiAgICAvLyBjbGVhbnVwIGV2ZW50IGhhbmRsZXJzIG9uY2UgdGhlIHBpcGUgaXMgYnJva2VuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ3VucGlwZScsIG9udW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIHVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcblxuICAgIGNsZWFuZWRVcCA9IHRydWU7XG5cbiAgICAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluICYmICghZGVzdC5fd3JpdGFibGVTdGF0ZSB8fCBkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbikpIG9uZHJhaW4oKTtcbiAgfVxuXG4gIC8vIElmIHRoZSB1c2VyIHB1c2hlcyBtb3JlIGRhdGEgd2hpbGUgd2UncmUgd3JpdGluZyB0byBkZXN0IHRoZW4gd2UnbGwgZW5kIHVwXG4gIC8vIGluIG9uZGF0YSBhZ2Fpbi4gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIGluY3JlYXNlIGF3YWl0RHJhaW4gb25jZSBiZWNhdXNlXG4gIC8vIGRlc3Qgd2lsbCBvbmx5IGVtaXQgb25lICdkcmFpbicgZXZlbnQgZm9yIHRoZSBtdWx0aXBsZSB3cml0ZXMuXG4gIC8vID0+IEludHJvZHVjZSBhIGd1YXJkIG9uIGluY3JlYXNpbmcgYXdhaXREcmFpbi5cbiAgdmFyIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgc3JjLm9uKCdkYXRhJywgb25kYXRhKTtcbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgZGVidWcoJ29uZGF0YScpO1xuICAgIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgICB2YXIgcmV0ID0gZGVzdC53cml0ZShjaHVuayk7XG4gICAgaWYgKGZhbHNlID09PSByZXQgJiYgIWluY3JlYXNlZEF3YWl0RHJhaW4pIHtcbiAgICAgIC8vIElmIHRoZSB1c2VyIHVucGlwZWQgZHVyaW5nIGBkZXN0LndyaXRlKClgLCBpdCBpcyBwb3NzaWJsZVxuICAgICAgLy8gdG8gZ2V0IHN0dWNrIGluIGEgcGVybWFuZW50bHkgcGF1c2VkIHN0YXRlIGlmIHRoYXQgd3JpdGVcbiAgICAgIC8vIGFsc28gcmV0dXJuZWQgZmFsc2UuXG4gICAgICAvLyA9PiBDaGVjayB3aGV0aGVyIGBkZXN0YCBpcyBzdGlsbCBhIHBpcGluZyBkZXN0aW5hdGlvbi5cbiAgICAgIGlmICgoc3RhdGUucGlwZXNDb3VudCA9PT0gMSAmJiBzdGF0ZS5waXBlcyA9PT0gZGVzdCB8fCBzdGF0ZS5waXBlc0NvdW50ID4gMSAmJiBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KSAhPT0gLTEpICYmICFjbGVhbmVkVXApIHtcbiAgICAgICAgZGVidWcoJ2ZhbHNlIHdyaXRlIHJlc3BvbnNlLCBwYXVzZScsIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKTtcbiAgICAgICAgc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4rKztcbiAgICAgICAgaW5jcmVhc2VkQXdhaXREcmFpbiA9IHRydWU7XG4gICAgICB9XG4gICAgICBzcmMucGF1c2UoKTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgZGVzdCBoYXMgYW4gZXJyb3IsIHRoZW4gc3RvcCBwaXBpbmcgaW50byBpdC5cbiAgLy8gaG93ZXZlciwgZG9uJ3Qgc3VwcHJlc3MgdGhlIHRocm93aW5nIGJlaGF2aW9yIGZvciB0aGlzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgZGVidWcoJ29uZXJyb3InLCBlcik7XG4gICAgdW5waXBlKCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBpZiAoRUVsaXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpID09PSAwKSBkZXN0LmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIG91ciBlcnJvciBoYW5kbGVyIGlzIGF0dGFjaGVkIGJlZm9yZSB1c2VybGFuZCBvbmVzLlxuICBwcmVwZW5kTGlzdGVuZXIoZGVzdCwgJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZWJ1Zygnb25maW5pc2gnKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBkZWJ1ZygndW5waXBlJyk7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfVxuXG4gIC8vIHRlbGwgdGhlIGRlc3QgdGhhdCBpdCdzIGJlaW5nIHBpcGVkIHRvXG4gIGRlc3QuZW1pdCgncGlwZScsIHNyYyk7XG5cbiAgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGlwZSByZXN1bWUnKTtcbiAgICBzcmMucmVzdW1lKCk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBkZWJ1ZygncGlwZU9uRHJhaW4nLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbikgc3RhdGUuYXdhaXREcmFpbi0tO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluID09PSAwICYmIEVFbGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykpIHtcbiAgICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgICAgZmxvdyhzcmMpO1xuICAgIH1cbiAgfTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uIChkZXN0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciB1bnBpcGVJbmZvID0geyBoYXNVbnBpcGVkOiBmYWxzZSB9O1xuXG4gIC8vIGlmIHdlJ3JlIG5vdCBwaXBpbmcgYW55d2hlcmUsIHRoZW4gZG8gbm90aGluZy5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApIHJldHVybiB0aGlzO1xuXG4gIC8vIGp1c3Qgb25lIGRlc3RpbmF0aW9uLiAgbW9zdCBjb21tb24gY2FzZS5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHtcbiAgICAvLyBwYXNzZWQgaW4gb25lLCBidXQgaXQncyBub3QgdGhlIHJpZ2h0IG9uZS5cbiAgICBpZiAoZGVzdCAmJiBkZXN0ICE9PSBzdGF0ZS5waXBlcykgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoIWRlc3QpIGRlc3QgPSBzdGF0ZS5waXBlcztcblxuICAgIC8vIGdvdCBhIG1hdGNoLlxuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgaWYgKGRlc3QpIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzbG93IGNhc2UuIG11bHRpcGxlIHBpcGUgZGVzdGluYXRpb25zLlxuXG4gIGlmICghZGVzdCkge1xuICAgIC8vIHJlbW92ZSBhbGwuXG4gICAgdmFyIGRlc3RzID0gc3RhdGUucGlwZXM7XG4gICAgdmFyIGxlbiA9IHN0YXRlLnBpcGVzQ291bnQ7XG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGRlc3RzW2ldLmVtaXQoJ3VucGlwZScsIHRoaXMsIHVucGlwZUluZm8pO1xuICAgIH1yZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHRyeSB0byBmaW5kIHRoZSByaWdodCBvbmUuXG4gIHZhciBpbmRleCA9IGluZGV4T2Yoc3RhdGUucGlwZXMsIGRlc3QpO1xuICBpZiAoaW5kZXggPT09IC0xKSByZXR1cm4gdGhpcztcblxuICBzdGF0ZS5waXBlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICBzdGF0ZS5waXBlc0NvdW50IC09IDE7XG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuXG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBzZXQgdXAgZGF0YSBldmVudHMgaWYgdGhleSBhcmUgYXNrZWQgZm9yXG4vLyBFbnN1cmUgcmVhZGFibGUgbGlzdGVuZXJzIGV2ZW50dWFsbHkgZ2V0IHNvbWV0aGluZ1xuUmVhZGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2LCBmbikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKHRoaXMsIGV2LCBmbik7XG5cbiAgaWYgKGV2ID09PSAnZGF0YScpIHtcbiAgICAvLyBTdGFydCBmbG93aW5nIG9uIG5leHQgdGljayBpZiBzdHJlYW0gaXNuJ3QgZXhwbGljaXRseSBwYXVzZWRcbiAgICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nICE9PSBmYWxzZSkgdGhpcy5yZXN1bWUoKTtcbiAgfSBlbHNlIGlmIChldiA9PT0gJ3JlYWRhYmxlJykge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmICFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgcG5hLm5leHRUaWNrKG5SZWFkaW5nTmV4dFRpY2ssIHRoaXMpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5sZW5ndGgpIHtcbiAgICAgICAgZW1pdFJlYWRhYmxlKHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyID0gUmVhZGFibGUucHJvdG90eXBlLm9uO1xuXG5mdW5jdGlvbiBuUmVhZGluZ05leHRUaWNrKHNlbGYpIHtcbiAgZGVidWcoJ3JlYWRhYmxlIG5leHR0aWNrIHJlYWQgMCcpO1xuICBzZWxmLnJlYWQoMCk7XG59XG5cbi8vIHBhdXNlKCkgYW5kIHJlc3VtZSgpIGFyZSByZW1uYW50cyBvZiB0aGUgbGVnYWN5IHJlYWRhYmxlIHN0cmVhbSBBUElcbi8vIElmIHRoZSB1c2VyIHVzZXMgdGhlbSwgdGhlbiBzd2l0Y2ggaW50byBvbGQgbW9kZS5cblJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdyZXN1bWUnKTtcbiAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICByZXN1bWUodGhpcywgc3RhdGUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gcmVzdW1lKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZXN1bWVTY2hlZHVsZWQpIHtcbiAgICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSB0cnVlO1xuICAgIHBuYS5uZXh0VGljayhyZXN1bWVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuICBzdGF0ZS5hd2FpdERyYWluID0gMDtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKSBzdHJlYW0ucmVhZCgwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2FsbCBwYXVzZSBmbG93aW5nPSVqJywgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtcbiAgaWYgKGZhbHNlICE9PSB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGF1c2UnKTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmbG93KHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdmbG93Jywgc3RhdGUuZmxvd2luZyk7XG4gIHdoaWxlIChzdGF0ZS5mbG93aW5nICYmIHN0cmVhbS5yZWFkKCkgIT09IG51bGwpIHt9XG59XG5cbi8vIHdyYXAgYW4gb2xkLXN0eWxlIHN0cmVhbSBhcyB0aGUgYXN5bmMgZGF0YSBzb3VyY2UuXG4vLyBUaGlzIGlzICpub3QqIHBhcnQgb2YgdGhlIHJlYWRhYmxlIHN0cmVhbSBpbnRlcmZhY2UuXG4vLyBJdCBpcyBhbiB1Z2x5IHVuZm9ydHVuYXRlIG1lc3Mgb2YgaGlzdG9yeS5cblJlYWRhYmxlLnByb3RvdHlwZS53cmFwID0gZnVuY3Rpb24gKHN0cmVhbSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBwYXVzZWQgPSBmYWxzZTtcblxuICBzdHJlYW0ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBlbmQnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSBfdGhpcy5wdXNoKGNodW5rKTtcbiAgICB9XG5cbiAgICBfdGhpcy5wdXNoKG51bGwpO1xuICB9KTtcblxuICBzdHJlYW0ub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBkYXRhJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG5cbiAgICAvLyBkb24ndCBza2lwIG92ZXIgZmFsc3kgdmFsdWVzIGluIG9iamVjdE1vZGVcbiAgICBpZiAoc3RhdGUub2JqZWN0TW9kZSAmJiAoY2h1bmsgPT09IG51bGwgfHwgY2h1bmsgPT09IHVuZGVmaW5lZCkpIHJldHVybjtlbHNlIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiAoIWNodW5rIHx8ICFjaHVuay5sZW5ndGgpKSByZXR1cm47XG5cbiAgICB2YXIgcmV0ID0gX3RoaXMucHVzaChjaHVuayk7XG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHByb3h5IGFsbCB0aGUgb3RoZXIgbWV0aG9kcy5cbiAgLy8gaW1wb3J0YW50IHdoZW4gd3JhcHBpbmcgZmlsdGVycyBhbmQgZHVwbGV4ZXMuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHRoaXNbaV0gPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBzdHJlYW1bbWV0aG9kXS5hcHBseShzdHJlYW0sIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgICB9KGkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHByb3h5IGNlcnRhaW4gaW1wb3J0YW50IGV2ZW50cy5cbiAgZm9yICh2YXIgbiA9IDA7IG4gPCBrUHJveHlFdmVudHMubGVuZ3RoOyBuKyspIHtcbiAgICBzdHJlYW0ub24oa1Byb3h5RXZlbnRzW25dLCB0aGlzLmVtaXQuYmluZCh0aGlzLCBrUHJveHlFdmVudHNbbl0pKTtcbiAgfVxuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHRoaXMuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICAgIGRlYnVnKCd3cmFwcGVkIF9yZWFkJywgbik7XG4gICAgaWYgKHBhdXNlZCkge1xuICAgICAgcGF1c2VkID0gZmFsc2U7XG4gICAgICBzdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ3JlYWRhYmxlSGlnaFdhdGVyTWFyaycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgfVxufSk7XG5cbi8vIGV4cG9zZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS5cblJlYWRhYmxlLl9mcm9tTGlzdCA9IGZyb21MaXN0O1xuXG4vLyBQbHVjayBvZmYgbiBieXRlcyBmcm9tIGFuIGFycmF5IG9mIGJ1ZmZlcnMuXG4vLyBMZW5ndGggaXMgdGhlIGNvbWJpbmVkIGxlbmd0aHMgb2YgYWxsIHRoZSBidWZmZXJzIGluIHRoZSBsaXN0LlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBmcm9tTGlzdChuLCBzdGF0ZSkge1xuICAvLyBub3RoaW5nIGJ1ZmZlcmVkXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gIHZhciByZXQ7XG4gIGlmIChzdGF0ZS5vYmplY3RNb2RlKSByZXQgPSBzdGF0ZS5idWZmZXIuc2hpZnQoKTtlbHNlIGlmICghbiB8fCBuID49IHN0YXRlLmxlbmd0aCkge1xuICAgIC8vIHJlYWQgaXQgYWxsLCB0cnVuY2F0ZSB0aGUgbGlzdFxuICAgIGlmIChzdGF0ZS5kZWNvZGVyKSByZXQgPSBzdGF0ZS5idWZmZXIuam9pbignJyk7ZWxzZSBpZiAoc3RhdGUuYnVmZmVyLmxlbmd0aCA9PT0gMSkgcmV0ID0gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YTtlbHNlIHJldCA9IHN0YXRlLmJ1ZmZlci5jb25jYXQoc3RhdGUubGVuZ3RoKTtcbiAgICBzdGF0ZS5idWZmZXIuY2xlYXIoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWFkIHBhcnQgb2YgbGlzdFxuICAgIHJldCA9IGZyb21MaXN0UGFydGlhbChuLCBzdGF0ZS5idWZmZXIsIHN0YXRlLmRlY29kZXIpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuLy8gRXh0cmFjdHMgb25seSBlbm91Z2ggYnVmZmVyZWQgZGF0YSB0byBzYXRpc2Z5IHRoZSBhbW91bnQgcmVxdWVzdGVkLlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBmcm9tTGlzdFBhcnRpYWwobiwgbGlzdCwgaGFzU3RyaW5ncykge1xuICB2YXIgcmV0O1xuICBpZiAobiA8IGxpc3QuaGVhZC5kYXRhLmxlbmd0aCkge1xuICAgIC8vIHNsaWNlIGlzIHRoZSBzYW1lIGZvciBidWZmZXJzIGFuZCBzdHJpbmdzXG4gICAgcmV0ID0gbGlzdC5oZWFkLmRhdGEuc2xpY2UoMCwgbik7XG4gICAgbGlzdC5oZWFkLmRhdGEgPSBsaXN0LmhlYWQuZGF0YS5zbGljZShuKTtcbiAgfSBlbHNlIGlmIChuID09PSBsaXN0LmhlYWQuZGF0YS5sZW5ndGgpIHtcbiAgICAvLyBmaXJzdCBjaHVuayBpcyBhIHBlcmZlY3QgbWF0Y2hcbiAgICByZXQgPSBsaXN0LnNoaWZ0KCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVzdWx0IHNwYW5zIG1vcmUgdGhhbiBvbmUgYnVmZmVyXG4gICAgcmV0ID0gaGFzU3RyaW5ncyA/IGNvcHlGcm9tQnVmZmVyU3RyaW5nKG4sIGxpc3QpIDogY29weUZyb21CdWZmZXIobiwgbGlzdCk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuLy8gQ29waWVzIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBjaGFyYWN0ZXJzIGZyb20gdGhlIGxpc3Qgb2YgYnVmZmVyZWQgZGF0YVxuLy8gY2h1bmtzLlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBjb3B5RnJvbUJ1ZmZlclN0cmluZyhuLCBsaXN0KSB7XG4gIHZhciBwID0gbGlzdC5oZWFkO1xuICB2YXIgYyA9IDE7XG4gIHZhciByZXQgPSBwLmRhdGE7XG4gIG4gLT0gcmV0Lmxlbmd0aDtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICB2YXIgc3RyID0gcC5kYXRhO1xuICAgIHZhciBuYiA9IG4gPiBzdHIubGVuZ3RoID8gc3RyLmxlbmd0aCA6IG47XG4gICAgaWYgKG5iID09PSBzdHIubGVuZ3RoKSByZXQgKz0gc3RyO2Vsc2UgcmV0ICs9IHN0ci5zbGljZSgwLCBuKTtcbiAgICBuIC09IG5iO1xuICAgIGlmIChuID09PSAwKSB7XG4gICAgICBpZiAobmIgPT09IHN0ci5sZW5ndGgpIHtcbiAgICAgICAgKytjO1xuICAgICAgICBpZiAocC5uZXh0KSBsaXN0LmhlYWQgPSBwLm5leHQ7ZWxzZSBsaXN0LmhlYWQgPSBsaXN0LnRhaWwgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGlzdC5oZWFkID0gcDtcbiAgICAgICAgcC5kYXRhID0gc3RyLnNsaWNlKG5iKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICArK2M7XG4gIH1cbiAgbGlzdC5sZW5ndGggLT0gYztcbiAgcmV0dXJuIHJldDtcbn1cblxuLy8gQ29waWVzIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBieXRlcyBmcm9tIHRoZSBsaXN0IG9mIGJ1ZmZlcmVkIGRhdGEgY2h1bmtzLlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBjb3B5RnJvbUJ1ZmZlcihuLCBsaXN0KSB7XG4gIHZhciByZXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobik7XG4gIHZhciBwID0gbGlzdC5oZWFkO1xuICB2YXIgYyA9IDE7XG4gIHAuZGF0YS5jb3B5KHJldCk7XG4gIG4gLT0gcC5kYXRhLmxlbmd0aDtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICB2YXIgYnVmID0gcC5kYXRhO1xuICAgIHZhciBuYiA9IG4gPiBidWYubGVuZ3RoID8gYnVmLmxlbmd0aCA6IG47XG4gICAgYnVmLmNvcHkocmV0LCByZXQubGVuZ3RoIC0gbiwgMCwgbmIpO1xuICAgIG4gLT0gbmI7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIGlmIChuYiA9PT0gYnVmLmxlbmd0aCkge1xuICAgICAgICArK2M7XG4gICAgICAgIGlmIChwLm5leHQpIGxpc3QuaGVhZCA9IHAubmV4dDtlbHNlIGxpc3QuaGVhZCA9IGxpc3QudGFpbCA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaXN0LmhlYWQgPSBwO1xuICAgICAgICBwLmRhdGEgPSBidWYuc2xpY2UobmIpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgICsrYztcbiAgfVxuICBsaXN0Lmxlbmd0aCAtPSBjO1xuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIElmIHdlIGdldCBoZXJlIGJlZm9yZSBjb25zdW1pbmcgYWxsIHRoZSBieXRlcywgdGhlbiB0aGF0IGlzIGFcbiAgLy8gYnVnIGluIG5vZGUuICBTaG91bGQgbmV2ZXIgaGFwcGVuLlxuICBpZiAoc3RhdGUubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEVycm9yKCdcImVuZFJlYWRhYmxlKClcIiBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO1xuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCkge1xuICAgIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgICBwbmEubmV4dFRpY2soZW5kUmVhZGFibGVOVCwgc3RhdGUsIHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSwgc3RyZWFtKSB7XG4gIC8vIENoZWNrIHRoYXQgd2UgZGlkbid0IGdldCBvbmUgbGFzdCB1bnNoaWZ0LlxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKSB7XG4gICAgc3RhdGUuZW5kRW1pdHRlZCA9IHRydWU7XG4gICAgc3RyZWFtLnJlYWRhYmxlID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2VuZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gYSB0cmFuc2Zvcm0gc3RyZWFtIGlzIGEgcmVhZGFibGUvd3JpdGFibGUgc3RyZWFtIHdoZXJlIHlvdSBkb1xuLy8gc29tZXRoaW5nIHdpdGggdGhlIGRhdGEuICBTb21ldGltZXMgaXQncyBjYWxsZWQgYSBcImZpbHRlclwiLFxuLy8gYnV0IHRoYXQncyBub3QgYSBncmVhdCBuYW1lIGZvciBpdCwgc2luY2UgdGhhdCBpbXBsaWVzIGEgdGhpbmcgd2hlcmVcbi8vIHNvbWUgYml0cyBwYXNzIHRocm91Z2gsIGFuZCBvdGhlcnMgYXJlIHNpbXBseSBpZ25vcmVkLiAgKFRoYXQgd291bGRcbi8vIGJlIGEgdmFsaWQgZXhhbXBsZSBvZiBhIHRyYW5zZm9ybSwgb2YgY291cnNlLilcbi8vXG4vLyBXaGlsZSB0aGUgb3V0cHV0IGlzIGNhdXNhbGx5IHJlbGF0ZWQgdG8gdGhlIGlucHV0LCBpdCdzIG5vdCBhXG4vLyBuZWNlc3NhcmlseSBzeW1tZXRyaWMgb3Igc3luY2hyb25vdXMgdHJhbnNmb3JtYXRpb24uICBGb3IgZXhhbXBsZSxcbi8vIGEgemxpYiBzdHJlYW0gbWlnaHQgdGFrZSBtdWx0aXBsZSBwbGFpbi10ZXh0IHdyaXRlcygpLCBhbmQgdGhlblxuLy8gZW1pdCBhIHNpbmdsZSBjb21wcmVzc2VkIGNodW5rIHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLlxuLy9cbi8vIEhlcmUncyBob3cgdGhpcyB3b3Jrczpcbi8vXG4vLyBUaGUgVHJhbnNmb3JtIHN0cmVhbSBoYXMgYWxsIHRoZSBhc3BlY3RzIG9mIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGVcbi8vIHN0cmVhbSBjbGFzc2VzLiAgV2hlbiB5b3Ugd3JpdGUoY2h1bmspLCB0aGF0IGNhbGxzIF93cml0ZShjaHVuayxjYilcbi8vIGludGVybmFsbHksIGFuZCByZXR1cm5zIGZhbHNlIGlmIHRoZXJlJ3MgYSBsb3Qgb2YgcGVuZGluZyB3cml0ZXNcbi8vIGJ1ZmZlcmVkIHVwLiAgV2hlbiB5b3UgY2FsbCByZWFkKCksIHRoYXQgY2FsbHMgX3JlYWQobikgdW50aWxcbi8vIHRoZXJlJ3MgZW5vdWdoIHBlbmRpbmcgcmVhZGFibGUgZGF0YSBidWZmZXJlZCB1cC5cbi8vXG4vLyBJbiBhIHRyYW5zZm9ybSBzdHJlYW0sIHRoZSB3cml0dGVuIGRhdGEgaXMgcGxhY2VkIGluIGEgYnVmZmVyLiAgV2hlblxuLy8gX3JlYWQobikgaXMgY2FsbGVkLCBpdCB0cmFuc2Zvcm1zIHRoZSBxdWV1ZWQgdXAgZGF0YSwgY2FsbGluZyB0aGVcbi8vIGJ1ZmZlcmVkIF93cml0ZSBjYidzIGFzIGl0IGNvbnN1bWVzIGNodW5rcy4gIElmIGNvbnN1bWluZyBhIHNpbmdsZVxuLy8gd3JpdHRlbiBjaHVuayB3b3VsZCByZXN1bHQgaW4gbXVsdGlwbGUgb3V0cHV0IGNodW5rcywgdGhlbiB0aGUgZmlyc3Rcbi8vIG91dHB1dHRlZCBiaXQgY2FsbHMgdGhlIHJlYWRjYiwgYW5kIHN1YnNlcXVlbnQgY2h1bmtzIGp1c3QgZ28gaW50b1xuLy8gdGhlIHJlYWQgYnVmZmVyLCBhbmQgd2lsbCBjYXVzZSBpdCB0byBlbWl0ICdyZWFkYWJsZScgaWYgbmVjZXNzYXJ5LlxuLy9cbi8vIFRoaXMgd2F5LCBiYWNrLXByZXNzdXJlIGlzIGFjdHVhbGx5IGRldGVybWluZWQgYnkgdGhlIHJlYWRpbmcgc2lkZSxcbi8vIHNpbmNlIF9yZWFkIGhhcyB0byBiZSBjYWxsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZyBhIG5ldyBjaHVuay4gIEhvd2V2ZXIsXG4vLyBhIHBhdGhvbG9naWNhbCBpbmZsYXRlIHR5cGUgb2YgdHJhbnNmb3JtIGNhbiBjYXVzZSBleGNlc3NpdmUgYnVmZmVyaW5nXG4vLyBoZXJlLiAgRm9yIGV4YW1wbGUsIGltYWdpbmUgYSBzdHJlYW0gd2hlcmUgZXZlcnkgYnl0ZSBvZiBpbnB1dCBpc1xuLy8gaW50ZXJwcmV0ZWQgYXMgYW4gaW50ZWdlciBmcm9tIDAtMjU1LCBhbmQgdGhlbiByZXN1bHRzIGluIHRoYXQgbWFueVxuLy8gYnl0ZXMgb2Ygb3V0cHV0LiAgV3JpdGluZyB0aGUgNCBieXRlcyB7ZmYsZmYsZmYsZmZ9IHdvdWxkIHJlc3VsdCBpblxuLy8gMWtiIG9mIGRhdGEgYmVpbmcgb3V0cHV0LiAgSW4gdGhpcyBjYXNlLCB5b3UgY291bGQgd3JpdGUgYSB2ZXJ5IHNtYWxsXG4vLyBhbW91bnQgb2YgaW5wdXQsIGFuZCBlbmQgdXAgd2l0aCBhIHZlcnkgbGFyZ2UgYW1vdW50IG9mIG91dHB1dC4gIEluXG4vLyBzdWNoIGEgcGF0aG9sb2dpY2FsIGluZmxhdGluZyBtZWNoYW5pc20sIHRoZXJlJ2QgYmUgbm8gd2F5IHRvIHRlbGxcbi8vIHRoZSBzeXN0ZW0gdG8gc3RvcCBkb2luZyB0aGUgdHJhbnNmb3JtLiAgQSBzaW5nbGUgNE1CIHdyaXRlIGNvdWxkXG4vLyBjYXVzZSB0aGUgc3lzdGVtIHRvIHJ1biBvdXQgb2YgbWVtb3J5LlxuLy9cbi8vIEhvd2V2ZXIsIGV2ZW4gaW4gc3VjaCBhIHBhdGhvbG9naWNhbCBjYXNlLCBvbmx5IGEgc2luZ2xlIHdyaXR0ZW4gY2h1bmtcbi8vIHdvdWxkIGJlIGNvbnN1bWVkLCBhbmQgdGhlbiB0aGUgcmVzdCB3b3VsZCB3YWl0ICh1bi10cmFuc2Zvcm1lZCkgdW50aWxcbi8vIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm1lZCBjaHVuayB3ZXJlIGNvbnN1bWVkLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNmb3JtO1xuXG52YXIgRHVwbGV4ID0gcmVxdWlyZSg3OSk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoNDApO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoODcpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoVHJhbnNmb3JtLCBEdXBsZXgpO1xuXG5mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShlciwgZGF0YSkge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMudHJhbnNmb3JtaW5nID0gZmFsc2U7XG5cbiAgdmFyIGNiID0gdHMud3JpdGVjYjtcblxuICBpZiAoIWNiKSB7XG4gICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ3dyaXRlIGNhbGxiYWNrIGNhbGxlZCBtdWx0aXBsZSB0aW1lcycpKTtcbiAgfVxuXG4gIHRzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0cy53cml0ZWNiID0gbnVsbDtcblxuICBpZiAoZGF0YSAhPSBudWxsKSAvLyBzaW5nbGUgZXF1YWxzIGNoZWNrIGZvciBib3RoIGBudWxsYCBhbmQgYHVuZGVmaW5lZGBcbiAgICB0aGlzLnB1c2goZGF0YSk7XG5cbiAgY2IoZXIpO1xuXG4gIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHJzLnJlYWRpbmcgPSBmYWxzZTtcbiAgaWYgKHJzLm5lZWRSZWFkYWJsZSB8fCBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSkgcmV0dXJuIG5ldyBUcmFuc2Zvcm0ob3B0aW9ucyk7XG5cbiAgRHVwbGV4LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUgPSB7XG4gICAgYWZ0ZXJUcmFuc2Zvcm06IGFmdGVyVHJhbnNmb3JtLmJpbmQodGhpcyksXG4gICAgbmVlZFRyYW5zZm9ybTogZmFsc2UsXG4gICAgdHJhbnNmb3JtaW5nOiBmYWxzZSxcbiAgICB3cml0ZWNiOiBudWxsLFxuICAgIHdyaXRlY2h1bms6IG51bGwsXG4gICAgd3JpdGVlbmNvZGluZzogbnVsbFxuICB9O1xuXG4gIC8vIHN0YXJ0IG91dCBhc2tpbmcgZm9yIGEgcmVhZGFibGUgZXZlbnQgb25jZSBkYXRhIGlzIHRyYW5zZm9ybWVkLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gd2UgaGF2ZSBpbXBsZW1lbnRlZCB0aGUgX3JlYWQgbWV0aG9kLCBhbmQgZG9uZSB0aGUgb3RoZXIgdGhpbmdzXG4gIC8vIHRoYXQgUmVhZGFibGUgd2FudHMgYmVmb3JlIHRoZSBmaXJzdCBfcmVhZCBjYWxsLCBzbyB1bnNldCB0aGVcbiAgLy8gc3luYyBndWFyZCBmbGFnLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmMgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50cmFuc2Zvcm0gPT09ICdmdW5jdGlvbicpIHRoaXMuX3RyYW5zZm9ybSA9IG9wdGlvbnMudHJhbnNmb3JtO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZsdXNoID09PSAnZnVuY3Rpb24nKSB0aGlzLl9mbHVzaCA9IG9wdGlvbnMuZmx1c2g7XG4gIH1cblxuICAvLyBXaGVuIHRoZSB3cml0YWJsZSBzaWRlIGZpbmlzaGVzLCB0aGVuIGZsdXNoIG91dCBhbnl0aGluZyByZW1haW5pbmcuXG4gIHRoaXMub24oJ3ByZWZpbmlzaCcsIHByZWZpbmlzaCk7XG59XG5cbmZ1bmN0aW9uIHByZWZpbmlzaCgpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICBpZiAodHlwZW9mIHRoaXMuX2ZsdXNoID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5fZmx1c2goZnVuY3Rpb24gKGVyLCBkYXRhKSB7XG4gICAgICBkb25lKF90aGlzLCBlciwgZGF0YSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgZG9uZSh0aGlzLCBudWxsLCBudWxsKTtcbiAgfVxufVxuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgcmV0dXJuIER1cGxleC5wcm90b3R5cGUucHVzaC5jYWxsKHRoaXMsIGNodW5rLCBlbmNvZGluZyk7XG59O1xuXG4vLyBUaGlzIGlzIHRoZSBwYXJ0IHdoZXJlIHlvdSBkbyBzdHVmZiFcbi8vIG92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gaW4gaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vICdjaHVuaycgaXMgYW4gaW5wdXQgY2h1bmsuXG4vL1xuLy8gQ2FsbCBgcHVzaChuZXdDaHVuaylgIHRvIHBhc3MgYWxvbmcgdHJhbnNmb3JtZWQgb3V0cHV0XG4vLyB0byB0aGUgcmVhZGFibGUgc2lkZS4gIFlvdSBtYXkgY2FsbCAncHVzaCcgemVybyBvciBtb3JlIHRpbWVzLlxuLy9cbi8vIENhbGwgYGNiKGVycilgIHdoZW4geW91IGFyZSBkb25lIHdpdGggdGhpcyBjaHVuay4gIElmIHlvdSBwYXNzXG4vLyBhbiBlcnJvciwgdGhlbiB0aGF0J2xsIHB1dCB0aGUgaHVydCBvbiB0aGUgd2hvbGUgb3BlcmF0aW9uLiAgSWYgeW91XG4vLyBuZXZlciBjYWxsIGNiKCksIHRoZW4geW91J2xsIG5ldmVyIGdldCBhbm90aGVyIGNodW5rLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdHJhbnNmb3JtKCkgaXMgbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuICBpZiAoIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKHRzLm5lZWRUcmFuc2Zvcm0gfHwgcnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn07XG5cbi8vIERvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGFyZ3MgYXJlIGhlcmUuXG4vLyBfdHJhbnNmb3JtIGRvZXMgYWxsIHRoZSB3b3JrLlxuLy8gVGhhdCB3ZSBnb3QgaGVyZSBtZWFucyB0aGF0IHRoZSByZWFkYWJsZSBzaWRlIHdhbnRzIG1vcmUgZGF0YS5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAodHMud3JpdGVjaHVuayAhPT0gbnVsbCAmJiB0cy53cml0ZWNiICYmICF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB0cy50cmFuc2Zvcm1pbmcgPSB0cnVlO1xuICAgIHRoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLCB0cy53cml0ZWVuY29kaW5nLCB0cy5hZnRlclRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFyayB0aGF0IHdlIG5lZWQgYSB0cmFuc2Zvcm0sIHNvIHRoYXQgYW55IGRhdGEgdGhhdCBjb21lcyBpblxuICAgIC8vIHdpbGwgZ2V0IHByb2Nlc3NlZCwgbm93IHRoYXQgd2UndmUgYXNrZWQgZm9yIGl0LlxuICAgIHRzLm5lZWRUcmFuc2Zvcm0gPSB0cnVlO1xuICB9XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgRHVwbGV4LnByb3RvdHlwZS5fZGVzdHJveS5jYWxsKHRoaXMsIGVyciwgZnVuY3Rpb24gKGVycjIpIHtcbiAgICBjYihlcnIyKTtcbiAgICBfdGhpczIuZW1pdCgnY2xvc2UnKTtcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgaWYgKGVyKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuXG4gIGlmIChkYXRhICE9IG51bGwpIC8vIHNpbmdsZSBlcXVhbHMgY2hlY2sgZm9yIGJvdGggYG51bGxgIGFuZCBgdW5kZWZpbmVkYFxuICAgIHN0cmVhbS5wdXNoKGRhdGEpO1xuXG4gIC8vIGlmIHRoZXJlJ3Mgbm90aGluZyBpbiB0aGUgd3JpdGUgYnVmZmVyLCB0aGVuIHRoYXQgbWVhbnNcbiAgLy8gdGhhdCBub3RoaW5nIG1vcmUgd2lsbCBldmVyIGJlIHByb3ZpZGVkXG4gIGlmIChzdHJlYW0uX3dyaXRhYmxlU3RhdGUubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ0NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiB3cy5sZW5ndGggIT0gMCcpO1xuXG4gIGlmIChzdHJlYW0uX3RyYW5zZm9ybVN0YXRlLnRyYW5zZm9ybWluZykgdGhyb3cgbmV3IEVycm9yKCdDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gc3RpbGwgdHJhbnNmb3JtaW5nJyk7XG5cbiAgcmV0dXJuIHN0cmVhbS5wdXNoKG51bGwpO1xufSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBBIGJpdCBzaW1wbGVyIHRoYW4gcmVhZGFibGUgc3RyZWFtcy5cbi8vIEltcGxlbWVudCBhbiBhc3luYyAuX3dyaXRlKGNodW5rLCBlbmNvZGluZywgY2IpLCBhbmQgaXQnbGwgaGFuZGxlIGFsbFxuLy8gdGhlIGRyYWluIGV2ZW50IGVtaXNzaW9uIGFuZCBidWZmZXJpbmcuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBXcml0YWJsZTtcblxuLyogPHJlcGxhY2VtZW50PiAqL1xuZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aGlzLmNodW5rID0gY2h1bms7XG4gIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgdGhpcy5jYWxsYmFjayA9IGNiO1xuICB0aGlzLm5leHQgPSBudWxsO1xufVxuXG4vLyBJdCBzZWVtcyBhIGxpbmtlZCBsaXN0IGJ1dCBpdCBpcyBub3Rcbi8vIHRoZXJlIHdpbGwgYmUgb25seSAyIG9mIHRoZXNlIGZvciBlYWNoIHN0cmVhbVxuZnVuY3Rpb24gQ29ya2VkUmVxdWVzdChzdGF0ZSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHRoaXMubmV4dCA9IG51bGw7XG4gIHRoaXMuZW50cnkgPSBudWxsO1xuICB0aGlzLmZpbmlzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICBvbkNvcmtlZEZpbmlzaChfdGhpcywgc3RhdGUpO1xuICB9O1xufVxuLyogPC9yZXBsYWNlbWVudD4gKi9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBhc3luY1dyaXRlID0gIXByb2Nlc3MuYnJvd3NlciAmJiBbJ3YwLjEwJywgJ3YwLjkuJ10uaW5kZXhPZihwcm9jZXNzLnZlcnNpb24uc2xpY2UoMCwgNSkpID4gLTEgPyBzZXRJbW1lZGlhdGUgOiBwbmEubmV4dFRpY2s7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBEdXBsZXg7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpbnRlcm5hbFV0aWwgPSB7XG4gIGRlcHJlY2F0ZTogcmVxdWlyZSgndXRpbC1kZXByZWNhdGUnKVxufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0nKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXI7XG52YXIgT3VyVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5IHx8IGZ1bmN0aW9uICgpIHt9O1xuZnVuY3Rpb24gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuaykge1xuICByZXR1cm4gQnVmZmVyLmZyb20oY2h1bmspO1xufVxuZnVuY3Rpb24gX2lzVWludDhBcnJheShvYmopIHtcbiAgcmV0dXJuIEJ1ZmZlci5pc0J1ZmZlcihvYmopIHx8IG9iaiBpbnN0YW5jZW9mIE91clVpbnQ4QXJyYXk7XG59XG5cbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgZGVzdHJveUltcGwgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvZGVzdHJveScpO1xuXG51dGlsLmluaGVyaXRzKFdyaXRhYmxlLCBTdHJlYW0pO1xuXG5mdW5jdGlvbiBub3AoKSB7fVxuXG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIER1cGxleCBzdHJlYW1zIGFyZSBib3RoIHJlYWRhYmxlIGFuZCB3cml0YWJsZSwgYnV0IHNoYXJlXG4gIC8vIHRoZSBzYW1lIG9wdGlvbnMgb2JqZWN0LlxuICAvLyBIb3dldmVyLCBzb21lIGNhc2VzIHJlcXVpcmUgc2V0dGluZyBvcHRpb25zIHRvIGRpZmZlcmVudFxuICAvLyB2YWx1ZXMgZm9yIHRoZSByZWFkYWJsZSBhbmQgdGhlIHdyaXRhYmxlIHNpZGVzIG9mIHRoZSBkdXBsZXggc3RyZWFtLlxuICAvLyBUaGVzZSBvcHRpb25zIGNhbiBiZSBwcm92aWRlZCBzZXBhcmF0ZWx5IGFzIHJlYWRhYmxlWFhYIGFuZCB3cml0YWJsZVhYWC5cbiAgdmFyIGlzRHVwbGV4ID0gc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChpc0R1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIHdyaXRlKCkgc3RhcnRzIHJldHVybmluZyBmYWxzZVxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIHRoYXQgd2UgYWx3YXlzIHJldHVybiBmYWxzZSBpZlxuICAvLyB0aGUgZW50aXJlIGJ1ZmZlciBpcyBub3QgZmx1c2hlZCBpbW1lZGlhdGVseSBvbiB3cml0ZSgpXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciB3cml0YWJsZUh3bSA9IG9wdGlvbnMud3JpdGFibGVIaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuXG4gIGlmIChod20gfHwgaHdtID09PSAwKSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod207ZWxzZSBpZiAoaXNEdXBsZXggJiYgKHdyaXRhYmxlSHdtIHx8IHdyaXRhYmxlSHdtID09PSAwKSkgdGhpcy5oaWdoV2F0ZXJNYXJrID0gd3JpdGFibGVId207ZWxzZSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gTWF0aC5mbG9vcih0aGlzLmhpZ2hXYXRlck1hcmspO1xuXG4gIC8vIGlmIF9maW5hbCBoYXMgYmVlbiBjYWxsZWRcbiAgdGhpcy5maW5hbENhbGxlZCA9IGZhbHNlO1xuXG4gIC8vIGRyYWluIGV2ZW50IGZsYWcuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIGhhcyBpdCBiZWVuIGRlc3Ryb3llZFxuICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyB3aGVuIHRydWUgYWxsIHdyaXRlcyB3aWxsIGJlIGJ1ZmZlcmVkIHVudGlsIC51bmNvcmsoKSBjYWxsXG4gIHRoaXMuY29ya2VkID0gMDtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uIChlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuXG4gIC8vIGNvdW50IGJ1ZmZlcmVkIHJlcXVlc3RzXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuXG4gIC8vIGFsbG9jYXRlIHRoZSBmaXJzdCBDb3JrZWRSZXF1ZXN0LCB0aGVyZSBpcyBhbHdheXNcbiAgLy8gb25lIGFsbG9jYXRlZCBhbmQgZnJlZSB0byB1c2UsIGFuZCB3ZSBtYWludGFpbiBhdCBtb3N0IHR3b1xuICB0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xufVxuXG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiBnZXRCdWZmZXIoKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXJlZFJlcXVlc3Q7XG4gIHZhciBvdXQgPSBbXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0YXRlLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgICAgIGdldDogaW50ZXJuYWxVdGlsLmRlcHJlY2F0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICAgICAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgKyAnaW5zdGVhZC4nLCAnREVQMDAwMycpXG4gICAgfSk7XG4gIH0gY2F0Y2ggKF8pIHt9XG59KSgpO1xuXG4vLyBUZXN0IF93cml0YWJsZVN0YXRlIGZvciBpbmhlcml0YW5jZSB0byBhY2NvdW50IGZvciBEdXBsZXggc3RyZWFtcyxcbi8vIHdob3NlIHByb3RvdHlwZSBjaGFpbiBvbmx5IHBvaW50cyB0byBSZWFkYWJsZS5cbnZhciByZWFsSGFzSW5zdGFuY2U7XG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuaGFzSW5zdGFuY2UgJiYgdHlwZW9mIEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdID09PSAnZnVuY3Rpb24nKSB7XG4gIHJlYWxIYXNJbnN0YW5jZSA9IEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUsIFN5bWJvbC5oYXNJbnN0YW5jZSwge1xuICAgIHZhbHVlOiBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgICBpZiAocmVhbEhhc0luc3RhbmNlLmNhbGwodGhpcywgb2JqZWN0KSkgcmV0dXJuIHRydWU7XG4gICAgICBpZiAodGhpcyAhPT0gV3JpdGFibGUpIHJldHVybiBmYWxzZTtcblxuICAgICAgcmV0dXJuIG9iamVjdCAmJiBvYmplY3QuX3dyaXRhYmxlU3RhdGUgaW5zdGFuY2VvZiBXcml0YWJsZVN0YXRlO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICByZWFsSGFzSW5zdGFuY2UgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIHRoaXM7XG4gIH07XG59XG5cbmZ1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICAvLyBXcml0YWJsZSBjdG9yIGlzIGFwcGxpZWQgdG8gRHVwbGV4ZXMsIHRvby5cbiAgLy8gYHJlYWxIYXNJbnN0YW5jZWAgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdXNpbmcgcGxhaW4gYGluc3RhbmNlb2ZgXG4gIC8vIHdvdWxkIHJldHVybiBmYWxzZSwgYXMgbm8gYF93cml0YWJsZVN0YXRlYCBwcm9wZXJ0eSBpcyBhdHRhY2hlZC5cblxuICAvLyBUcnlpbmcgdG8gdXNlIHRoZSBjdXN0b20gYGluc3RhbmNlb2ZgIGZvciBXcml0YWJsZSBoZXJlIHdpbGwgYWxzbyBicmVhayB0aGVcbiAgLy8gTm9kZS5qcyBMYXp5VHJhbnNmb3JtIGltcGxlbWVudGF0aW9uLCB3aGljaCBoYXMgYSBub24tdHJpdmlhbCBnZXR0ZXIgZm9yXG4gIC8vIGBfd3JpdGFibGVTdGF0ZWAgdGhhdCB3b3VsZCBsZWFkIHRvIGluZmluaXRlIHJlY3Vyc2lvbi5cbiAgaWYgKCFyZWFsSGFzSW5zdGFuY2UuY2FsbChXcml0YWJsZSwgdGhpcykgJiYgISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSkge1xuICAgIHJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7XG4gIH1cblxuICB0aGlzLl93cml0YWJsZVN0YXRlID0gbmV3IFdyaXRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5LlxuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53cml0ZSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGUgPSBvcHRpb25zLndyaXRlO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRldiA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGV2ID0gb3B0aW9ucy53cml0ZXY7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZGVzdHJveSA9IG9wdGlvbnMuZGVzdHJveTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5maW5hbCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmluYWwgPSBvcHRpb25zLmZpbmFsO1xuICB9XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE90aGVyd2lzZSBwZW9wbGUgY2FuIHBpcGUgV3JpdGFibGUgc3RyZWFtcywgd2hpY2ggaXMganVzdCB3cm9uZy5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdDYW5ub3QgcGlwZSwgbm90IHJlYWRhYmxlJykpO1xufTtcblxuZnVuY3Rpb24gd3JpdGVBZnRlckVuZChzdHJlYW0sIGNiKSB7XG4gIHZhciBlciA9IG5ldyBFcnJvcignd3JpdGUgYWZ0ZXIgZW5kJyk7XG4gIC8vIFRPRE86IGRlZmVyIGVycm9yIGV2ZW50cyBjb25zaXN0ZW50bHkgZXZlcnl3aGVyZSwgbm90IGp1c3QgdGhlIGNiXG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgcG5hLm5leHRUaWNrKGNiLCBlcik7XG59XG5cbi8vIENoZWNrcyB0aGF0IGEgdXNlci1zdXBwbGllZCBjaHVuayBpcyB2YWxpZCwgZXNwZWNpYWxseSBmb3IgdGhlIHBhcnRpY3VsYXJcbi8vIG1vZGUgdGhlIHN0cmVhbSBpcyBpbi4gQ3VycmVudGx5IHRoaXMgbWVhbnMgdGhhdCBgbnVsbGAgaXMgbmV2ZXIgYWNjZXB0ZWRcbi8vIGFuZCB1bmRlZmluZWQvbm9uLXN0cmluZyB2YWx1ZXMgYXJlIG9ubHkgYWxsb3dlZCBpbiBvYmplY3QgbW9kZS5cbmZ1bmN0aW9uIHZhbGlkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGNiKSB7XG4gIHZhciB2YWxpZCA9IHRydWU7XG4gIHZhciBlciA9IGZhbHNlO1xuXG4gIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignTWF5IG5vdCB3cml0ZSBudWxsIHZhbHVlcyB0byBzdHJlYW0nKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmIGNodW5rICE9PSB1bmRlZmluZWQgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgfVxuICBpZiAoZXIpIHtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgcG5hLm5leHRUaWNrKGNiLCBlcik7XG4gICAgdmFsaWQgPSBmYWxzZTtcbiAgfVxuICByZXR1cm4gdmFsaWQ7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG4gIHZhciByZXQgPSBmYWxzZTtcbiAgdmFyIGlzQnVmID0gIXN0YXRlLm9iamVjdE1vZGUgJiYgX2lzVWludDhBcnJheShjaHVuayk7XG5cbiAgaWYgKGlzQnVmICYmICFCdWZmZXIuaXNCdWZmZXIoY2h1bmspKSB7XG4gICAgY2h1bmsgPSBfdWludDhBcnJheVRvQnVmZmVyKGNodW5rKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChpc0J1ZikgZW5jb2RpbmcgPSAnYnVmZmVyJztlbHNlIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuXG4gIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpIGNiID0gbm9wO1xuXG4gIGlmIChzdGF0ZS5lbmRlZCkgd3JpdGVBZnRlckVuZCh0aGlzLCBjYik7ZWxzZSBpZiAoaXNCdWYgfHwgdmFsaWRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGNiKSkge1xuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGlzQnVmLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBzdGF0ZS5jb3JrZWQrKztcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS51bmNvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZC0tO1xuXG4gICAgaWYgKCFzdGF0ZS53cml0aW5nICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCkgY2xlYXJCdWZmZXIodGhpcywgc3RhdGUpO1xuICB9XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuc2V0RGVmYXVsdEVuY29kaW5nID0gZnVuY3Rpb24gc2V0RGVmYXVsdEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIC8vIG5vZGU6OlBhcnNlRW5jb2RpbmcoKSByZXF1aXJlcyBsb3dlciBjYXNlLlxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykgZW5jb2RpbmcgPSBlbmNvZGluZy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoIShbJ2hleCcsICd1dGY4JywgJ3V0Zi04JywgJ2FzY2lpJywgJ2JpbmFyeScsICdiYXNlNjQnLCAndWNzMicsICd1Y3MtMicsICd1dGYxNmxlJywgJ3V0Zi0xNmxlJywgJ3JhdyddLmluZGV4T2YoKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKCkpID4gLTEpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB0aGlzLl93cml0YWJsZVN0YXRlLmRlZmF1bHRFbmNvZGluZyA9IGVuY29kaW5nO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpIHtcbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmIHN0YXRlLmRlY29kZVN0cmluZ3MgIT09IGZhbHNlICYmIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBjaHVuayA9IEJ1ZmZlci5mcm9tKGNodW5rLCBlbmNvZGluZyk7XG4gIH1cbiAgcmV0dXJuIGNodW5rO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnd3JpdGFibGVIaWdoV2F0ZXJNYXJrJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICB9XG59KTtcblxuLy8gaWYgd2UncmUgYWxyZWFkeSB3cml0aW5nIHNvbWV0aGluZywgdGhlbiBqdXN0IHB1dCB0aGlzXG4vLyBpbiB0aGUgcXVldWUsIGFuZCB3YWl0IG91ciB0dXJuLiAgT3RoZXJ3aXNlLCBjYWxsIF93cml0ZVxuLy8gSWYgd2UgcmV0dXJuIGZhbHNlLCB0aGVuIHdlIG5lZWQgYSBkcmFpbiBldmVudCwgc28gc2V0IHRoYXQgZmxhZy5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgaXNCdWYsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgaWYgKCFpc0J1Zikge1xuICAgIHZhciBuZXdDaHVuayA9IGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpO1xuICAgIGlmIChjaHVuayAhPT0gbmV3Q2h1bmspIHtcbiAgICAgIGlzQnVmID0gdHJ1ZTtcbiAgICAgIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gICAgICBjaHVuayA9IG5ld0NodW5rO1xuICAgIH1cbiAgfVxuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcblxuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgLy8gd2UgbXVzdCBlbnN1cmUgdGhhdCBwcmV2aW91cyBuZWVkRHJhaW4gd2lsbCBub3QgYmUgcmVzZXQgdG8gZmFsc2UuXG4gIGlmICghcmV0KSBzdGF0ZS5uZWVkRHJhaW4gPSB0cnVlO1xuXG4gIGlmIChzdGF0ZS53cml0aW5nIHx8IHN0YXRlLmNvcmtlZCkge1xuICAgIHZhciBsYXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0ge1xuICAgICAgY2h1bms6IGNodW5rLFxuICAgICAgZW5jb2Rpbmc6IGVuY29kaW5nLFxuICAgICAgaXNCdWY6IGlzQnVmLFxuICAgICAgY2FsbGJhY2s6IGNiLFxuICAgICAgbmV4dDogbnVsbFxuICAgIH07XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIGxhc3QubmV4dCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfVxuICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ICs9IDE7XG4gIH0gZWxzZSB7XG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgd3JpdGV2LCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgc3RhdGUud3JpdGVsZW4gPSBsZW47XG4gIHN0YXRlLndyaXRlY2IgPSBjYjtcbiAgc3RhdGUud3JpdGluZyA9IHRydWU7XG4gIHN0YXRlLnN5bmMgPSB0cnVlO1xuICBpZiAod3JpdGV2KSBzdHJlYW0uX3dyaXRldihjaHVuaywgc3RhdGUub253cml0ZSk7ZWxzZSBzdHJlYW0uX3dyaXRlKGNodW5rLCBlbmNvZGluZywgc3RhdGUub253cml0ZSk7XG4gIHN0YXRlLnN5bmMgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYikge1xuICAtLXN0YXRlLnBlbmRpbmdjYjtcblxuICBpZiAoc3luYykge1xuICAgIC8vIGRlZmVyIHRoZSBjYWxsYmFjayBpZiB3ZSBhcmUgYmVpbmcgY2FsbGVkIHN5bmNocm9ub3VzbHlcbiAgICAvLyB0byBhdm9pZCBwaWxpbmcgdXAgdGhpbmdzIG9uIHRoZSBzdGFja1xuICAgIHBuYS5uZXh0VGljayhjYiwgZXIpO1xuICAgIC8vIHRoaXMgY2FuIGVtaXQgZmluaXNoLCBhbmQgaXQgd2lsbCBhbHdheXMgaGFwcGVuXG4gICAgLy8gYWZ0ZXIgZXJyb3JcbiAgICBwbmEubmV4dFRpY2soZmluaXNoTWF5YmUsIHN0cmVhbSwgc3RhdGUpO1xuICAgIHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB0aGUgY2FsbGVyIGV4cGVjdCB0aGlzIHRvIGhhcHBlbiBiZWZvcmUgaWZcbiAgICAvLyBpdCBpcyBhc3luY1xuICAgIGNiKGVyKTtcbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgLy8gdGhpcyBjYW4gZW1pdCBmaW5pc2gsIGJ1dCBmaW5pc2ggbXVzdFxuICAgIC8vIGFsd2F5cyBmb2xsb3cgZXJyb3JcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpIHtcbiAgc3RhdGUud3JpdGluZyA9IGZhbHNlO1xuICBzdGF0ZS53cml0ZWNiID0gbnVsbDtcbiAgc3RhdGUubGVuZ3RoIC09IHN0YXRlLndyaXRlbGVuO1xuICBzdGF0ZS53cml0ZWxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcblxuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuXG4gIGlmIChlcikgb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYik7ZWxzZSB7XG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgYWN0dWFsbHkgcmVhZHkgdG8gZmluaXNoLCBidXQgZG9uJ3QgZW1pdCB5ZXRcbiAgICB2YXIgZmluaXNoZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcblxuICAgIGlmICghZmluaXNoZWQgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIHtcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cblxuICAgIGlmIChzeW5jKSB7XG4gICAgICAvKjxyZXBsYWNlbWVudD4qL1xuICAgICAgYXN5bmNXcml0ZShhZnRlcldyaXRlLCBzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgICAgLyo8L3JlcGxhY2VtZW50PiovXG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZCkgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgY2IoKTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbi8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5uZWVkRHJhaW4pIHtcbiAgICBzdGF0ZS5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZHJhaW4nKTtcbiAgfVxufVxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0O1xuXG4gIGlmIChzdHJlYW0uX3dyaXRldiAmJiBlbnRyeSAmJiBlbnRyeS5uZXh0KSB7XG4gICAgLy8gRmFzdCBjYXNlLCB3cml0ZSBldmVyeXRoaW5nIHVzaW5nIF93cml0ZXYoKVxuICAgIHZhciBsID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ7XG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheShsKTtcbiAgICB2YXIgaG9sZGVyID0gc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO1xuICAgIGhvbGRlci5lbnRyeSA9IGVudHJ5O1xuXG4gICAgdmFyIGNvdW50ID0gMDtcbiAgICB2YXIgYWxsQnVmZmVycyA9IHRydWU7XG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICBidWZmZXJbY291bnRdID0gZW50cnk7XG4gICAgICBpZiAoIWVudHJ5LmlzQnVmKSBhbGxCdWZmZXJzID0gZmFsc2U7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICBjb3VudCArPSAxO1xuICAgIH1cbiAgICBidWZmZXIuYWxsQnVmZmVycyA9IGFsbEJ1ZmZlcnM7XG5cbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHRydWUsIHN0YXRlLmxlbmd0aCwgYnVmZmVyLCAnJywgaG9sZGVyLmZpbmlzaCk7XG5cbiAgICAvLyBkb1dyaXRlIGlzIGFsbW9zdCBhbHdheXMgYXN5bmMsIGRlZmVyIHRoZXNlIHRvIHNhdmUgYSBiaXQgb2YgdGltZVxuICAgIC8vIGFzIHRoZSBob3QgcGF0aCBlbmRzIHdpdGggZG9Xcml0ZVxuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICAgIGlmIChob2xkZXIubmV4dCkge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gaG9sZGVyLm5leHQ7XG4gICAgICBob2xkZXIubmV4dCA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHN0YXRlKTtcbiAgICB9XG4gICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIFNsb3cgY2FzZSwgd3JpdGUgY2h1bmtzIG9uZS1ieS1vbmVcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjaHVuayA9IGVudHJ5LmNodW5rO1xuICAgICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICAgIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICAgICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50LS07XG4gICAgICAvLyBpZiB3ZSBkaWRuJ3QgY2FsbCB0aGUgb253cml0ZSBpbW1lZGlhdGVseSwgdGhlblxuICAgICAgLy8gaXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHdhaXQgdW50aWwgaXQgZG9lcy5cbiAgICAgIC8vIGFsc28sIHRoYXQgbWVhbnMgdGhhdCB0aGUgY2h1bmsgYW5kIGNiIGFyZSBjdXJyZW50bHlcbiAgICAgIC8vIGJlaW5nIHByb2Nlc3NlZCwgc28gbW92ZSB0aGUgYnVmZmVyIGNvdW50ZXIgcGFzdCB0aGVtLlxuICAgICAgaWYgKHN0YXRlLndyaXRpbmcpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5ID09PSBudWxsKSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IGVudHJ5O1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRXJyb3IoJ193cml0ZSgpIGlzIG5vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGV2ID0gbnVsbDtcblxuV3JpdGFibGUucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBjaHVuayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gY2h1bms7XG4gICAgY2h1bmsgPSBudWxsO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkKSB0aGlzLndyaXRlKGNodW5rLCBlbmNvZGluZyk7XG5cbiAgLy8gLmVuZCgpIGZ1bGx5IHVuY29ya3NcbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZCA9IDE7XG4gICAgdGhpcy51bmNvcmsoKTtcbiAgfVxuXG4gIC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cbiAgaWYgKCFzdGF0ZS5lbmRpbmcgJiYgIXN0YXRlLmZpbmlzaGVkKSBlbmRXcml0YWJsZSh0aGlzLCBzdGF0ZSwgY2IpO1xufTtcblxuZnVuY3Rpb24gbmVlZEZpbmlzaChzdGF0ZSkge1xuICByZXR1cm4gc3RhdGUuZW5kaW5nICYmIHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPT09IG51bGwgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS53cml0aW5nO1xufVxuZnVuY3Rpb24gY2FsbEZpbmFsKHN0cmVhbSwgc3RhdGUpIHtcbiAgc3RyZWFtLl9maW5hbChmdW5jdGlvbiAoZXJyKSB7XG4gICAgc3RhdGUucGVuZGluZ2NiLS07XG4gICAgaWYgKGVycikge1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICB9XG4gICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgfSk7XG59XG5mdW5jdGlvbiBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnByZWZpbmlzaGVkICYmICFzdGF0ZS5maW5hbENhbGxlZCkge1xuICAgIGlmICh0eXBlb2Ygc3RyZWFtLl9maW5hbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgICBzdGF0ZS5maW5hbENhbGxlZCA9IHRydWU7XG4gICAgICBwbmEubmV4dFRpY2soY2FsbEZpbmFsLCBzdHJlYW0sIHN0YXRlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLmVtaXQoJ3ByZWZpbmlzaCcpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBuZWVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG4gIGlmIChuZWVkKSB7XG4gICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICAgIGlmIChzdGF0ZS5wZW5kaW5nY2IgPT09IDApIHtcbiAgICAgIHN0YXRlLmZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5lbWl0KCdmaW5pc2gnKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5lZWQ7XG59XG5cbmZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHN0YXRlLmVuZGluZyA9IHRydWU7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAoY2IpIHtcbiAgICBpZiAoc3RhdGUuZmluaXNoZWQpIHBuYS5uZXh0VGljayhjYik7ZWxzZSBzdHJlYW0ub25jZSgnZmluaXNoJywgY2IpO1xuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgc3RyZWFtLndyaXRhYmxlID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG9uQ29ya2VkRmluaXNoKGNvcmtSZXEsIHN0YXRlLCBlcnIpIHtcbiAgdmFyIGVudHJ5ID0gY29ya1JlcS5lbnRyeTtcbiAgY29ya1JlcS5lbnRyeSA9IG51bGw7XG4gIHdoaWxlIChlbnRyeSkge1xuICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgIHN0YXRlLnBlbmRpbmdjYi0tO1xuICAgIGNiKGVycik7XG4gICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICB9XG4gIGlmIChzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUpIHtcbiAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IGNvcmtSZXE7XG4gIH0gZWxzZSB7XG4gICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gY29ya1JlcTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnZGVzdHJveWVkJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAvLyB3ZSBpZ25vcmUgdGhlIHZhbHVlIGlmIHRoZSBzdHJlYW1cbiAgICAvLyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgaWYgKCF0aGlzLl93cml0YWJsZVN0YXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdGhlIHVzZXIgaXMgZXhwbGljaXRseVxuICAgIC8vIG1hbmFnaW5nIGRlc3Ryb3llZFxuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdmFsdWU7XG4gIH1cbn0pO1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLmRlc3Ryb3k7XG5Xcml0YWJsZS5wcm90b3R5cGUuX3VuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLnVuZGVzdHJveTtcbldyaXRhYmxlLnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIChlcnIsIGNiKSB7XG4gIHRoaXMuZW5kKCk7XG4gIGNiKGVycik7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlcjtcbnZhciB1dGlsID0gcmVxdWlyZSgzNCk7XG5cbmZ1bmN0aW9uIGNvcHlCdWZmZXIoc3JjLCB0YXJnZXQsIG9mZnNldCkge1xuICBzcmMuY29weSh0YXJnZXQsIG9mZnNldCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBCdWZmZXJMaXN0KCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBCdWZmZXJMaXN0KTtcblxuICAgIHRoaXMuaGVhZCA9IG51bGw7XG4gICAgdGhpcy50YWlsID0gbnVsbDtcbiAgICB0aGlzLmxlbmd0aCA9IDA7XG4gIH1cblxuICBCdWZmZXJMaXN0LnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gcHVzaCh2KSB7XG4gICAgdmFyIGVudHJ5ID0geyBkYXRhOiB2LCBuZXh0OiBudWxsIH07XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gMCkgdGhpcy50YWlsLm5leHQgPSBlbnRyeTtlbHNlIHRoaXMuaGVhZCA9IGVudHJ5O1xuICAgIHRoaXMudGFpbCA9IGVudHJ5O1xuICAgICsrdGhpcy5sZW5ndGg7XG4gIH07XG5cbiAgQnVmZmVyTGlzdC5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uIHVuc2hpZnQodikge1xuICAgIHZhciBlbnRyeSA9IHsgZGF0YTogdiwgbmV4dDogdGhpcy5oZWFkIH07XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSB0aGlzLnRhaWwgPSBlbnRyeTtcbiAgICB0aGlzLmhlYWQgPSBlbnRyeTtcbiAgICArK3RoaXMubGVuZ3RoO1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24gc2hpZnQoKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgdmFyIHJldCA9IHRoaXMuaGVhZC5kYXRhO1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtlbHNlIHRoaXMuaGVhZCA9IHRoaXMuaGVhZC5uZXh0O1xuICAgIC0tdGhpcy5sZW5ndGg7XG4gICAgcmV0dXJuIHJldDtcbiAgfTtcblxuICBCdWZmZXJMaXN0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiBqb2luKHMpIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgICB2YXIgcCA9IHRoaXMuaGVhZDtcbiAgICB2YXIgcmV0ID0gJycgKyBwLmRhdGE7XG4gICAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICAgIHJldCArPSBzICsgcC5kYXRhO1xuICAgIH1yZXR1cm4gcmV0O1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdChuKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gQnVmZmVyLmFsbG9jKDApO1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHRoaXMuaGVhZC5kYXRhO1xuICAgIHZhciByZXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobiA+Pj4gMCk7XG4gICAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChwKSB7XG4gICAgICBjb3B5QnVmZmVyKHAuZGF0YSwgcmV0LCBpKTtcbiAgICAgIGkgKz0gcC5kYXRhLmxlbmd0aDtcbiAgICAgIHAgPSBwLm5leHQ7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH07XG5cbiAgcmV0dXJuIEJ1ZmZlckxpc3Q7XG59KCk7XG5cbmlmICh1dGlsICYmIHV0aWwuaW5zcGVjdCAmJiB1dGlsLmluc3BlY3QuY3VzdG9tKSB7XG4gIG1vZHVsZS5leHBvcnRzLnByb3RvdHlwZVt1dGlsLmluc3BlY3QuY3VzdG9tXSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgb2JqID0gdXRpbC5pbnNwZWN0KHsgbGVuZ3RoOiB0aGlzLmxlbmd0aCB9KTtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnICsgb2JqO1xuICB9O1xufSIsIid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoNzYpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8vIHVuZG9jdW1lbnRlZCBjYigpIEFQSSwgbmVlZGVkIGZvciBjb3JlLCBub3QgZm9yIHB1YmxpYyBBUElcbmZ1bmN0aW9uIGRlc3Ryb3koZXJyLCBjYikge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHZhciByZWFkYWJsZURlc3Ryb3llZCA9IHRoaXMuX3JlYWRhYmxlU3RhdGUgJiYgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIHZhciB3cml0YWJsZURlc3Ryb3llZCA9IHRoaXMuX3dyaXRhYmxlU3RhdGUgJiYgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG5cbiAgaWYgKHJlYWRhYmxlRGVzdHJveWVkIHx8IHdyaXRhYmxlRGVzdHJveWVkKSB7XG4gICAgaWYgKGNiKSB7XG4gICAgICBjYihlcnIpO1xuICAgIH0gZWxzZSBpZiAoZXJyICYmICghdGhpcy5fd3JpdGFibGVTdGF0ZSB8fCAhdGhpcy5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQpKSB7XG4gICAgICBwbmEubmV4dFRpY2soZW1pdEVycm9yTlQsIHRoaXMsIGVycik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gd2Ugc2V0IGRlc3Ryb3llZCB0byB0cnVlIGJlZm9yZSBmaXJpbmcgZXJyb3IgY2FsbGJhY2tzIGluIG9yZGVyXG4gIC8vIHRvIG1ha2UgaXQgcmUtZW50cmFuY2Ugc2FmZSBpbiBjYXNlIGRlc3Ryb3koKSBpcyBjYWxsZWQgd2l0aGluIGNhbGxiYWNrc1xuXG4gIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlKSB7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB0cnVlO1xuICB9XG5cbiAgLy8gaWYgdGhpcyBpcyBhIGR1cGxleCBzdHJlYW0gbWFyayB0aGUgd3JpdGFibGUgcGFydCBhcyBkZXN0cm95ZWQgYXMgd2VsbFxuICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdHJ1ZTtcbiAgfVxuXG4gIHRoaXMuX2Rlc3Ryb3koZXJyIHx8IG51bGwsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoIWNiICYmIGVycikge1xuICAgICAgcG5hLm5leHRUaWNrKGVtaXRFcnJvck5ULCBfdGhpcywgZXJyKTtcbiAgICAgIGlmIChfdGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgICAgICBfdGhpcy5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY2IpIHtcbiAgICAgIGNiKGVycik7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gdW5kZXN0cm95KCkge1xuICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKHRoaXMuX3dyaXRhYmxlU3RhdGUpIHtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZmluaXNoZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRFcnJvck5UKHNlbGYsIGVycikge1xuICBzZWxmLmVtaXQoJ2Vycm9yJywgZXJyKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGRlc3Ryb3k6IGRlc3Ryb3ksXG4gIHVuZGVzdHJveTogdW5kZXN0cm95XG59OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSg2MikuRXZlbnRFbWl0dGVyO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKDg5KS5QYXNzVGhyb3VnaFxuIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSg4MSk7XG5leHBvcnRzLlN0cmVhbSA9IGV4cG9ydHM7XG5leHBvcnRzLlJlYWRhYmxlID0gZXhwb3J0cztcbmV4cG9ydHMuV3JpdGFibGUgPSByZXF1aXJlKDgzKTtcbmV4cG9ydHMuRHVwbGV4ID0gcmVxdWlyZSg3OSk7XG5leHBvcnRzLlRyYW5zZm9ybSA9IHJlcXVpcmUoODIpO1xuZXhwb3J0cy5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoODApO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKDg5KS5UcmFuc2Zvcm1cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSg4Myk7XG4iLCIndXNlIHN0cmljdCdcbnZhciBCdWZmZXIgPSByZXF1aXJlKDM1KS5CdWZmZXJcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoNjUpXG52YXIgSGFzaEJhc2UgPSByZXF1aXJlKDYzKVxuXG52YXIgQVJSQVkxNiA9IG5ldyBBcnJheSgxNilcblxudmFyIHpsID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dXG5cbnZhciB6ciA9IFtcbiAgNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMixcbiAgNiwgMTEsIDMsIDcsIDAsIDEzLCA1LCAxMCwgMTQsIDE1LCA4LCAxMiwgNCwgOSwgMSwgMixcbiAgMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxMyxcbiAgOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNCxcbiAgMTIsIDE1LCAxMCwgNCwgMSwgNSwgOCwgNywgNiwgMiwgMTMsIDE0LCAwLCAzLCA5LCAxMVxuXVxuXG52YXIgc2wgPSBbXG4gIDExLCAxNCwgMTUsIDEyLCA1LCA4LCA3LCA5LCAxMSwgMTMsIDE0LCAxNSwgNiwgNywgOSwgOCxcbiAgNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyLFxuICAxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDUsXG4gIDExLCAxMiwgMTQsIDE1LCAxNCwgMTUsIDksIDgsIDksIDE0LCA1LCA2LCA4LCA2LCA1LCAxMixcbiAgOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XG5dXG5cbnZhciBzciA9IFtcbiAgOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2LFxuICA5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTEsXG4gIDksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNSxcbiAgMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4LFxuICA4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFcbl1cblxudmFyIGhsID0gWzB4MDAwMDAwMDAsIDB4NWE4Mjc5OTksIDB4NmVkOWViYTEsIDB4OGYxYmJjZGMsIDB4YTk1M2ZkNGVdXG52YXIgaHIgPSBbMHg1MGEyOGJlNiwgMHg1YzRkZDEyNCwgMHg2ZDcwM2VmMywgMHg3YTZkNzZlOSwgMHgwMDAwMDAwMF1cblxuZnVuY3Rpb24gUklQRU1EMTYwICgpIHtcbiAgSGFzaEJhc2UuY2FsbCh0aGlzLCA2NClcblxuICAvLyBzdGF0ZVxuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxuICB0aGlzLl9lID0gMHhjM2QyZTFmMFxufVxuXG5pbmhlcml0cyhSSVBFTUQxNjAsIEhhc2hCYXNlKVxuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB3b3JkcyA9IEFSUkFZMTZcbiAgZm9yICh2YXIgaiA9IDA7IGogPCAxNjsgKytqKSB3b3Jkc1tqXSA9IHRoaXMuX2Jsb2NrLnJlYWRJbnQzMkxFKGogKiA0KVxuXG4gIHZhciBhbCA9IHRoaXMuX2EgfCAwXG4gIHZhciBibCA9IHRoaXMuX2IgfCAwXG4gIHZhciBjbCA9IHRoaXMuX2MgfCAwXG4gIHZhciBkbCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlbCA9IHRoaXMuX2UgfCAwXG5cbiAgdmFyIGFyID0gdGhpcy5fYSB8IDBcbiAgdmFyIGJyID0gdGhpcy5fYiB8IDBcbiAgdmFyIGNyID0gdGhpcy5fYyB8IDBcbiAgdmFyIGRyID0gdGhpcy5fZCB8IDBcbiAgdmFyIGVyID0gdGhpcy5fZSB8IDBcblxuICAvLyBjb21wdXRhdGlvblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDgwOyBpICs9IDEpIHtcbiAgICB2YXIgdGxcbiAgICB2YXIgdHJcbiAgICBpZiAoaSA8IDE2KSB7XG4gICAgICB0bCA9IGZuMShhbCwgYmwsIGNsLCBkbCwgZWwsIHdvcmRzW3psW2ldXSwgaGxbMF0sIHNsW2ldKVxuICAgICAgdHIgPSBmbjUoYXIsIGJyLCBjciwgZHIsIGVyLCB3b3Jkc1t6cltpXV0sIGhyWzBdLCBzcltpXSlcbiAgICB9IGVsc2UgaWYgKGkgPCAzMikge1xuICAgICAgdGwgPSBmbjIoYWwsIGJsLCBjbCwgZGwsIGVsLCB3b3Jkc1t6bFtpXV0sIGhsWzFdLCBzbFtpXSlcbiAgICAgIHRyID0gZm40KGFyLCBiciwgY3IsIGRyLCBlciwgd29yZHNbenJbaV1dLCBoclsxXSwgc3JbaV0pXG4gICAgfSBlbHNlIGlmIChpIDwgNDgpIHtcbiAgICAgIHRsID0gZm4zKGFsLCBibCwgY2wsIGRsLCBlbCwgd29yZHNbemxbaV1dLCBobFsyXSwgc2xbaV0pXG4gICAgICB0ciA9IGZuMyhhciwgYnIsIGNyLCBkciwgZXIsIHdvcmRzW3pyW2ldXSwgaHJbMl0sIHNyW2ldKVxuICAgIH0gZWxzZSBpZiAoaSA8IDY0KSB7XG4gICAgICB0bCA9IGZuNChhbCwgYmwsIGNsLCBkbCwgZWwsIHdvcmRzW3psW2ldXSwgaGxbM10sIHNsW2ldKVxuICAgICAgdHIgPSBmbjIoYXIsIGJyLCBjciwgZHIsIGVyLCB3b3Jkc1t6cltpXV0sIGhyWzNdLCBzcltpXSlcbiAgICB9IGVsc2UgeyAvLyBpZiAoaTw4MCkge1xuICAgICAgdGwgPSBmbjUoYWwsIGJsLCBjbCwgZGwsIGVsLCB3b3Jkc1t6bFtpXV0sIGhsWzRdLCBzbFtpXSlcbiAgICAgIHRyID0gZm4xKGFyLCBiciwgY3IsIGRyLCBlciwgd29yZHNbenJbaV1dLCBocls0XSwgc3JbaV0pXG4gICAgfVxuXG4gICAgYWwgPSBlbFxuICAgIGVsID0gZGxcbiAgICBkbCA9IHJvdGwoY2wsIDEwKVxuICAgIGNsID0gYmxcbiAgICBibCA9IHRsXG5cbiAgICBhciA9IGVyXG4gICAgZXIgPSBkclxuICAgIGRyID0gcm90bChjciwgMTApXG4gICAgY3IgPSBiclxuICAgIGJyID0gdHJcbiAgfVxuXG4gIC8vIHVwZGF0ZSBzdGF0ZVxuICB2YXIgdCA9ICh0aGlzLl9iICsgY2wgKyBkcikgfCAwXG4gIHRoaXMuX2IgPSAodGhpcy5fYyArIGRsICsgZXIpIHwgMFxuICB0aGlzLl9jID0gKHRoaXMuX2QgKyBlbCArIGFyKSB8IDBcbiAgdGhpcy5fZCA9ICh0aGlzLl9lICsgYWwgKyBicikgfCAwXG4gIHRoaXMuX2UgPSAodGhpcy5fYSArIGJsICsgY3IpIHwgMFxuICB0aGlzLl9hID0gdFxufVxuXG5SSVBFTUQxNjAucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIGNyZWF0ZSBwYWRkaW5nIGFuZCBoYW5kbGUgYmxvY2tzXG4gIHRoaXMuX2Jsb2NrW3RoaXMuX2Jsb2NrT2Zmc2V0KytdID0gMHg4MFxuICBpZiAodGhpcy5fYmxvY2tPZmZzZXQgPiA1Nikge1xuICAgIHRoaXMuX2Jsb2NrLmZpbGwoMCwgdGhpcy5fYmxvY2tPZmZzZXQsIDY0KVxuICAgIHRoaXMuX3VwZGF0ZSgpXG4gICAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIH1cblxuICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMF0sIDU2KVxuICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkxFKHRoaXMuX2xlbmd0aFsxXSwgNjApXG4gIHRoaXMuX3VwZGF0ZSgpXG5cbiAgLy8gcHJvZHVjZSByZXN1bHRcbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyA/IEJ1ZmZlci5hbGxvYygyMCkgOiBuZXcgQnVmZmVyKDIwKVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2EsIDApXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYiwgNClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9jLCA4KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2QsIDEyKVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2UsIDE2KVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIHJvdGwgKHgsIG4pIHtcbiAgcmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKVxufVxuXG5mdW5jdGlvbiBmbjEgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKGIgXiBjIF4gZCkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5mdW5jdGlvbiBmbjIgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiICYgYykgfCAoKH5iKSAmIGQpKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbmZ1bmN0aW9uIGZuMyAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgfCAofmMpKSBeIGQpICsgbSArIGspIHwgMCwgcykgKyBlKSB8IDBcbn1cblxuZnVuY3Rpb24gZm40IChhLCBiLCBjLCBkLCBlLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYiAmIGQpIHwgKGMgJiAofmQpKSkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5mdW5jdGlvbiBmbjUgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKGIgXiAoYyB8ICh+ZCkpKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUklQRU1EMTYwXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBub2RlL25vLWRlcHJlY2F0ZWQtYXBpICovXG52YXIgYnVmZmVyID0gcmVxdWlyZSgzNSlcbnZhciBCdWZmZXIgPSBidWZmZXIuQnVmZmVyXG5cbi8vIGFsdGVybmF0aXZlIHRvIHVzaW5nIE9iamVjdC5rZXlzIGZvciBvbGQgYnJvd3NlcnNcbmZ1bmN0aW9uIGNvcHlQcm9wcyAoc3JjLCBkc3QpIHtcbiAgZm9yICh2YXIga2V5IGluIHNyYykge1xuICAgIGRzdFtrZXldID0gc3JjW2tleV1cbiAgfVxufVxuaWYgKEJ1ZmZlci5mcm9tICYmIEJ1ZmZlci5hbGxvYyAmJiBCdWZmZXIuYWxsb2NVbnNhZmUgJiYgQnVmZmVyLmFsbG9jVW5zYWZlU2xvdykge1xuICBtb2R1bGUuZXhwb3J0cyA9IGJ1ZmZlclxufSBlbHNlIHtcbiAgLy8gQ29weSBwcm9wZXJ0aWVzIGZyb20gcmVxdWlyZSgnYnVmZmVyJylcbiAgY29weVByb3BzKGJ1ZmZlciwgZXhwb3J0cylcbiAgZXhwb3J0cy5CdWZmZXIgPSBTYWZlQnVmZmVyXG59XG5cbmZ1bmN0aW9uIFNhZmVCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIENvcHkgc3RhdGljIG1ldGhvZHMgZnJvbSBCdWZmZXJcbmNvcHlQcm9wcyhCdWZmZXIsIFNhZmVCdWZmZXIpXG5cblNhZmVCdWZmZXIuZnJvbSA9IGZ1bmN0aW9uIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuU2FmZUJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgdmFyIGJ1ZiA9IEJ1ZmZlcihzaXplKVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgIH0gZWxzZSB7XG4gICAgICBidWYuZmlsbChmaWxsKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBidWYuZmlsbCgwKVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKHNpemUpXG59XG5cblNhZmVCdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBidWZmZXIuU2xvd0J1ZmZlcihzaXplKVxufVxuIiwiIWZ1bmN0aW9uKGdsb2JhbHMpe1xuJ3VzZSBzdHJpY3QnXG5cbi8vKioqIFVNRCBCRUdJTlxuaWYgKHR5cGVvZiBkZWZpbmUgIT09ICd1bmRlZmluZWQnICYmIGRlZmluZS5hbWQpIHsgLy9yZXF1aXJlLmpzIC8gQU1EXG4gIGRlZmluZShbXSwgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNlY3VyZVJhbmRvbVxuICB9KVxufSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykgeyAvL0NvbW1vbkpTXG4gIG1vZHVsZS5leHBvcnRzID0gc2VjdXJlUmFuZG9tXG59IGVsc2UgeyAvL3NjcmlwdCAvIGJyb3dzZXJcbiAgZ2xvYmFscy5zZWN1cmVSYW5kb20gPSBzZWN1cmVSYW5kb21cbn1cbi8vKioqIFVNRCBFTkRcblxuLy9vcHRpb25zLnR5cGUgaXMgdGhlIG9ubHkgdmFsaWQgb3B0aW9uXG5mdW5jdGlvbiBzZWN1cmVSYW5kb20oY291bnQsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge3R5cGU6ICdBcnJheSd9XG4gIC8vd2UgY2hlY2sgZm9yIHByb2Nlc3MucGlkIHRvIHByZXZlbnQgYnJvd3NlcmlmeSBmcm9tIHRyaWNraW5nIHVzXG4gIGlmICh0eXBlb2YgcHJvY2VzcyAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgcHJvY2Vzcy5waWQgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gbm9kZVJhbmRvbShjb3VudCwgb3B0aW9ucylcbiAgfSBlbHNlIHtcbiAgICB2YXIgY3J5cHRvID0gd2luZG93LmNyeXB0byB8fCB3aW5kb3cubXNDcnlwdG9cbiAgICBpZiAoIWNyeXB0bykgdGhyb3cgbmV3IEVycm9yKFwiWW91ciBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgd2luZG93LmNyeXB0by5cIilcbiAgICByZXR1cm4gYnJvd3NlclJhbmRvbShjb3VudCwgb3B0aW9ucylcbiAgfVxufVxuXG5mdW5jdGlvbiBub2RlUmFuZG9tKGNvdW50LCBvcHRpb25zKSB7XG4gIHZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKVxuICB2YXIgYnVmID0gY3J5cHRvLnJhbmRvbUJ5dGVzKGNvdW50KVxuXG4gIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIFtdLnNsaWNlLmNhbGwoYnVmKVxuICAgIGNhc2UgJ0J1ZmZlcic6XG4gICAgICByZXR1cm4gYnVmXG4gICAgY2FzZSAnVWludDhBcnJheSc6XG4gICAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoY291bnQpXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsgYXJyW2ldID0gYnVmLnJlYWRVSW50OChpKSB9XG4gICAgICByZXR1cm4gYXJyXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihvcHRpb25zLnR5cGUgKyBcIiBpcyB1bnN1cHBvcnRlZC5cIilcbiAgfVxufVxuXG5mdW5jdGlvbiBicm93c2VyUmFuZG9tKGNvdW50LCBvcHRpb25zKSB7XG4gIHZhciBuYXRpdmVBcnIgPSBuZXcgVWludDhBcnJheShjb3VudClcbiAgdmFyIGNyeXB0byA9IHdpbmRvdy5jcnlwdG8gfHwgd2luZG93Lm1zQ3J5cHRvXG4gIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmF0aXZlQXJyKVxuXG4gIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIFtdLnNsaWNlLmNhbGwobmF0aXZlQXJyKVxuICAgIGNhc2UgJ0J1ZmZlcic6XG4gICAgICB0cnkgeyB2YXIgYiA9IG5ldyBCdWZmZXIoMSkgfSBjYXRjaChlKSB7IHRocm93IG5ldyBFcnJvcignQnVmZmVyIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBlbnZpcm9ubWVudC4gVXNlIE5vZGUuanMgb3IgQnJvd3NlcmlmeSBmb3IgYnJvd3NlciBzdXBwb3J0LicpfVxuICAgICAgcmV0dXJuIG5ldyBCdWZmZXIobmF0aXZlQXJyKVxuICAgIGNhc2UgJ1VpbnQ4QXJyYXknOlxuICAgICAgcmV0dXJuIG5hdGl2ZUFyclxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3Iob3B0aW9ucy50eXBlICsgXCIgaXMgdW5zdXBwb3J0ZWQuXCIpXG4gIH1cbn1cblxuc2VjdXJlUmFuZG9tLnJhbmRvbUFycmF5ID0gZnVuY3Rpb24oYnl0ZUNvdW50KSB7XG4gIHJldHVybiBzZWN1cmVSYW5kb20oYnl0ZUNvdW50LCB7dHlwZTogJ0FycmF5J30pXG59XG5cbnNlY3VyZVJhbmRvbS5yYW5kb21VaW50OEFycmF5ID0gZnVuY3Rpb24oYnl0ZUNvdW50KSB7XG4gIHJldHVybiBzZWN1cmVSYW5kb20oYnl0ZUNvdW50LCB7dHlwZTogJ1VpbnQ4QXJyYXknfSlcbn1cblxuc2VjdXJlUmFuZG9tLnJhbmRvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ5dGVDb3VudCkge1xuICByZXR1cm4gc2VjdXJlUmFuZG9tKGJ5dGVDb3VudCwge3R5cGU6ICdCdWZmZXInfSlcbn1cblxuXG59KHRoaXMpO1xuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlclxuXG4vLyBwcm90b3R5cGUgY2xhc3MgZm9yIGhhc2ggZnVuY3Rpb25zXG5mdW5jdGlvbiBIYXNoIChibG9ja1NpemUsIGZpbmFsU2l6ZSkge1xuICB0aGlzLl9ibG9jayA9IEJ1ZmZlci5hbGxvYyhibG9ja1NpemUpXG4gIHRoaXMuX2ZpbmFsU2l6ZSA9IGZpbmFsU2l6ZVxuICB0aGlzLl9ibG9ja1NpemUgPSBibG9ja1NpemVcbiAgdGhpcy5fbGVuID0gMFxufVxuXG5IYXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmMgPSBlbmMgfHwgJ3V0ZjgnXG4gICAgZGF0YSA9IEJ1ZmZlci5mcm9tKGRhdGEsIGVuYylcbiAgfVxuXG4gIHZhciBibG9jayA9IHRoaXMuX2Jsb2NrXG4gIHZhciBibG9ja1NpemUgPSB0aGlzLl9ibG9ja1NpemVcbiAgdmFyIGxlbmd0aCA9IGRhdGEubGVuZ3RoXG4gIHZhciBhY2N1bSA9IHRoaXMuX2xlblxuXG4gIGZvciAodmFyIG9mZnNldCA9IDA7IG9mZnNldCA8IGxlbmd0aDspIHtcbiAgICB2YXIgYXNzaWduZWQgPSBhY2N1bSAlIGJsb2NrU2l6ZVxuICAgIHZhciByZW1haW5kZXIgPSBNYXRoLm1pbihsZW5ndGggLSBvZmZzZXQsIGJsb2NrU2l6ZSAtIGFzc2lnbmVkKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZW1haW5kZXI7IGkrKykge1xuICAgICAgYmxvY2tbYXNzaWduZWQgKyBpXSA9IGRhdGFbb2Zmc2V0ICsgaV1cbiAgICB9XG5cbiAgICBhY2N1bSArPSByZW1haW5kZXJcbiAgICBvZmZzZXQgKz0gcmVtYWluZGVyXG5cbiAgICBpZiAoKGFjY3VtICUgYmxvY2tTaXplKSA9PT0gMCkge1xuICAgICAgdGhpcy5fdXBkYXRlKGJsb2NrKVxuICAgIH1cbiAgfVxuXG4gIHRoaXMuX2xlbiArPSBsZW5ndGhcbiAgcmV0dXJuIHRoaXNcbn1cblxuSGFzaC5wcm90b3R5cGUuZGlnZXN0ID0gZnVuY3Rpb24gKGVuYykge1xuICB2YXIgcmVtID0gdGhpcy5fbGVuICUgdGhpcy5fYmxvY2tTaXplXG5cbiAgdGhpcy5fYmxvY2tbcmVtXSA9IDB4ODBcblxuICAvLyB6ZXJvIChyZW0gKyAxKSB0cmFpbGluZyBiaXRzLCB3aGVyZSAocmVtICsgMSkgaXMgdGhlIHNtYWxsZXN0XG4gIC8vIG5vbi1uZWdhdGl2ZSBzb2x1dGlvbiB0byB0aGUgZXF1YXRpb24gKGxlbmd0aCArIDEgKyAocmVtICsgMSkpID09PSBmaW5hbFNpemUgbW9kIGJsb2NrU2l6ZVxuICB0aGlzLl9ibG9jay5maWxsKDAsIHJlbSArIDEpXG5cbiAgaWYgKHJlbSA+PSB0aGlzLl9maW5hbFNpemUpIHtcbiAgICB0aGlzLl91cGRhdGUodGhpcy5fYmxvY2spXG4gICAgdGhpcy5fYmxvY2suZmlsbCgwKVxuICB9XG5cbiAgdmFyIGJpdHMgPSB0aGlzLl9sZW4gKiA4XG5cbiAgLy8gdWludDMyXG4gIGlmIChiaXRzIDw9IDB4ZmZmZmZmZmYpIHtcbiAgICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkJFKGJpdHMsIHRoaXMuX2Jsb2NrU2l6ZSAtIDQpXG5cbiAgLy8gdWludDY0XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxvd0JpdHMgPSAoYml0cyAmIDB4ZmZmZmZmZmYpID4+PiAwXG4gICAgdmFyIGhpZ2hCaXRzID0gKGJpdHMgLSBsb3dCaXRzKSAvIDB4MTAwMDAwMDAwXG5cbiAgICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkJFKGhpZ2hCaXRzLCB0aGlzLl9ibG9ja1NpemUgLSA4KVxuICAgIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyQkUobG93Qml0cywgdGhpcy5fYmxvY2tTaXplIC0gNClcbiAgfVxuXG4gIHRoaXMuX3VwZGF0ZSh0aGlzLl9ibG9jaylcbiAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoKClcblxuICByZXR1cm4gZW5jID8gaGFzaC50b1N0cmluZyhlbmMpIDogaGFzaFxufVxuXG5IYXNoLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ191cGRhdGUgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzcycpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gSGFzaFxuIiwidmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFNIQSAoYWxnb3JpdGhtKSB7XG4gIGFsZ29yaXRobSA9IGFsZ29yaXRobS50b0xvd2VyQ2FzZSgpXG5cbiAgdmFyIEFsZ29yaXRobSA9IGV4cG9ydHNbYWxnb3JpdGhtXVxuICBpZiAoIUFsZ29yaXRobSkgdGhyb3cgbmV3IEVycm9yKGFsZ29yaXRobSArICcgaXMgbm90IHN1cHBvcnRlZCAod2UgYWNjZXB0IHB1bGwgcmVxdWVzdHMpJylcblxuICByZXR1cm4gbmV3IEFsZ29yaXRobSgpXG59XG5cbmV4cG9ydHMuc2hhID0gcmVxdWlyZSg5NylcbmV4cG9ydHMuc2hhMSA9IHJlcXVpcmUoOTgpXG5leHBvcnRzLnNoYTIyNCA9IHJlcXVpcmUoOTkpXG5leHBvcnRzLnNoYTI1NiA9IHJlcXVpcmUoMTAwKVxuZXhwb3J0cy5zaGEzODQgPSByZXF1aXJlKDEwMSlcbmV4cG9ydHMuc2hhNTEyID0gcmVxdWlyZSgxMDIpXG4iLCIvKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0wLCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIFBVQiAxODAtMVxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBkZXJpdmVkIGZyb20gc2hhMS5qcyBvZiB0aGUgc2FtZSByZXBvc2l0b3J5LlxuICogVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBTSEEtMCBhbmQgU0hBLTEgaXMganVzdCBhIGJpdHdpc2Ugcm90YXRlIGxlZnRcbiAqIG9wZXJhdGlvbiB3YXMgYWRkZWQuXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBIYXNoID0gcmVxdWlyZSg5NSlcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcblxudmFyIEsgPSBbXG4gIDB4NWE4Mjc5OTksIDB4NmVkOWViYTEsIDB4OGYxYmJjZGMgfCAwLCAweGNhNjJjMWQ2IHwgMFxuXVxuXG52YXIgVyA9IG5ldyBBcnJheSg4MClcblxuZnVuY3Rpb24gU2hhICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGEsIEhhc2gpXG5cblNoYS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4Njc0NTIzMDFcbiAgdGhpcy5fYiA9IDB4ZWZjZGFiODlcbiAgdGhpcy5fYyA9IDB4OThiYWRjZmVcbiAgdGhpcy5fZCA9IDB4MTAzMjU0NzZcbiAgdGhpcy5fZSA9IDB4YzNkMmUxZjBcblxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiByb3RsNSAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDUpIHwgKG51bSA+Pj4gMjcpXG59XG5cbmZ1bmN0aW9uIHJvdGwzMCAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDMwKSB8IChudW0gPj4+IDIpXG59XG5cbmZ1bmN0aW9uIGZ0IChzLCBiLCBjLCBkKSB7XG4gIGlmIChzID09PSAwKSByZXR1cm4gKGIgJiBjKSB8ICgofmIpICYgZClcbiAgaWYgKHMgPT09IDIpIHJldHVybiAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZClcbiAgcmV0dXJuIGIgXiBjIF4gZFxufVxuXG5TaGEucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYSA9IHRoaXMuX2EgfCAwXG4gIHZhciBiID0gdGhpcy5fYiB8IDBcbiAgdmFyIGMgPSB0aGlzLl9jIHwgMFxuICB2YXIgZCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlID0gdGhpcy5fZSB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIFdbaV0gPSBNLnJlYWRJbnQzMkJFKGkgKiA0KVxuICBmb3IgKDsgaSA8IDgwOyArK2kpIFdbaV0gPSBXW2kgLSAzXSBeIFdbaSAtIDhdIF4gV1tpIC0gMTRdIF4gV1tpIC0gMTZdXG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCA4MDsgKytqKSB7XG4gICAgdmFyIHMgPSB+fihqIC8gMjApXG4gICAgdmFyIHQgPSAocm90bDUoYSkgKyBmdChzLCBiLCBjLCBkKSArIGUgKyBXW2pdICsgS1tzXSkgfCAwXG5cbiAgICBlID0gZFxuICAgIGQgPSBjXG4gICAgYyA9IHJvdGwzMChiKVxuICAgIGIgPSBhXG4gICAgYSA9IHRcbiAgfVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbn1cblxuU2hhLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMjApXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSB8IDAsIDApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2IgfCAwLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jIHwgMCwgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCB8IDAsIDEyKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9lIHwgMCwgMTYpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGFcbiIsIi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTEsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBWZXJzaW9uIDIuMWEgQ29weXJpZ2h0IFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDIuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBkZXRhaWxzLlxuICovXG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoNjUpXG52YXIgSGFzaCA9IHJlcXVpcmUoOTUpXG52YXIgQnVmZmVyID0gcmVxdWlyZSg5MykuQnVmZmVyXG5cbnZhciBLID0gW1xuICAweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjIHwgMCwgMHhjYTYyYzFkNiB8IDBcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoODApXG5cbmZ1bmN0aW9uIFNoYTEgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYTEsIEhhc2gpXG5cblNoYTEucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDY3NDUyMzAxXG4gIHRoaXMuX2IgPSAweGVmY2RhYjg5XG4gIHRoaXMuX2MgPSAweDk4YmFkY2ZlXG4gIHRoaXMuX2QgPSAweDEwMzI1NDc2XG4gIHRoaXMuX2UgPSAweGMzZDJlMWYwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gcm90bDEgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCAxKSB8IChudW0gPj4+IDMxKVxufVxuXG5mdW5jdGlvbiByb3RsNSAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDUpIHwgKG51bSA+Pj4gMjcpXG59XG5cbmZ1bmN0aW9uIHJvdGwzMCAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDMwKSB8IChudW0gPj4+IDIpXG59XG5cbmZ1bmN0aW9uIGZ0IChzLCBiLCBjLCBkKSB7XG4gIGlmIChzID09PSAwKSByZXR1cm4gKGIgJiBjKSB8ICgofmIpICYgZClcbiAgaWYgKHMgPT09IDIpIHJldHVybiAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZClcbiAgcmV0dXJuIGIgXiBjIF4gZFxufVxuXG5TaGExLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hIHwgMFxuICB2YXIgYiA9IHRoaXMuX2IgfCAwXG4gIHZhciBjID0gdGhpcy5fYyB8IDBcbiAgdmFyIGQgPSB0aGlzLl9kIHwgMFxuICB2YXIgZSA9IHRoaXMuX2UgfCAwXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgKytpKSBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgZm9yICg7IGkgPCA4MDsgKytpKSBXW2ldID0gcm90bDEoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSlcblxuICBmb3IgKHZhciBqID0gMDsgaiA8IDgwOyArK2opIHtcbiAgICB2YXIgcyA9IH5+KGogLyAyMClcbiAgICB2YXIgdCA9IChyb3RsNShhKSArIGZ0KHMsIGIsIGMsIGQpICsgZSArIFdbal0gKyBLW3NdKSB8IDBcblxuICAgIGUgPSBkXG4gICAgZCA9IGNcbiAgICBjID0gcm90bDMwKGIpXG4gICAgYiA9IGFcbiAgICBhID0gdFxuICB9XG5cbiAgdGhpcy5fYSA9IChhICsgdGhpcy5fYSkgfCAwXG4gIHRoaXMuX2IgPSAoYiArIHRoaXMuX2IpIHwgMFxuICB0aGlzLl9jID0gKGMgKyB0aGlzLl9jKSB8IDBcbiAgdGhpcy5fZCA9IChkICsgdGhpcy5fZCkgfCAwXG4gIHRoaXMuX2UgPSAoZSArIHRoaXMuX2UpIHwgMFxufVxuXG5TaGExLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMjApXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSB8IDAsIDApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2IgfCAwLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jIHwgMCwgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCB8IDAsIDEyKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9lIHwgMCwgMTYpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGExXG4iLCIvKipcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMjU2LCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIDE4MC0yXG4gKiBWZXJzaW9uIDIuMi1iZXRhIENvcHlyaWdodCBBbmdlbCBNYXJpbiwgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwOS5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBTaGEyNTYgPSByZXF1aXJlKDEwMClcbnZhciBIYXNoID0gcmVxdWlyZSg5NSlcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcblxudmFyIFcgPSBuZXcgQXJyYXkoNjQpXG5cbmZ1bmN0aW9uIFNoYTIyNCAoKSB7XG4gIHRoaXMuaW5pdCgpXG5cbiAgdGhpcy5fdyA9IFcgLy8gbmV3IEFycmF5KDY0KVxuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYTIyNCwgU2hhMjU2KVxuXG5TaGEyMjQucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweGMxMDU5ZWQ4XG4gIHRoaXMuX2IgPSAweDM2N2NkNTA3XG4gIHRoaXMuX2MgPSAweDMwNzBkZDE3XG4gIHRoaXMuX2QgPSAweGY3MGU1OTM5XG4gIHRoaXMuX2UgPSAweGZmYzAwYjMxXG4gIHRoaXMuX2YgPSAweDY4NTgxNTExXG4gIHRoaXMuX2cgPSAweDY0Zjk4ZmE3XG4gIHRoaXMuX2ggPSAweGJlZmE0ZmE0XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuU2hhMjI0LnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMjgpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEyMjRcbiIsIi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKDY1KVxudmFyIEhhc2ggPSByZXF1aXJlKDk1KVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlclxuXG52YXIgSyA9IFtcbiAgMHg0MjhBMkY5OCwgMHg3MTM3NDQ5MSwgMHhCNUMwRkJDRiwgMHhFOUI1REJBNSxcbiAgMHgzOTU2QzI1QiwgMHg1OUYxMTFGMSwgMHg5MjNGODJBNCwgMHhBQjFDNUVENSxcbiAgMHhEODA3QUE5OCwgMHgxMjgzNUIwMSwgMHgyNDMxODVCRSwgMHg1NTBDN0RDMyxcbiAgMHg3MkJFNUQ3NCwgMHg4MERFQjFGRSwgMHg5QkRDMDZBNywgMHhDMTlCRjE3NCxcbiAgMHhFNDlCNjlDMSwgMHhFRkJFNDc4NiwgMHgwRkMxOURDNiwgMHgyNDBDQTFDQyxcbiAgMHgyREU5MkM2RiwgMHg0QTc0ODRBQSwgMHg1Q0IwQTlEQywgMHg3NkY5ODhEQSxcbiAgMHg5ODNFNTE1MiwgMHhBODMxQzY2RCwgMHhCMDAzMjdDOCwgMHhCRjU5N0ZDNyxcbiAgMHhDNkUwMEJGMywgMHhENUE3OTE0NywgMHgwNkNBNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN0I3MEE4NSwgMHgyRTFCMjEzOCwgMHg0RDJDNkRGQywgMHg1MzM4MEQxMyxcbiAgMHg2NTBBNzM1NCwgMHg3NjZBMEFCQiwgMHg4MUMyQzkyRSwgMHg5MjcyMkM4NSxcbiAgMHhBMkJGRThBMSwgMHhBODFBNjY0QiwgMHhDMjRCOEI3MCwgMHhDNzZDNTFBMyxcbiAgMHhEMTkyRTgxOSwgMHhENjk5MDYyNCwgMHhGNDBFMzU4NSwgMHgxMDZBQTA3MCxcbiAgMHgxOUE0QzExNiwgMHgxRTM3NkMwOCwgMHgyNzQ4Nzc0QywgMHgzNEIwQkNCNSxcbiAgMHgzOTFDMENCMywgMHg0RUQ4QUE0QSwgMHg1QjlDQ0E0RiwgMHg2ODJFNkZGMyxcbiAgMHg3NDhGODJFRSwgMHg3OEE1NjM2RiwgMHg4NEM4NzgxNCwgMHg4Q0M3MDIwOCxcbiAgMHg5MEJFRkZGQSwgMHhBNDUwNkNFQiwgMHhCRUY5QTNGNywgMHhDNjcxNzhGMlxuXVxuXG52YXIgVyA9IG5ldyBBcnJheSg2NClcblxuZnVuY3Rpb24gU2hhMjU2ICgpIHtcbiAgdGhpcy5pbml0KClcblxuICB0aGlzLl93ID0gVyAvLyBuZXcgQXJyYXkoNjQpXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhMjU2LCBIYXNoKVxuXG5TaGEyNTYucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDZhMDllNjY3XG4gIHRoaXMuX2IgPSAweGJiNjdhZTg1XG4gIHRoaXMuX2MgPSAweDNjNmVmMzcyXG4gIHRoaXMuX2QgPSAweGE1NGZmNTNhXG4gIHRoaXMuX2UgPSAweDUxMGU1MjdmXG4gIHRoaXMuX2YgPSAweDliMDU2ODhjXG4gIHRoaXMuX2cgPSAweDFmODNkOWFiXG4gIHRoaXMuX2ggPSAweDViZTBjZDE5XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gY2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIG1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gc2lnbWEwICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gMiB8IHggPDwgMzApIF4gKHggPj4+IDEzIHwgeCA8PCAxOSkgXiAoeCA+Pj4gMjIgfCB4IDw8IDEwKVxufVxuXG5mdW5jdGlvbiBzaWdtYTEgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiA2IHwgeCA8PCAyNikgXiAoeCA+Pj4gMTEgfCB4IDw8IDIxKSBeICh4ID4+PiAyNSB8IHggPDwgNylcbn1cblxuZnVuY3Rpb24gZ2FtbWEwICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gNyB8IHggPDwgMjUpIF4gKHggPj4+IDE4IHwgeCA8PCAxNCkgXiAoeCA+Pj4gMylcbn1cblxuZnVuY3Rpb24gZ2FtbWExICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gMTcgfCB4IDw8IDE1KSBeICh4ID4+PiAxOSB8IHggPDwgMTMpIF4gKHggPj4+IDEwKVxufVxuXG5TaGEyNTYucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYSA9IHRoaXMuX2EgfCAwXG4gIHZhciBiID0gdGhpcy5fYiB8IDBcbiAgdmFyIGMgPSB0aGlzLl9jIHwgMFxuICB2YXIgZCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlID0gdGhpcy5fZSB8IDBcbiAgdmFyIGYgPSB0aGlzLl9mIHwgMFxuICB2YXIgZyA9IHRoaXMuX2cgfCAwXG4gIHZhciBoID0gdGhpcy5faCB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIFdbaV0gPSBNLnJlYWRJbnQzMkJFKGkgKiA0KVxuICBmb3IgKDsgaSA8IDY0OyArK2kpIFdbaV0gPSAoZ2FtbWExKFdbaSAtIDJdKSArIFdbaSAtIDddICsgZ2FtbWEwKFdbaSAtIDE1XSkgKyBXW2kgLSAxNl0pIHwgMFxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgNjQ7ICsraikge1xuICAgIHZhciBUMSA9IChoICsgc2lnbWExKGUpICsgY2goZSwgZiwgZykgKyBLW2pdICsgV1tqXSkgfCAwXG4gICAgdmFyIFQyID0gKHNpZ21hMChhKSArIG1haihhLCBiLCBjKSkgfCAwXG5cbiAgICBoID0gZ1xuICAgIGcgPSBmXG4gICAgZiA9IGVcbiAgICBlID0gKGQgKyBUMSkgfCAwXG4gICAgZCA9IGNcbiAgICBjID0gYlxuICAgIGIgPSBhXG4gICAgYSA9IChUMSArIFQyKSB8IDBcbiAgfVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbiAgdGhpcy5fZiA9IChmICsgdGhpcy5fZikgfCAwXG4gIHRoaXMuX2cgPSAoZyArIHRoaXMuX2cpIHwgMFxuICB0aGlzLl9oID0gKGggKyB0aGlzLl9oKSB8IDBcbn1cblxuU2hhMjU2LnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMzIpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2gsIDI4KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMjU2XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKDY1KVxudmFyIFNIQTUxMiA9IHJlcXVpcmUoMTAyKVxudmFyIEhhc2ggPSByZXF1aXJlKDk1KVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlclxuXG52YXIgVyA9IG5ldyBBcnJheSgxNjApXG5cbmZ1bmN0aW9uIFNoYTM4NCAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDEyOCwgMTEyKVxufVxuXG5pbmhlcml0cyhTaGEzODQsIFNIQTUxMilcblxuU2hhMzg0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9haCA9IDB4Y2JiYjlkNWRcbiAgdGhpcy5fYmggPSAweDYyOWEyOTJhXG4gIHRoaXMuX2NoID0gMHg5MTU5MDE1YVxuICB0aGlzLl9kaCA9IDB4MTUyZmVjZDhcbiAgdGhpcy5fZWggPSAweDY3MzMyNjY3XG4gIHRoaXMuX2ZoID0gMHg4ZWI0NGE4N1xuICB0aGlzLl9naCA9IDB4ZGIwYzJlMGRcbiAgdGhpcy5faGggPSAweDQ3YjU0ODFkXG5cbiAgdGhpcy5fYWwgPSAweGMxMDU5ZWQ4XG4gIHRoaXMuX2JsID0gMHgzNjdjZDUwN1xuICB0aGlzLl9jbCA9IDB4MzA3MGRkMTdcbiAgdGhpcy5fZGwgPSAweGY3MGU1OTM5XG4gIHRoaXMuX2VsID0gMHhmZmMwMGIzMVxuICB0aGlzLl9mbCA9IDB4Njg1ODE1MTFcbiAgdGhpcy5fZ2wgPSAweDY0Zjk4ZmE3XG4gIHRoaXMuX2hsID0gMHhiZWZhNGZhNFxuXG4gIHJldHVybiB0aGlzXG59XG5cblNoYTM4NC5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDQ4KVxuXG4gIGZ1bmN0aW9uIHdyaXRlSW50NjRCRSAoaCwgbCwgb2Zmc2V0KSB7XG4gICAgSC53cml0ZUludDMyQkUoaCwgb2Zmc2V0KVxuICAgIEgud3JpdGVJbnQzMkJFKGwsIG9mZnNldCArIDQpXG4gIH1cblxuICB3cml0ZUludDY0QkUodGhpcy5fYWgsIHRoaXMuX2FsLCAwKVxuICB3cml0ZUludDY0QkUodGhpcy5fYmgsIHRoaXMuX2JsLCA4KVxuICB3cml0ZUludDY0QkUodGhpcy5fY2gsIHRoaXMuX2NsLCAxNilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2RoLCB0aGlzLl9kbCwgMjQpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9laCwgdGhpcy5fZWwsIDMyKVxuICB3cml0ZUludDY0QkUodGhpcy5fZmgsIHRoaXMuX2ZsLCA0MClcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTM4NFxuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBIYXNoID0gcmVxdWlyZSg5NSlcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcblxudmFyIEsgPSBbXG4gIDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIsIDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QsXG4gIDB4YjVjMGZiY2YsIDB4ZWM0ZDNiMmYsIDB4ZTliNWRiYTUsIDB4ODE4OWRiYmMsXG4gIDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgsIDB4NTlmMTExZjEsIDB4YjYwNWQwMTksXG4gIDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIsIDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgsXG4gIDB4ZDgwN2FhOTgsIDB4YTMwMzAyNDIsIDB4MTI4MzViMDEsIDB4NDU3MDZmYmUsXG4gIDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMsIDB4NTUwYzdkYzMsIDB4ZDVmZmI0ZTIsXG4gIDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYsIDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEsXG4gIDB4OWJkYzA2YTcsIDB4MjVjNzEyMzUsIDB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTQsXG4gIDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIsIDB4ZWZiZTQ3ODYsIDB4Mzg0ZjI1ZTMsXG4gIDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUsIDB4MjQwY2ExY2MsIDB4NzdhYzljNjUsXG4gIDB4MmRlOTJjNmYsIDB4NTkyYjAyNzUsIDB4NGE3NDg0YWEsIDB4NmVhNmU0ODMsXG4gIDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQsIDB4NzZmOTg4ZGEsIDB4ODMxMTUzYjUsXG4gIDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIsIDB4YTgzMWM2NmQsIDB4MmRiNDMyMTAsXG4gIDB4YjAwMzI3YzgsIDB4OThmYjIxM2YsIDB4YmY1OTdmYzcsIDB4YmVlZjBlZTQsXG4gIDB4YzZlMDBiZjMsIDB4M2RhODhmYzIsIDB4ZDVhNzkxNDcsIDB4OTMwYWE3MjUsXG4gIDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYsIDB4MTQyOTI5NjcsIDB4MGEwZTZlNzAsXG4gIDB4MjdiNzBhODUsIDB4NDZkMjJmZmMsIDB4MmUxYjIxMzgsIDB4NWMyNmM5MjYsXG4gIDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQsIDB4NTMzODBkMTMsIDB4OWQ5NWIzZGYsXG4gIDB4NjUwYTczNTQsIDB4OGJhZjYzZGUsIDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgsXG4gIDB4ODFjMmM5MmUsIDB4NDdlZGFlZTYsIDB4OTI3MjJjODUsIDB4MTQ4MjM1M2IsXG4gIDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQsIDB4YTgxYTY2NGIsIDB4YmM0MjMwMDEsXG4gIDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEsIDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzAsXG4gIDB4ZDE5MmU4MTksIDB4ZDZlZjUyMTgsIDB4ZDY5OTA2MjQsIDB4NTU2NWE5MTAsXG4gIDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEsIDB4MTA2YWEwNzAsIDB4MzJiYmQxYjgsXG4gIDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgsIDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMsXG4gIDB4Mjc0ODc3NGMsIDB4ZGY4ZWViOTksIDB4MzRiMGJjYjUsIDB4ZTE5YjQ4YTgsXG4gIDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMsIDB4NGVkOGFhNGEsIDB4ZTM0MThhY2IsXG4gIDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMsIDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMsXG4gIDB4NzQ4ZjgyZWUsIDB4NWRlZmIyZmMsIDB4NzhhNTYzNmYsIDB4NDMxNzJmNjAsXG4gIDB4ODRjODc4MTQsIDB4YTFmMGFiNzIsIDB4OGNjNzAyMDgsIDB4MWE2NDM5ZWMsXG4gIDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgsIDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTksXG4gIDB4YmVmOWEzZjcsIDB4YjJjNjc5MTUsIDB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmIsXG4gIDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMsIDB4ZDE4NmI4YzcsIDB4MjFjMGMyMDcsXG4gIDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUsIDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgsXG4gIDB4MDZmMDY3YWEsIDB4NzIxNzZmYmEsIDB4MGE2MzdkYzUsIDB4YTJjODk4YTYsXG4gIDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUsIDB4MWI3MTBiMzUsIDB4MTMxYzQ3MWIsXG4gIDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQsIDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMsXG4gIDB4M2M5ZWJlMGEsIDB4MTVjOWJlYmMsIDB4NDMxZDY3YzQsIDB4OWMxMDBkNGMsXG4gIDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYsIDB4NTk3ZjI5OWMsIDB4ZmM2NTdlMmEsXG4gIDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMsIDB4NmM0NDE5OGMsIDB4NGE0NzU4MTdcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoMTYwKVxuXG5mdW5jdGlvbiBTaGE1MTIgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCAxMjgsIDExMilcbn1cblxuaW5oZXJpdHMoU2hhNTEyLCBIYXNoKVxuXG5TaGE1MTIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2FoID0gMHg2YTA5ZTY2N1xuICB0aGlzLl9iaCA9IDB4YmI2N2FlODVcbiAgdGhpcy5fY2ggPSAweDNjNmVmMzcyXG4gIHRoaXMuX2RoID0gMHhhNTRmZjUzYVxuICB0aGlzLl9laCA9IDB4NTEwZTUyN2ZcbiAgdGhpcy5fZmggPSAweDliMDU2ODhjXG4gIHRoaXMuX2doID0gMHgxZjgzZDlhYlxuICB0aGlzLl9oaCA9IDB4NWJlMGNkMTlcblxuICB0aGlzLl9hbCA9IDB4ZjNiY2M5MDhcbiAgdGhpcy5fYmwgPSAweDg0Y2FhNzNiXG4gIHRoaXMuX2NsID0gMHhmZTk0ZjgyYlxuICB0aGlzLl9kbCA9IDB4NWYxZDM2ZjFcbiAgdGhpcy5fZWwgPSAweGFkZTY4MmQxXG4gIHRoaXMuX2ZsID0gMHgyYjNlNmMxZlxuICB0aGlzLl9nbCA9IDB4ZmI0MWJkNmJcbiAgdGhpcy5faGwgPSAweDEzN2UyMTc5XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gQ2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIG1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gc2lnbWEwICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDI4IHwgeGwgPDwgNCkgXiAoeGwgPj4+IDIgfCB4IDw8IDMwKSBeICh4bCA+Pj4gNyB8IHggPDwgMjUpXG59XG5cbmZ1bmN0aW9uIHNpZ21hMSAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxNCB8IHhsIDw8IDE4KSBeICh4ID4+PiAxOCB8IHhsIDw8IDE0KSBeICh4bCA+Pj4gOSB8IHggPDwgMjMpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNylcbn1cblxuZnVuY3Rpb24gR2FtbWEwbCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNyB8IHhsIDw8IDI1KVxufVxuXG5mdW5jdGlvbiBHYW1tYTEgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMTkgfCB4bCA8PCAxMykgXiAoeGwgPj4+IDI5IHwgeCA8PCAzKSBeICh4ID4+PiA2KVxufVxuXG5mdW5jdGlvbiBHYW1tYTFsICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDE5IHwgeGwgPDwgMTMpIF4gKHhsID4+PiAyOSB8IHggPDwgMykgXiAoeCA+Pj4gNiB8IHhsIDw8IDI2KVxufVxuXG5mdW5jdGlvbiBnZXRDYXJyeSAoYSwgYikge1xuICByZXR1cm4gKGEgPj4+IDApIDwgKGIgPj4+IDApID8gMSA6IDBcbn1cblxuU2hhNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGFoID0gdGhpcy5fYWggfCAwXG4gIHZhciBiaCA9IHRoaXMuX2JoIHwgMFxuICB2YXIgY2ggPSB0aGlzLl9jaCB8IDBcbiAgdmFyIGRoID0gdGhpcy5fZGggfCAwXG4gIHZhciBlaCA9IHRoaXMuX2VoIHwgMFxuICB2YXIgZmggPSB0aGlzLl9maCB8IDBcbiAgdmFyIGdoID0gdGhpcy5fZ2ggfCAwXG4gIHZhciBoaCA9IHRoaXMuX2hoIHwgMFxuXG4gIHZhciBhbCA9IHRoaXMuX2FsIHwgMFxuICB2YXIgYmwgPSB0aGlzLl9ibCB8IDBcbiAgdmFyIGNsID0gdGhpcy5fY2wgfCAwXG4gIHZhciBkbCA9IHRoaXMuX2RsIHwgMFxuICB2YXIgZWwgPSB0aGlzLl9lbCB8IDBcbiAgdmFyIGZsID0gdGhpcy5fZmwgfCAwXG4gIHZhciBnbCA9IHRoaXMuX2dsIHwgMFxuICB2YXIgaGwgPSB0aGlzLl9obCB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpICs9IDIpIHtcbiAgICBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgICBXW2kgKyAxXSA9IE0ucmVhZEludDMyQkUoaSAqIDQgKyA0KVxuICB9XG4gIGZvciAoOyBpIDwgMTYwOyBpICs9IDIpIHtcbiAgICB2YXIgeGggPSBXW2kgLSAxNSAqIDJdXG4gICAgdmFyIHhsID0gV1tpIC0gMTUgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWEwID0gR2FtbWEwKHhoLCB4bClcbiAgICB2YXIgZ2FtbWEwbCA9IEdhbW1hMGwoeGwsIHhoKVxuXG4gICAgeGggPSBXW2kgLSAyICogMl1cbiAgICB4bCA9IFdbaSAtIDIgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWExID0gR2FtbWExKHhoLCB4bClcbiAgICB2YXIgZ2FtbWExbCA9IEdhbW1hMWwoeGwsIHhoKVxuXG4gICAgLy8gV1tpXSA9IGdhbW1hMCArIFdbaSAtIDddICsgZ2FtbWExICsgV1tpIC0gMTZdXG4gICAgdmFyIFdpN2ggPSBXW2kgLSA3ICogMl1cbiAgICB2YXIgV2k3bCA9IFdbaSAtIDcgKiAyICsgMV1cblxuICAgIHZhciBXaTE2aCA9IFdbaSAtIDE2ICogMl1cbiAgICB2YXIgV2kxNmwgPSBXW2kgLSAxNiAqIDIgKyAxXVxuXG4gICAgdmFyIFdpbCA9IChnYW1tYTBsICsgV2k3bCkgfCAwXG4gICAgdmFyIFdpaCA9IChnYW1tYTAgKyBXaTdoICsgZ2V0Q2FycnkoV2lsLCBnYW1tYTBsKSkgfCAwXG4gICAgV2lsID0gKFdpbCArIGdhbW1hMWwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBnYW1tYTEgKyBnZXRDYXJyeShXaWwsIGdhbW1hMWwpKSB8IDBcbiAgICBXaWwgPSAoV2lsICsgV2kxNmwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBXaTE2aCArIGdldENhcnJ5KFdpbCwgV2kxNmwpKSB8IDBcblxuICAgIFdbaV0gPSBXaWhcbiAgICBXW2kgKyAxXSA9IFdpbFxuICB9XG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCAxNjA7IGogKz0gMikge1xuICAgIFdpaCA9IFdbal1cbiAgICBXaWwgPSBXW2ogKyAxXVxuXG4gICAgdmFyIG1hamggPSBtYWooYWgsIGJoLCBjaClcbiAgICB2YXIgbWFqbCA9IG1haihhbCwgYmwsIGNsKVxuXG4gICAgdmFyIHNpZ21hMGggPSBzaWdtYTAoYWgsIGFsKVxuICAgIHZhciBzaWdtYTBsID0gc2lnbWEwKGFsLCBhaClcbiAgICB2YXIgc2lnbWExaCA9IHNpZ21hMShlaCwgZWwpXG4gICAgdmFyIHNpZ21hMWwgPSBzaWdtYTEoZWwsIGVoKVxuXG4gICAgLy8gdDEgPSBoICsgc2lnbWExICsgY2ggKyBLW2pdICsgV1tqXVxuICAgIHZhciBLaWggPSBLW2pdXG4gICAgdmFyIEtpbCA9IEtbaiArIDFdXG5cbiAgICB2YXIgY2hoID0gQ2goZWgsIGZoLCBnaClcbiAgICB2YXIgY2hsID0gQ2goZWwsIGZsLCBnbClcblxuICAgIHZhciB0MWwgPSAoaGwgKyBzaWdtYTFsKSB8IDBcbiAgICB2YXIgdDFoID0gKGhoICsgc2lnbWExaCArIGdldENhcnJ5KHQxbCwgaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgY2hsKSB8IDBcbiAgICB0MWggPSAodDFoICsgY2hoICsgZ2V0Q2FycnkodDFsLCBjaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgS2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgS2loICsgZ2V0Q2FycnkodDFsLCBLaWwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgV2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgV2loICsgZ2V0Q2FycnkodDFsLCBXaWwpKSB8IDBcblxuICAgIC8vIHQyID0gc2lnbWEwICsgbWFqXG4gICAgdmFyIHQybCA9IChzaWdtYTBsICsgbWFqbCkgfCAwXG4gICAgdmFyIHQyaCA9IChzaWdtYTBoICsgbWFqaCArIGdldENhcnJ5KHQybCwgc2lnbWEwbCkpIHwgMFxuXG4gICAgaGggPSBnaFxuICAgIGhsID0gZ2xcbiAgICBnaCA9IGZoXG4gICAgZ2wgPSBmbFxuICAgIGZoID0gZWhcbiAgICBmbCA9IGVsXG4gICAgZWwgPSAoZGwgKyB0MWwpIHwgMFxuICAgIGVoID0gKGRoICsgdDFoICsgZ2V0Q2FycnkoZWwsIGRsKSkgfCAwXG4gICAgZGggPSBjaFxuICAgIGRsID0gY2xcbiAgICBjaCA9IGJoXG4gICAgY2wgPSBibFxuICAgIGJoID0gYWhcbiAgICBibCA9IGFsXG4gICAgYWwgPSAodDFsICsgdDJsKSB8IDBcbiAgICBhaCA9ICh0MWggKyB0MmggKyBnZXRDYXJyeShhbCwgdDFsKSkgfCAwXG4gIH1cblxuICB0aGlzLl9hbCA9ICh0aGlzLl9hbCArIGFsKSB8IDBcbiAgdGhpcy5fYmwgPSAodGhpcy5fYmwgKyBibCkgfCAwXG4gIHRoaXMuX2NsID0gKHRoaXMuX2NsICsgY2wpIHwgMFxuICB0aGlzLl9kbCA9ICh0aGlzLl9kbCArIGRsKSB8IDBcbiAgdGhpcy5fZWwgPSAodGhpcy5fZWwgKyBlbCkgfCAwXG4gIHRoaXMuX2ZsID0gKHRoaXMuX2ZsICsgZmwpIHwgMFxuICB0aGlzLl9nbCA9ICh0aGlzLl9nbCArIGdsKSB8IDBcbiAgdGhpcy5faGwgPSAodGhpcy5faGwgKyBobCkgfCAwXG5cbiAgdGhpcy5fYWggPSAodGhpcy5fYWggKyBhaCArIGdldENhcnJ5KHRoaXMuX2FsLCBhbCkpIHwgMFxuICB0aGlzLl9iaCA9ICh0aGlzLl9iaCArIGJoICsgZ2V0Q2FycnkodGhpcy5fYmwsIGJsKSkgfCAwXG4gIHRoaXMuX2NoID0gKHRoaXMuX2NoICsgY2ggKyBnZXRDYXJyeSh0aGlzLl9jbCwgY2wpKSB8IDBcbiAgdGhpcy5fZGggPSAodGhpcy5fZGggKyBkaCArIGdldENhcnJ5KHRoaXMuX2RsLCBkbCkpIHwgMFxuICB0aGlzLl9laCA9ICh0aGlzLl9laCArIGVoICsgZ2V0Q2FycnkodGhpcy5fZWwsIGVsKSkgfCAwXG4gIHRoaXMuX2ZoID0gKHRoaXMuX2ZoICsgZmggKyBnZXRDYXJyeSh0aGlzLl9mbCwgZmwpKSB8IDBcbiAgdGhpcy5fZ2ggPSAodGhpcy5fZ2ggKyBnaCArIGdldENhcnJ5KHRoaXMuX2dsLCBnbCkpIHwgMFxuICB0aGlzLl9oaCA9ICh0aGlzLl9oaCArIGhoICsgZ2V0Q2FycnkodGhpcy5faGwsIGhsKSkgfCAwXG59XG5cblNoYTUxMi5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDY0KVxuXG4gIGZ1bmN0aW9uIHdyaXRlSW50NjRCRSAoaCwgbCwgb2Zmc2V0KSB7XG4gICAgSC53cml0ZUludDMyQkUoaCwgb2Zmc2V0KVxuICAgIEgud3JpdGVJbnQzMkJFKGwsIG9mZnNldCArIDQpXG4gIH1cblxuICB3cml0ZUludDY0QkUodGhpcy5fYWgsIHRoaXMuX2FsLCAwKVxuICB3cml0ZUludDY0QkUodGhpcy5fYmgsIHRoaXMuX2JsLCA4KVxuICB3cml0ZUludDY0QkUodGhpcy5fY2gsIHRoaXMuX2NsLCAxNilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2RoLCB0aGlzLl9kbCwgMjQpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9laCwgdGhpcy5fZWwsIDMyKVxuICB3cml0ZUludDY0QkUodGhpcy5fZmgsIHRoaXMuX2ZsLCA0MClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2doLCB0aGlzLl9nbCwgNDgpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9oaCwgdGhpcy5faGwsIDU2KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhNTEyXG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBFRSA9IHJlcXVpcmUoNjIpLkV2ZW50RW1pdHRlcjtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoNjUpO1xuXG5pbmhlcml0cyhTdHJlYW0sIEVFKTtcblN0cmVhbS5SZWFkYWJsZSA9IHJlcXVpcmUoODkpO1xuU3RyZWFtLldyaXRhYmxlID0gcmVxdWlyZSg5MSk7XG5TdHJlYW0uRHVwbGV4ID0gcmVxdWlyZSg3OCk7XG5TdHJlYW0uVHJhbnNmb3JtID0gcmVxdWlyZSg5MCk7XG5TdHJlYW0uUGFzc1Rocm91Z2ggPSByZXF1aXJlKDg4KTtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC40LnhcblN0cmVhbS5TdHJlYW0gPSBTdHJlYW07XG5cblxuXG4vLyBvbGQtc3R5bGUgc3RyZWFtcy4gIE5vdGUgdGhhdCB0aGUgcGlwZSBtZXRob2QgKHRoZSBvbmx5IHJlbGV2YW50XG4vLyBwYXJ0IG9mIHRoaXMgY2xhc3MpIGlzIG92ZXJyaWRkZW4gaW4gdGhlIFJlYWRhYmxlIGNsYXNzLlxuXG5mdW5jdGlvbiBTdHJlYW0oKSB7XG4gIEVFLmNhbGwodGhpcyk7XG59XG5cblN0cmVhbS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKGRlc3QsIG9wdGlvbnMpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgaWYgKGRlc3Qud3JpdGFibGUpIHtcbiAgICAgIGlmIChmYWxzZSA9PT0gZGVzdC53cml0ZShjaHVuaykgJiYgc291cmNlLnBhdXNlKSB7XG4gICAgICAgIHNvdXJjZS5wYXVzZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZGF0YScsIG9uZGF0YSk7XG5cbiAgZnVuY3Rpb24gb25kcmFpbigpIHtcbiAgICBpZiAoc291cmNlLnJlYWRhYmxlICYmIHNvdXJjZS5yZXN1bWUpIHtcbiAgICAgIHNvdXJjZS5yZXN1bWUoKTtcbiAgICB9XG4gIH1cblxuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIC8vIElmIHRoZSAnZW5kJyBvcHRpb24gaXMgbm90IHN1cHBsaWVkLCBkZXN0LmVuZCgpIHdpbGwgYmUgY2FsbGVkIHdoZW5cbiAgLy8gc291cmNlIGdldHMgdGhlICdlbmQnIG9yICdjbG9zZScgZXZlbnRzLiAgT25seSBkZXN0LmVuZCgpIG9uY2UuXG4gIGlmICghZGVzdC5faXNTdGRpbyAmJiAoIW9wdGlvbnMgfHwgb3B0aW9ucy5lbmQgIT09IGZhbHNlKSkge1xuICAgIHNvdXJjZS5vbignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5vbignY2xvc2UnLCBvbmNsb3NlKTtcbiAgfVxuXG4gIHZhciBkaWRPbkVuZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGlmICh0eXBlb2YgZGVzdC5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSBkZXN0LmRlc3Ryb3koKTtcbiAgfVxuXG4gIC8vIGRvbid0IGxlYXZlIGRhbmdsaW5nIHBpcGVzIHdoZW4gdGhlcmUgYXJlIGVycm9ycy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGNsZWFudXAoKTtcbiAgICBpZiAoRUUubGlzdGVuZXJDb3VudCh0aGlzLCAnZXJyb3InKSA9PT0gMCkge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCBzdHJlYW0gZXJyb3IgaW4gcGlwZS5cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2Vycm9yJywgb25lcnJvcik7XG4gIGRlc3Qub24oJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gcmVtb3ZlIGFsbCB0aGUgZXZlbnQgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZC5cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcbiAgfVxuXG4gIHNvdXJjZS5vbignZW5kJywgY2xlYW51cCk7XG4gIHNvdXJjZS5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0Lm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3QuZW1pdCgncGlwZScsIHNvdXJjZSk7XG5cbiAgLy8gQWxsb3cgZm9yIHVuaXgtbGlrZSB1c2FnZTogQS5waXBlKEIpLnBpcGUoQylcbiAgcmV0dXJuIGRlc3Q7XG59O1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlcjtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgaXNFbmNvZGluZyA9IEJ1ZmZlci5pc0VuY29kaW5nIHx8IGZ1bmN0aW9uIChlbmNvZGluZykge1xuICBlbmNvZGluZyA9ICcnICsgZW5jb2Rpbmc7XG4gIHN3aXRjaCAoZW5jb2RpbmcgJiYgZW5jb2RpbmcudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6Y2FzZSAndXRmOCc6Y2FzZSAndXRmLTgnOmNhc2UgJ2FzY2lpJzpjYXNlICdiaW5hcnknOmNhc2UgJ2Jhc2U2NCc6Y2FzZSAndWNzMic6Y2FzZSAndWNzLTInOmNhc2UgJ3V0ZjE2bGUnOmNhc2UgJ3V0Zi0xNmxlJzpjYXNlICdyYXcnOlxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX25vcm1hbGl6ZUVuY29kaW5nKGVuYykge1xuICBpZiAoIWVuYykgcmV0dXJuICd1dGY4JztcbiAgdmFyIHJldHJpZWQ7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmMpIHtcbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gJ3V0ZjgnO1xuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuICd1dGYxNmxlJztcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gJ2xhdGluMSc7XG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGVuYztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChyZXRyaWVkKSByZXR1cm47IC8vIHVuZGVmaW5lZFxuICAgICAgICBlbmMgPSAoJycgKyBlbmMpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHJpZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxufTtcblxuLy8gRG8gbm90IGNhY2hlIGBCdWZmZXIuaXNFbmNvZGluZ2Agd2hlbiBjaGVja2luZyBlbmNvZGluZyBuYW1lcyBhcyBzb21lXG4vLyBtb2R1bGVzIG1vbmtleS1wYXRjaCBpdCB0byBzdXBwb3J0IGFkZGl0aW9uYWwgZW5jb2RpbmdzXG5mdW5jdGlvbiBub3JtYWxpemVFbmNvZGluZyhlbmMpIHtcbiAgdmFyIG5lbmMgPSBfbm9ybWFsaXplRW5jb2RpbmcoZW5jKTtcbiAgaWYgKHR5cGVvZiBuZW5jICE9PSAnc3RyaW5nJyAmJiAoQnVmZmVyLmlzRW5jb2RpbmcgPT09IGlzRW5jb2RpbmcgfHwgIWlzRW5jb2RpbmcoZW5jKSkpIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuYyk7XG4gIHJldHVybiBuZW5jIHx8IGVuYztcbn1cblxuLy8gU3RyaW5nRGVjb2RlciBwcm92aWRlcyBhbiBpbnRlcmZhY2UgZm9yIGVmZmljaWVudGx5IHNwbGl0dGluZyBhIHNlcmllcyBvZlxuLy8gYnVmZmVycyBpbnRvIGEgc2VyaWVzIG9mIEpTIHN0cmluZ3Mgd2l0aG91dCBicmVha2luZyBhcGFydCBtdWx0aS1ieXRlXG4vLyBjaGFyYWN0ZXJzLlxuZXhwb3J0cy5TdHJpbmdEZWNvZGVyID0gU3RyaW5nRGVjb2RlcjtcbmZ1bmN0aW9uIFN0cmluZ0RlY29kZXIoZW5jb2RpbmcpIHtcbiAgdGhpcy5lbmNvZGluZyA9IG5vcm1hbGl6ZUVuY29kaW5nKGVuY29kaW5nKTtcbiAgdmFyIG5iO1xuICBzd2l0Y2ggKHRoaXMuZW5jb2RpbmcpIHtcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIHRoaXMudGV4dCA9IHV0ZjE2VGV4dDtcbiAgICAgIHRoaXMuZW5kID0gdXRmMTZFbmQ7XG4gICAgICBuYiA9IDQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd1dGY4JzpcbiAgICAgIHRoaXMuZmlsbExhc3QgPSB1dGY4RmlsbExhc3Q7XG4gICAgICBuYiA9IDQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgdGhpcy50ZXh0ID0gYmFzZTY0VGV4dDtcbiAgICAgIHRoaXMuZW5kID0gYmFzZTY0RW5kO1xuICAgICAgbmIgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBzaW1wbGVXcml0ZTtcbiAgICAgIHRoaXMuZW5kID0gc2ltcGxlRW5kO1xuICAgICAgcmV0dXJuO1xuICB9XG4gIHRoaXMubGFzdE5lZWQgPSAwO1xuICB0aGlzLmxhc3RUb3RhbCA9IDA7XG4gIHRoaXMubGFzdENoYXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobmIpO1xufVxuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChidWYpIHtcbiAgaWYgKGJ1Zi5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgdmFyIHI7XG4gIHZhciBpO1xuICBpZiAodGhpcy5sYXN0TmVlZCkge1xuICAgIHIgPSB0aGlzLmZpbGxMYXN0KGJ1Zik7XG4gICAgaWYgKHIgPT09IHVuZGVmaW5lZCkgcmV0dXJuICcnO1xuICAgIGkgPSB0aGlzLmxhc3ROZWVkO1xuICAgIHRoaXMubGFzdE5lZWQgPSAwO1xuICB9IGVsc2Uge1xuICAgIGkgPSAwO1xuICB9XG4gIGlmIChpIDwgYnVmLmxlbmd0aCkgcmV0dXJuIHIgPyByICsgdGhpcy50ZXh0KGJ1ZiwgaSkgOiB0aGlzLnRleHQoYnVmLCBpKTtcbiAgcmV0dXJuIHIgfHwgJyc7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQgPSB1dGY4RW5kO1xuXG4vLyBSZXR1cm5zIG9ubHkgY29tcGxldGUgY2hhcmFjdGVycyBpbiBhIEJ1ZmZlclxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUudGV4dCA9IHV0ZjhUZXh0O1xuXG4vLyBBdHRlbXB0cyB0byBjb21wbGV0ZSBhIHBhcnRpYWwgbm9uLVVURi04IGNoYXJhY3RlciB1c2luZyBieXRlcyBmcm9tIGEgQnVmZmVyXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5maWxsTGFzdCA9IGZ1bmN0aW9uIChidWYpIHtcbiAgaWYgKHRoaXMubGFzdE5lZWQgPD0gYnVmLmxlbmd0aCkge1xuICAgIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZCwgMCwgdGhpcy5sYXN0TmVlZCk7XG4gICAgcmV0dXJuIHRoaXMubGFzdENoYXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgdGhpcy5sYXN0VG90YWwpO1xuICB9XG4gIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZCwgMCwgYnVmLmxlbmd0aCk7XG4gIHRoaXMubGFzdE5lZWQgLT0gYnVmLmxlbmd0aDtcbn07XG5cbi8vIENoZWNrcyB0aGUgdHlwZSBvZiBhIFVURi04IGJ5dGUsIHdoZXRoZXIgaXQncyBBU0NJSSwgYSBsZWFkaW5nIGJ5dGUsIG9yIGFcbi8vIGNvbnRpbnVhdGlvbiBieXRlLiBJZiBhbiBpbnZhbGlkIGJ5dGUgaXMgZGV0ZWN0ZWQsIC0yIGlzIHJldHVybmVkLlxuZnVuY3Rpb24gdXRmOENoZWNrQnl0ZShieXRlKSB7XG4gIGlmIChieXRlIDw9IDB4N0YpIHJldHVybiAwO2Vsc2UgaWYgKGJ5dGUgPj4gNSA9PT0gMHgwNikgcmV0dXJuIDI7ZWxzZSBpZiAoYnl0ZSA+PiA0ID09PSAweDBFKSByZXR1cm4gMztlbHNlIGlmIChieXRlID4+IDMgPT09IDB4MUUpIHJldHVybiA0O1xuICByZXR1cm4gYnl0ZSA+PiA2ID09PSAweDAyID8gLTEgOiAtMjtcbn1cblxuLy8gQ2hlY2tzIGF0IG1vc3QgMyBieXRlcyBhdCB0aGUgZW5kIG9mIGEgQnVmZmVyIGluIG9yZGVyIHRvIGRldGVjdCBhblxuLy8gaW5jb21wbGV0ZSBtdWx0aS1ieXRlIFVURi04IGNoYXJhY3Rlci4gVGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyAoMiwgMywgb3IgNClcbi8vIG5lZWRlZCB0byBjb21wbGV0ZSB0aGUgVVRGLTggY2hhcmFjdGVyIChpZiBhcHBsaWNhYmxlKSBhcmUgcmV0dXJuZWQuXG5mdW5jdGlvbiB1dGY4Q2hlY2tJbmNvbXBsZXRlKHNlbGYsIGJ1ZiwgaSkge1xuICB2YXIgaiA9IGJ1Zi5sZW5ndGggLSAxO1xuICBpZiAoaiA8IGkpIHJldHVybiAwO1xuICB2YXIgbmIgPSB1dGY4Q2hlY2tCeXRlKGJ1ZltqXSk7XG4gIGlmIChuYiA+PSAwKSB7XG4gICAgaWYgKG5iID4gMCkgc2VsZi5sYXN0TmVlZCA9IG5iIC0gMTtcbiAgICByZXR1cm4gbmI7XG4gIH1cbiAgaWYgKC0taiA8IGkgfHwgbmIgPT09IC0yKSByZXR1cm4gMDtcbiAgbmIgPSB1dGY4Q2hlY2tCeXRlKGJ1ZltqXSk7XG4gIGlmIChuYiA+PSAwKSB7XG4gICAgaWYgKG5iID4gMCkgc2VsZi5sYXN0TmVlZCA9IG5iIC0gMjtcbiAgICByZXR1cm4gbmI7XG4gIH1cbiAgaWYgKC0taiA8IGkgfHwgbmIgPT09IC0yKSByZXR1cm4gMDtcbiAgbmIgPSB1dGY4Q2hlY2tCeXRlKGJ1ZltqXSk7XG4gIGlmIChuYiA+PSAwKSB7XG4gICAgaWYgKG5iID4gMCkge1xuICAgICAgaWYgKG5iID09PSAyKSBuYiA9IDA7ZWxzZSBzZWxmLmxhc3ROZWVkID0gbmIgLSAzO1xuICAgIH1cbiAgICByZXR1cm4gbmI7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbi8vIFZhbGlkYXRlcyBhcyBtYW55IGNvbnRpbnVhdGlvbiBieXRlcyBmb3IgYSBtdWx0aS1ieXRlIFVURi04IGNoYXJhY3RlciBhc1xuLy8gbmVlZGVkIG9yIGFyZSBhdmFpbGFibGUuIElmIHdlIHNlZSBhIG5vbi1jb250aW51YXRpb24gYnl0ZSB3aGVyZSB3ZSBleHBlY3Rcbi8vIG9uZSwgd2UgXCJyZXBsYWNlXCIgdGhlIHZhbGlkYXRlZCBjb250aW51YXRpb24gYnl0ZXMgd2UndmUgc2VlbiBzbyBmYXIgd2l0aFxuLy8gYSBzaW5nbGUgVVRGLTggcmVwbGFjZW1lbnQgY2hhcmFjdGVyICgnXFx1ZmZmZCcpLCB0byBtYXRjaCB2OCdzIFVURi04IGRlY29kaW5nXG4vLyBiZWhhdmlvci4gVGhlIGNvbnRpbnVhdGlvbiBieXRlIGNoZWNrIGlzIGluY2x1ZGVkIHRocmVlIHRpbWVzIGluIHRoZSBjYXNlXG4vLyB3aGVyZSBhbGwgb2YgdGhlIGNvbnRpbnVhdGlvbiBieXRlcyBmb3IgYSBjaGFyYWN0ZXIgZXhpc3QgaW4gdGhlIHNhbWUgYnVmZmVyLlxuLy8gSXQgaXMgYWxzbyBkb25lIHRoaXMgd2F5IGFzIGEgc2xpZ2h0IHBlcmZvcm1hbmNlIGluY3JlYXNlIGluc3RlYWQgb2YgdXNpbmcgYVxuLy8gbG9vcC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0V4dHJhQnl0ZXMoc2VsZiwgYnVmLCBwKSB7XG4gIGlmICgoYnVmWzBdICYgMHhDMCkgIT09IDB4ODApIHtcbiAgICBzZWxmLmxhc3ROZWVkID0gMDtcbiAgICByZXR1cm4gJ1xcdWZmZmQnO1xuICB9XG4gIGlmIChzZWxmLmxhc3ROZWVkID4gMSAmJiBidWYubGVuZ3RoID4gMSkge1xuICAgIGlmICgoYnVmWzFdICYgMHhDMCkgIT09IDB4ODApIHtcbiAgICAgIHNlbGYubGFzdE5lZWQgPSAxO1xuICAgICAgcmV0dXJuICdcXHVmZmZkJztcbiAgICB9XG4gICAgaWYgKHNlbGYubGFzdE5lZWQgPiAyICYmIGJ1Zi5sZW5ndGggPiAyKSB7XG4gICAgICBpZiAoKGJ1ZlsyXSAmIDB4QzApICE9PSAweDgwKSB7XG4gICAgICAgIHNlbGYubGFzdE5lZWQgPSAyO1xuICAgICAgICByZXR1cm4gJ1xcdWZmZmQnO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vLyBBdHRlbXB0cyB0byBjb21wbGV0ZSBhIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyIHVzaW5nIGJ5dGVzIGZyb20gYSBCdWZmZXIuXG5mdW5jdGlvbiB1dGY4RmlsbExhc3QoYnVmKSB7XG4gIHZhciBwID0gdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkO1xuICB2YXIgciA9IHV0ZjhDaGVja0V4dHJhQnl0ZXModGhpcywgYnVmLCBwKTtcbiAgaWYgKHIgIT09IHVuZGVmaW5lZCkgcmV0dXJuIHI7XG4gIGlmICh0aGlzLmxhc3ROZWVkIDw9IGJ1Zi5sZW5ndGgpIHtcbiAgICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCBwLCAwLCB0aGlzLmxhc3ROZWVkKTtcbiAgICByZXR1cm4gdGhpcy5sYXN0Q2hhci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCB0aGlzLmxhc3RUb3RhbCk7XG4gIH1cbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgcCwgMCwgYnVmLmxlbmd0aCk7XG4gIHRoaXMubGFzdE5lZWQgLT0gYnVmLmxlbmd0aDtcbn1cblxuLy8gUmV0dXJucyBhbGwgY29tcGxldGUgVVRGLTggY2hhcmFjdGVycyBpbiBhIEJ1ZmZlci4gSWYgdGhlIEJ1ZmZlciBlbmRlZCBvbiBhXG4vLyBwYXJ0aWFsIGNoYXJhY3RlciwgdGhlIGNoYXJhY3RlcidzIGJ5dGVzIGFyZSBidWZmZXJlZCB1bnRpbCB0aGUgcmVxdWlyZWRcbi8vIG51bWJlciBvZiBieXRlcyBhcmUgYXZhaWxhYmxlLlxuZnVuY3Rpb24gdXRmOFRleHQoYnVmLCBpKSB7XG4gIHZhciB0b3RhbCA9IHV0ZjhDaGVja0luY29tcGxldGUodGhpcywgYnVmLCBpKTtcbiAgaWYgKCF0aGlzLmxhc3ROZWVkKSByZXR1cm4gYnVmLnRvU3RyaW5nKCd1dGY4JywgaSk7XG4gIHRoaXMubGFzdFRvdGFsID0gdG90YWw7XG4gIHZhciBlbmQgPSBidWYubGVuZ3RoIC0gKHRvdGFsIC0gdGhpcy5sYXN0TmVlZCk7XG4gIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIDAsIGVuZCk7XG4gIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjgnLCBpLCBlbmQpO1xufVxuXG4vLyBGb3IgVVRGLTgsIGEgcmVwbGFjZW1lbnQgY2hhcmFjdGVyIGlzIGFkZGVkIHdoZW4gZW5kaW5nIG9uIGEgcGFydGlhbFxuLy8gY2hhcmFjdGVyLlxuZnVuY3Rpb24gdXRmOEVuZChidWYpIHtcbiAgdmFyIHIgPSBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xuICBpZiAodGhpcy5sYXN0TmVlZCkgcmV0dXJuIHIgKyAnXFx1ZmZmZCc7XG4gIHJldHVybiByO1xufVxuXG4vLyBVVEYtMTZMRSB0eXBpY2FsbHkgbmVlZHMgdHdvIGJ5dGVzIHBlciBjaGFyYWN0ZXIsIGJ1dCBldmVuIGlmIHdlIGhhdmUgYW4gZXZlblxuLy8gbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZSwgd2UgbmVlZCB0byBjaGVjayBpZiB3ZSBlbmQgb24gYSBsZWFkaW5nL2hpZ2hcbi8vIHN1cnJvZ2F0ZS4gSW4gdGhhdCBjYXNlLCB3ZSBuZWVkIHRvIHdhaXQgZm9yIHRoZSBuZXh0IHR3byBieXRlcyBpbiBvcmRlciB0b1xuLy8gZGVjb2RlIHRoZSBsYXN0IGNoYXJhY3RlciBwcm9wZXJseS5cbmZ1bmN0aW9uIHV0ZjE2VGV4dChidWYsIGkpIHtcbiAgaWYgKChidWYubGVuZ3RoIC0gaSkgJSAyID09PSAwKSB7XG4gICAgdmFyIHIgPSBidWYudG9TdHJpbmcoJ3V0ZjE2bGUnLCBpKTtcbiAgICBpZiAocikge1xuICAgICAgdmFyIGMgPSByLmNoYXJDb2RlQXQoci5sZW5ndGggLSAxKTtcbiAgICAgIGlmIChjID49IDB4RDgwMCAmJiBjIDw9IDB4REJGRikge1xuICAgICAgICB0aGlzLmxhc3ROZWVkID0gMjtcbiAgICAgICAgdGhpcy5sYXN0VG90YWwgPSA0O1xuICAgICAgICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAyXTtcbiAgICAgICAgdGhpcy5sYXN0Q2hhclsxXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gICAgICAgIHJldHVybiByLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH1cbiAgdGhpcy5sYXN0TmVlZCA9IDE7XG4gIHRoaXMubGFzdFRvdGFsID0gMjtcbiAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjE2bGUnLCBpLCBidWYubGVuZ3RoIC0gMSk7XG59XG5cbi8vIEZvciBVVEYtMTZMRSB3ZSBkbyBub3QgZXhwbGljaXRseSBhcHBlbmQgc3BlY2lhbCByZXBsYWNlbWVudCBjaGFyYWN0ZXJzIGlmIHdlXG4vLyBlbmQgb24gYSBwYXJ0aWFsIGNoYXJhY3Rlciwgd2Ugc2ltcGx5IGxldCB2OCBoYW5kbGUgdGhhdC5cbmZ1bmN0aW9uIHV0ZjE2RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSB7XG4gICAgdmFyIGVuZCA9IHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZDtcbiAgICByZXR1cm4gciArIHRoaXMubGFzdENoYXIudG9TdHJpbmcoJ3V0ZjE2bGUnLCAwLCBlbmQpO1xuICB9XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBiYXNlNjRUZXh0KGJ1ZiwgaSkge1xuICB2YXIgbiA9IChidWYubGVuZ3RoIC0gaSkgJSAzO1xuICBpZiAobiA9PT0gMCkgcmV0dXJuIGJ1Zi50b1N0cmluZygnYmFzZTY0JywgaSk7XG4gIHRoaXMubGFzdE5lZWQgPSAzIC0gbjtcbiAgdGhpcy5sYXN0VG90YWwgPSAzO1xuICBpZiAobiA9PT0gMSkge1xuICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICB9IGVsc2Uge1xuICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDJdO1xuICAgIHRoaXMubGFzdENoYXJbMV0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICB9XG4gIHJldHVybiBidWYudG9TdHJpbmcoJ2Jhc2U2NCcsIGksIGJ1Zi5sZW5ndGggLSBuKTtcbn1cblxuZnVuY3Rpb24gYmFzZTY0RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSByZXR1cm4gciArIHRoaXMubGFzdENoYXIudG9TdHJpbmcoJ2Jhc2U2NCcsIDAsIDMgLSB0aGlzLmxhc3ROZWVkKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIFBhc3MgYnl0ZXMgb24gdGhyb3VnaCBmb3Igc2luZ2xlLWJ5dGUgZW5jb2RpbmdzIChlLmcuIGFzY2lpLCBsYXRpbjEsIGhleClcbmZ1bmN0aW9uIHNpbXBsZVdyaXRlKGJ1Zikge1xuICByZXR1cm4gYnVmLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiBzaW1wbGVFbmQoYnVmKSB7XG4gIHJldHVybiBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xufSIsInZhciBuZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MvYnJvd3Nlci5qcycpLm5leHRUaWNrO1xudmFyIGFwcGx5ID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGltbWVkaWF0ZUlkcyA9IHt9O1xudmFyIG5leHRJbW1lZGlhdGVJZCA9IDA7XG5cbi8vIERPTSBBUElzLCBmb3IgY29tcGxldGVuZXNzXG5cbmV4cG9ydHMuc2V0VGltZW91dCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRUaW1lb3V0LCB3aW5kb3csIGFyZ3VtZW50cyksIGNsZWFyVGltZW91dCk7XG59O1xuZXhwb3J0cy5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRJbnRlcnZhbCwgd2luZG93LCBhcmd1bWVudHMpLCBjbGVhckludGVydmFsKTtcbn07XG5leHBvcnRzLmNsZWFyVGltZW91dCA9XG5leHBvcnRzLmNsZWFySW50ZXJ2YWwgPSBmdW5jdGlvbih0aW1lb3V0KSB7IHRpbWVvdXQuY2xvc2UoKTsgfTtcblxuZnVuY3Rpb24gVGltZW91dChpZCwgY2xlYXJGbikge1xuICB0aGlzLl9pZCA9IGlkO1xuICB0aGlzLl9jbGVhckZuID0gY2xlYXJGbjtcbn1cblRpbWVvdXQucHJvdG90eXBlLnVucmVmID0gVGltZW91dC5wcm90b3R5cGUucmVmID0gZnVuY3Rpb24oKSB7fTtcblRpbWVvdXQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX2NsZWFyRm4uY2FsbCh3aW5kb3csIHRoaXMuX2lkKTtcbn07XG5cbi8vIERvZXMgbm90IHN0YXJ0IHRoZSB0aW1lLCBqdXN0IHNldHMgdXAgdGhlIG1lbWJlcnMgbmVlZGVkLlxuZXhwb3J0cy5lbnJvbGwgPSBmdW5jdGlvbihpdGVtLCBtc2Vjcykge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gbXNlY3M7XG59O1xuXG5leHBvcnRzLnVuZW5yb2xsID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gLTE7XG59O1xuXG5leHBvcnRzLl91bnJlZkFjdGl2ZSA9IGV4cG9ydHMuYWN0aXZlID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG5cbiAgdmFyIG1zZWNzID0gaXRlbS5faWRsZVRpbWVvdXQ7XG4gIGlmIChtc2VjcyA+PSAwKSB7XG4gICAgaXRlbS5faWRsZVRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgaWYgKGl0ZW0uX29uVGltZW91dClcbiAgICAgICAgaXRlbS5fb25UaW1lb3V0KCk7XG4gICAgfSwgbXNlY3MpO1xuICB9XG59O1xuXG4vLyBUaGF0J3Mgbm90IGhvdyBub2RlLmpzIGltcGxlbWVudHMgaXQgYnV0IHRoZSBleHBvc2VkIGFwaSBpcyB0aGUgc2FtZS5cbmV4cG9ydHMuc2V0SW1tZWRpYXRlID0gdHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gXCJmdW5jdGlvblwiID8gc2V0SW1tZWRpYXRlIDogZnVuY3Rpb24oZm4pIHtcbiAgdmFyIGlkID0gbmV4dEltbWVkaWF0ZUlkKys7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzLmxlbmd0aCA8IDIgPyBmYWxzZSA6IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblxuICBpbW1lZGlhdGVJZHNbaWRdID0gdHJ1ZTtcblxuICBuZXh0VGljayhmdW5jdGlvbiBvbk5leHRUaWNrKCkge1xuICAgIGlmIChpbW1lZGlhdGVJZHNbaWRdKSB7XG4gICAgICAvLyBmbi5jYWxsKCkgaXMgZmFzdGVyIHNvIHdlIG9wdGltaXplIGZvciB0aGUgY29tbW9uIHVzZS1jYXNlXG4gICAgICAvLyBAc2VlIGh0dHA6Ly9qc3BlcmYuY29tL2NhbGwtYXBwbHktc2VndVxuICAgICAgaWYgKGFyZ3MpIHtcbiAgICAgICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmbi5jYWxsKG51bGwpO1xuICAgICAgfVxuICAgICAgLy8gUHJldmVudCBpZHMgZnJvbSBsZWFraW5nXG4gICAgICBleHBvcnRzLmNsZWFySW1tZWRpYXRlKGlkKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBpZDtcbn07XG5cbmV4cG9ydHMuY2xlYXJJbW1lZGlhdGUgPSB0eXBlb2YgY2xlYXJJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIiA/IGNsZWFySW1tZWRpYXRlIDogZnVuY3Rpb24oaWQpIHtcbiAgZGVsZXRlIGltbWVkaWF0ZUlkc1tpZF07XG59OyIsIlxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlcHJlY2F0ZTtcblxuLyoqXG4gKiBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICogUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLm5vRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRocm93RGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgdGhyb3cgYW4gRXJyb3Igd2hlbiBpbnZva2VkLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudHJhY2VEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCBpbnZva2UgYGNvbnNvbGUudHJhY2UoKWAgaW5zdGVhZCBvZiBgY29uc29sZS5lcnJvcigpYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBkZXByZWNhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgLSB0aGUgc3RyaW5nIHRvIHByaW50IHRvIHRoZSBjb25zb2xlIHdoZW4gYGZuYCBpcyBpbnZva2VkXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IGEgbmV3IFwiZGVwcmVjYXRlZFwiIHZlcnNpb24gb2YgYGZuYFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZXByZWNhdGUgKGZuLCBtc2cpIHtcbiAgaWYgKGNvbmZpZygnbm9EZXByZWNhdGlvbicpKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAoY29uZmlnKCd0aHJvd0RlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKGNvbmZpZygndHJhY2VEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgYGxvY2FsU3RvcmFnZWAgZm9yIGJvb2xlYW4gdmFsdWVzIGZvciB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGNvbmZpZyAobmFtZSkge1xuICAvLyBhY2Nlc3NpbmcgZ2xvYmFsLmxvY2FsU3RvcmFnZSBjYW4gdHJpZ2dlciBhIERPTUV4Y2VwdGlvbiBpbiBzYW5kYm94ZWQgaWZyYW1lc1xuICB0cnkge1xuICAgIGlmICghZ2xvYmFsLmxvY2FsU3RvcmFnZSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB2YWwgPSBnbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO1xuICBpZiAobnVsbCA9PSB2YWwpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJztcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNCdWZmZXIoYXJnKSB7XG4gIHJldHVybiBhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ29iamVjdCdcbiAgICAmJiB0eXBlb2YgYXJnLmNvcHkgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLmZpbGwgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLnJlYWRVSW50OCA9PT0gJ2Z1bmN0aW9uJztcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uKGYpIHtcbiAgaWYgKCFpc1N0cmluZyhmKSkge1xuICAgIHZhciBvYmplY3RzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9iamVjdHMucHVzaChpbnNwZWN0KGFyZ3VtZW50c1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0cy5qb2luKCcgJyk7XG4gIH1cblxuICB2YXIgaSA9IDE7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG4gIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uKHgpIHtcbiAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcbiAgICBpZiAoaSA+PSBsZW4pIHJldHVybiB4O1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJXMnOiByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclZCc6IHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVqJzpcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgfSk7XG4gIGZvciAodmFyIHggPSBhcmdzW2ldOyBpIDwgbGVuOyB4ID0gYXJnc1srK2ldKSB7XG4gICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcbiAgICAgIHN0ciArPSAnICcgKyB4O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn07XG5cblxuLy8gTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbi8vIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4vLyBJZiAtLW5vLWRlcHJlY2F0aW9uIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuZXhwb3J0cy5kZXByZWNhdGUgPSBmdW5jdGlvbihmbiwgbXNnKSB7XG4gIC8vIEFsbG93IGZvciBkZXByZWNhdGluZyB0aGluZ3MgaW4gdGhlIHByb2Nlc3Mgb2Ygc3RhcnRpbmcgdXAuXG4gIGlmIChpc1VuZGVmaW5lZChnbG9iYWwucHJvY2VzcykpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZXhwb3J0cy5kZXByZWNhdGUoZm4sIG1zZykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3Mubm9EZXByZWNhdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKHByb2Nlc3MudGhyb3dEZXByZWNhdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy50cmFjZURlcHJlY2F0aW9uKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59O1xuXG5cbnZhciBkZWJ1Z3MgPSB7fTtcbnZhciBkZWJ1Z0Vudmlyb247XG5leHBvcnRzLmRlYnVnbG9nID0gZnVuY3Rpb24oc2V0KSB7XG4gIGlmIChpc1VuZGVmaW5lZChkZWJ1Z0Vudmlyb24pKVxuICAgIGRlYnVnRW52aXJvbiA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgfHwgJyc7XG4gIHNldCA9IHNldC50b1VwcGVyQ2FzZSgpO1xuICBpZiAoIWRlYnVnc1tzZXRdKSB7XG4gICAgaWYgKG5ldyBSZWdFeHAoJ1xcXFxiJyArIHNldCArICdcXFxcYicsICdpJykudGVzdChkZWJ1Z0Vudmlyb24pKSB7XG4gICAgICB2YXIgcGlkID0gcHJvY2Vzcy5waWQ7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbXNnID0gZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignJXMgJWQ6ICVzJywgc2V0LCBwaWQsIG1zZyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge307XG4gICAgfVxuICB9XG4gIHJldHVybiBkZWJ1Z3Nbc2V0XTtcbn07XG5cblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIGFycmF5LmZvckVhY2goZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChrZXlzLmluZGV4T2YoJ21lc3NhZ2UnKSA+PSAwIHx8IGtleXMuaW5kZXhPZignZGVzY3JpcHRpb24nKSA+PSAwKSkge1xuICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgdmFyIG4gPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcbiAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmICghaGFzT3duUHJvcGVydHkodmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGN0eC5zZWVuLmluZGV4T2YoZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IG91dHB1dC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cbmZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXIpO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSByZXF1aXJlKCcuL3N1cHBvcnQvaXNCdWZmZXInKTtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZXhwb3J0cy5fZXh0ZW5kID0gZnVuY3Rpb24ob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZCk7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gIH1cbiAgcmV0dXJuIG9yaWdpbjtcbn07XG5cbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG4iXX0= diff --git a/build/peerplaysjs-lib.min.js b/build/peerplaysjs-lib.min.js new file mode 100644 index 0000000..2af404d --- /dev/null +++ b/build/peerplaysjs-lib.min.js @@ -0,0 +1 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).peerplays_js=e()}}(function(){return function o(s,a,f){function u(t,e){if(!a[t]){if(!s[t]){var r="function"==typeof require&&require;if(!e&&r)return r(t,!0);if(c)return c(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var i=a[t]={exports:{}};s[t][0].call(i.exports,function(e){return u(s[t][1][e]||e)},i,i.exports,o,s,a,f)}return a[t].exports}for(var c="function"==typeof require&&require,e=0;e %s (%d bytes)",o.operation_name,i[1],s,s.length/2)}a.tr_buffer=p.ops.transaction.toBuffer(a)}))})},e.prototype.id=function(){if(!this.tr_buffer)throw new Error("not finalized");return a.hash.sha256(this.tr_buffer).toString("hex").substring(0,40)},e.prototype.add_operation=function(e){if(this.tr_buffer)throw new Error("already finalized");if((0,u.default)(e,"operation"),!Array.isArray(e))throw new Error("Expecting array [operation_id, operation]");this.operations.push(e)},e.prototype.get_type_operation=function(e,t){if(this.tr_buffer)throw new Error("already finalized");(0,u.default)(e,"name"),(0,u.default)(t,"operation");var r=p.ops[e];(0,u.default)(r,"Unknown operation "+e);var n=c.default.operations[r.operation_name];if(void 0===n)throw new Error("unknown operation: "+r.operation_name);if(t.fee||(t.fee={amount:0,asset_id:0}),"proposal_create"===e){var i=!1,o=0;if(t.proposed_ops.forEach(function(e){var t=void 0;switch(e.op[0]){case 0:t="from";break;case 6:case 17:t="account";break;case 10:case 11:case 12:case 13:case 14:case 18:case 43:t="issuer";break;case 15:t="payer";break;case 16:t="from_account";break;case 22:case 23:case 24:t="fee_paying_account";break;case 31:i=!0,o=1123200}t in e.op[1]&&0===e.op[1][t]&&(i=!0)}),!t.expiration_time){var s=this.base_expiration_sec();t.expiration_time=s+l.ChainConfig.expire_in_secs_proposal}if(i){var a=Math.max(this.commitee_min_review,86400,l.ChainConfig.review_in_secs_committee);t.review_period_seconds=o+a,t.expiration_time+=3600+o}}return[n,r.fromObject(t)]},e.prototype.update_head_block=function(){var n=this;return l.Apis.instance().db_api().exec("get_objects",[["2.0.0","2.1.0"]]).then(function(e){var t=e[0],r=e[1];n.head_block_time_string=r[0].time,n.committee_min_review=t[0].parameters.committee_proposal_review_period})},e.prototype.set_expire_seconds=function(e){if(this.tr_buffer)throw new Error("already finalized");return this.expiration=this.base_expiration_sec()+e,this.expiration},e.prototype.propose=function(e){if(this.tr_buffer)throw new Error("already finalized");if(!this.operations.length)throw new Error("add operation first");(0,u.default)(e,"proposal_create_options"),(0,u.default)(e.fee_paying_account,"proposal_create_options.fee_paying_account");var t=this.operations.map(function(e){return{op:e}});return this.operations=[],this.signatures=[],this.signer_private_keys=[],e.proposed_ops=t,this.add_type_operation("proposal_create",e),this},e.prototype.has_proposed_operation=function(){for(var e=!1,t=0;tparseInt(h,10)&&(a=f,u="1.3.0")}var i=[];!function e(t){if(Array.isArray(t))for(var r=0,n=t.length;r>1?s.add(i):s,c=e.pointFromX(f,u),h=c.multiply(i);(0,_.default)(e.isInfinity(h),"nR is not a valid curve point");var l=t.negate().mod(i),p=s.modInverse(i),d=c.multiplyTwo(a,o,l).multiply(p);return e.validate(d),d}r.calcPubKeyRecoveryParam=function(e,t,r,n){for(var i=0;i<4;i++)if(o(e,t,r,i).equals(n))return i;throw new Error("Unable to find valid recovery factor")},r.deterministicGenerateK=d,r.recoverPubKey=o,r.sign=function(r,e,n,t){var i=c.default.fromBuffer(e),o=r.n,s=r.G,a=void 0,f=void 0;d(r,e,n,function(e){var t=s.multiply(e);return!r.isInfinity(t)&&0!==(a=t.affineX.mod(o)).signum()&&0!==(f=e.modInverse(o).multiply(i.add(n.multiply(a))).mod(o)).signum()},t);var u=o.shiftRight(1);return 0i.length;)e.writeUint8(0)}},n.public_key=function(e,t){var r=void 0;if(e)return t?(r=t.toBuffer(),void e.append(r.toString("binary"),"binary")):(r=n.fixed_data(e,33),i.default.fromBuffer(r))},n.ripemd160=function(e,t){if(e)return t?void n.fixed_data(e,20,t):n.fixed_data(e,20)},n.sha256=function(e,t){if(e)return t?void n.fixed_data(e,32,t):n.fixed_data(e,32)},n.time_point_sec=function(e,t){if(!t)return t=e.readInt32(),new Date(1e3*t);t=Math.ceil(t/1e3),e.writeInt32(t)},n}();a.default=r,s.exports=a.default}).call(this,n(35).Buffer)},{11:11,35:35}],21:[function(e,t,r){"use strict";r.__esModule=!0;var n,i="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},o=e(38),s=e(3),a=(n=s)&&n.__esModule?n:{default:n};var f=9007199254740991,u=-9007199254740991,c={is_empty:function(e){return null==e},required:function(e){var t=1>=8;for(;0>=8}for(var s=0;e[s]===c&&s>16&255,o[s++]=t>>8&255,o[s++]=255&t;var u,c;2===i&&(t=h[e.charCodeAt(f)]<<2|h[e.charCodeAt(f+1)]>>4,o[s++]=255&t);1===i&&(t=h[e.charCodeAt(f)]<<10|h[e.charCodeAt(f+1)]<<4|h[e.charCodeAt(f+2)]>>2,o[s++]=t>>8&255,o[s++]=255&t);return o},r.fromByteArray=function(e){for(var t,r=e.length,n=r%3,i=[],o=0,s=r-n;o>2]+a[t<<4&63]+"==")):2===n&&(t=(e[r-2]<<8)+e[r-1],i.push(a[t>>10]+a[t>>4&63]+a[t<<2&63]+"="));return i.join("")};for(var a=[],h=[],l="undefined"!=typeof Uint8Array?Uint8Array:Array,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,o=n.length;i>18&63]+a[i>>12&63]+a[i>>6&63]+a[63&i]);return o.join("")}h["-".charCodeAt(0)]=62,h["_".charCodeAt(0)]=63},{}],30:[function(e,t,r){function b(e,t,r){if(!(this instanceof b))return new b(e,t,r);null!=e&&("number"==typeof e?this.fromNumber(e,t,r):null==t&&"string"!=typeof e?this.fromString(e,256):this.fromString(e,t))}var n=b.prototype;n.__bigi=e(33).version,b.isBigInteger=function(e,t){return e&&e.__bigi&&(!t||e.__bigi===n.__bigi)},b.prototype.am=function(e,t,r,n,i,o){for(;0<=--o;){var s=t*this[e++]+r[n]+i;i=Math.floor(s/67108864),r[n++]=67108863&s}return i},b.prototype.DB=26,b.prototype.DM=67108863;var i=b.prototype.DV=1<<26;b.prototype.FV=Math.pow(2,52),b.prototype.F1=26,b.prototype.F2=0;var o,s,a="0123456789abcdefghijklmnopqrstuvwxyz",f=new Array;for(o="0".charCodeAt(0),s=0;s<=9;++s)f[o++]=s;for(o="a".charCodeAt(0),s=10;s<36;++s)f[o++]=s;for(o="A".charCodeAt(0),s=10;s<36;++s)f[o++]=s;function u(e){return a.charAt(e)}function c(e,t){var r=f[e.charCodeAt(t)];return null==r?-1:r}function g(e){var t=new b;return t.fromInt(e),t}function w(e){var t,r=1;return 0!=(t=e>>>16)&&(e=t,r+=16),0!=(t=e>>8)&&(e=t,r+=8),0!=(t=e>>4)&&(e=t,r+=4),0!=(t=e>>2)&&(e=t,r+=2),0!=(t=e>>1)&&(e=t,r+=1),r}function m(e){this.m=e}function v(e){this.m=e,this.mp=e.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<>=16,t+=16),0==(255&e)&&(e>>=8,t+=8),0==(15&e)&&(e>>=4,t+=4),0==(3&e)&&(e>>=2,t+=2),0==(1&e)&&++t,t}function y(e){for(var t=0;0!=e;)e&=e-1,++t;return t}function E(){}function B(e){return e}function k(e){this.r2=new b,this.q3=new b,b.ONE.dlShiftTo(2*e.t,this.r2),this.mu=this.r2.divide(e),this.m=e}m.prototype.convert=function(e){return e.s<0||0<=e.compareTo(this.m)?e.mod(this.m):e},m.prototype.revert=function(e){return e},m.prototype.reduce=function(e){e.divRemTo(this.m,null,e)},m.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},m.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},v.prototype.convert=function(e){var t=new b;return e.abs().dlShiftTo(this.m.t,t),t.divRemTo(this.m,null,t),e.s<0&&0>15)*this.mpl&this.um)<<15)&e.DM;for(e[r=t+this.m.t]+=this.m.am(0,n,e,t,0,this.m.t);e[r]>=e.DV;)e[r]-=e.DV,e[++r]++}e.clamp(),e.drShiftTo(this.m.t,e),0<=e.compareTo(this.m)&&e.subTo(this.m,e)},v.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},v.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},n.copyTo=function(e){for(var t=this.t-1;0<=t;--t)e[t]=this[t];e.t=this.t,e.s=this.s},n.fromInt=function(e){this.t=1,this.s=e<0?-1:0,0n.DB?(n[n.t-1]|=(a&(1<>n.DB-s):n[n.t-1]|=a<=n.DB&&(s-=n.DB))}8==r&&0!=(128&e[0])&&(n.s=-1,0>o|f,f=(n[r]&s)<=r.t)t.t=0;else{var i=e%r.DB,o=r.DB-i,s=(1<>i;for(var a=n+1;a>i;0>=r.DB;if(e.t>=r.DB;i+=r.s}else{for(i+=r.s;n>=r.DB;i-=e.s}t.s=i<0?-1:0,i<-1?t[n++]=r.DV+i:0=t.DV&&(e[r+t.t]-=t.DV,e[r+t.t+1]=1)}0>n.F2:0),p=n.FV/l,d=(1<>f)&&(o=!0,s=u(n));0<=a;)f>(f+=r.DB-t)):(n=r[a]>>(f-=t)&i,f<=0&&(f+=r.DB,--a)),0>3},n.mod=function(e){var t=new b;return this.abs().divRemTo(e,null,t),this.s<0&&02*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=new b;return e.copyTo(t),this.reduce(t),t},k.prototype.revert=function(e){return e},k.prototype.reduce=function(e){var t=this;for(e.drShiftTo(t.m.t-1,t.r2),e.t>t.m.t+1&&(e.t=t.m.t+1,e.clamp()),t.mu.multiplyUpperTo(t.r2,t.m.t+1,t.q3),t.m.multiplyLowerTo(t.q3,t.m.t+1,t.r2);e.compareTo(t.r2)<0;)e.dAddOffset(1,t.m.t+1);for(e.subTo(t.r2,e);0<=e.compareTo(t.m);)e.subTo(t.m,e)},k.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},k.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)};var T=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],S=(1<<26)/T[T.length-1];n.chunkSize=function(e){return Math.floor(Math.LN2*this.DB/Math.log(e))},n.toRadix=function(e){if(null==e&&(e=10),0==this.signum()||e<2||36=n&&(r.dMultiply(i),r.dAddOffset(a,0),a=s=0))}0e&&n.subTo(b.ONE.shiftLeft(e-1),n);else{var i=new Array,o=7&e;i.length=1+(e>>3),t.nextBytes(i),0>=r.DB;if(e.t>=r.DB;i+=r.s}else{for(i+=r.s;n>=r.DB;i+=e.s}t.s=i<0?-1:0,0=this.DV;)this[t]-=this.DV,++t>=this.t&&(this[this.t++]=0),++this[t]}},n.multiplyLowerTo=function(e,t,r){var n,i=Math.min(this.t+e.t,t);for(r.s=0,r.t=i;0>1)&&(e=T.length);for(var i=new b(null),o=[],s=0;s>24},n.shortValue=function(){return 0==this.t?this.s:this[0]<<16>>16},n.signum=function(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1},n.toByteArray=function(){var e=this,t=e.t,r=new Array;r[0]=e.s;var n,i=e.DB-t*e.DB%8,o=0;if(0>i)!=(e.s&e.DM)>>i&&(r[o++]=n|e.s<>(i+=e.DB-8)):(n=e[t]>>(i-=8)&255,i<=0&&(i+=e.DB,--t)),0!=(128&n)&&(n|=-256),0===o&&(128&e.s)!=(128&n)&&++o,(0=this.t?0!=this.s:0!=(this[t]&1<>i-f&u:(h=(e[p]&(1<>this.DB+i-f)),a=r;0==(1&h);)h>>=1,--a;if((i-=a)<0&&(i+=this.DB,--p),d)s[h].copyTo(o),d=!1;else{for(;1=r())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+r().toString(16)+" bytes");return 0|e}function p(e,t){if(h.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var r=e.length;if(0===r)return 0;for(var n=!1;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return j(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return M(e).length;default:if(n)return j(e).length;t=(""+t).toLowerCase(),n=!0}}function d(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}function _(e,t,r,n,i){if(0===e.length)return-1;if("string"==typeof r?(n=r,r=0):2147483647=e.length){if(i)return-1;r=e.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof t&&(t=h.from(t,n)),h.isBuffer(t))return 0===t.length?-1:g(e,t,r,n,i);if("number"==typeof t)return t&=255,h.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):g(e,[t],r,n,i);throw new TypeError("val must be string, number or Buffer")}function g(e,t,r,n,i){var o,s=1,a=e.length,f=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;a/=s=2,f/=2,r/=2}function u(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){var c=-1;for(o=r;o>>10&1023|55296),c=56320|1023&c),n.push(c),i+=h}return function(e){var t=e.length;if(t<=w)return String.fromCharCode.apply(String,e);var r="",n=0;for(;nthis.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return k(this,t,r);case"utf8":case"utf-8":return b(this,t,r);case"ascii":return E(this,t,r);case"latin1":case"binary":return B(this,t,r);case"base64":return y(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return T(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}.apply(this,arguments)},h.prototype.equals=function(e){if(!h.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===h.compare(this,e)},h.prototype.inspect=function(){var e="",t=q.INSPECT_MAX_BYTES;return 0t&&(e+=" ... ")),""},h.prototype.compare=function(e,t,r,n,i){if(!h.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),t<0||r>e.length||n<0||i>this.length)throw new RangeError("out of range index");if(i<=n&&r<=t)return 0;if(i<=n)return-1;if(r<=t)return 1;if(this===e)return 0;for(var o=(i>>>=0)-(n>>>=0),s=(r>>>=0)-(t>>>=0),a=Math.min(o,s),f=this.slice(n,i),u=e.slice(t,r),c=0;cthis.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var o,s,a,f,u,c,h,l,p,d=!1;;)switch(n){case"hex":return m(this,e,t,r);case"utf8":case"utf-8":return l=t,p=r,D(j(e,(h=this).length-l),h,l,p);case"ascii":return v(this,e,t,r);case"latin1":case"binary":return v(this,e,t,r);case"base64":return f=this,u=t,c=r,D(M(e),f,u,c);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return s=t,a=r,D(function(e,t){for(var r,n,i,o=[],s=0;s>8,i=r%256,o.push(i),o.push(n);return o}(e,(o=this).length-s),o,s,a);default:if(d)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),d=!0}},h.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var w=4096;function E(e,t,r){var n="";r=Math.min(e.length,r);for(var i=t;ie.length)throw new RangeError("Index out of range")}function I(e,t,r,n){t<0&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-r,2);i>>8*(n?i:1-i)}function A(e,t,r,n){t<0&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-r,4);i>>8*(n?i:3-i)&255}function O(e,t,r,n,i,o){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function L(e,t,r,n,i){return i||O(e,0,r,4),o.write(e,t,r,n,23,4),r+4}function C(e,t,r,n,i){return i||O(e,0,r,8),o.write(e,t,r,n,52,8),r+8}h.prototype.slice=function(e,t){var r,n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):n>>8):I(this,e,t,!0),t+2},h.prototype.writeUInt16BE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,2,65535,0),h.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):I(this,e,t,!1),t+2},h.prototype.writeUInt32LE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,4,4294967295,0),h.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):A(this,e,t,!0),t+4},h.prototype.writeUInt32BE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,4,4294967295,0),h.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},h.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t|=0,!n){var i=Math.pow(2,8*r-1);x(this,e,t,r,i-1,-i)}var o=0,s=1,a=0;for(this[t]=255&e;++o>0)-a&255;return t+r},h.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t|=0,!n){var i=Math.pow(2,8*r-1);x(this,e,t,r,i-1,-i)}var o=r-1,s=1,a=0;for(this[t+o]=255&e;0<=--o&&(s*=256);)e<0&&0===a&&0!==this[t+o+1]&&(a=1),this[t+o]=(e/s>>0)-a&255;return t+r},h.prototype.writeInt8=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,1,127,-128),h.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},h.prototype.writeInt16LE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,2,32767,-32768),h.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):I(this,e,t,!0),t+2},h.prototype.writeInt16BE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,2,32767,-32768),h.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):I(this,e,t,!1),t+2},h.prototype.writeInt32LE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,4,2147483647,-2147483648),h.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):A(this,e,t,!0),t+4},h.prototype.writeInt32BE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),h.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},h.prototype.writeFloatLE=function(e,t,r){return L(this,e,t,!0,r)},h.prototype.writeFloatBE=function(e,t,r){return L(this,e,t,!1,r)},h.prototype.writeDoubleLE=function(e,t,r){return C(this,e,t,!0,r)},h.prototype.writeDoubleBE=function(e,t,r){return C(this,e,t,!1,r)},h.prototype.copy=function(e,t,r,n){if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),0=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(o=t;o>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return o}function M(e){return n.toByteArray(function(e){var t;if((e=(t=e,t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")).replace(R,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function D(e,t,r,n){for(var i=0;i=t.length||i>=e.length);++i)t[i+r]=e[i];return i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{29:29,64:64,67:67}],36:[function(e,t,r){var n=e(35).Buffer,i=n.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};var o=r.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!i(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=a;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=f;break;default:return void(this.write=s)}this.charBuffer=new n(6),this.charReceived=0,this.charLength=0};function s(e){return e.toString(this.encoding)}function a(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function f(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}o.prototype.write=function(e){for(var t="";this.charLength;){var r=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,r),this.charReceived+=r,this.charReceived>5==6){this.charLength=2;break}if(t<=2&&r>>4==14){this.charLength=3;break}if(t<=3&&r>>3==30){this.charLength=4;break}}this.charReceived=t},o.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var r=this.charReceived,n=this.charBuffer,i=this.encoding;t+=n.slice(0,r).toString(i)}return t}},{35:35}],37:[function(e,t,r){var n=e(28);t.exports=n("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")},{28:28}],38:[function(t,e,r){var n,i;n=this,i=function(f){"use strict";var d=function(e,t,r){if(void 0===e&&(e=d.DEFAULT_CAPACITY),void 0===t&&(t=d.DEFAULT_ENDIAN),void 0===r&&(r=d.DEFAULT_NOASSERT),!r){if((e|=0)<0)throw RangeError("Illegal capacity");t=!!t,r=!!r}this.buffer=0===e?o:new ArrayBuffer(e),this.view=0===e?null:new Uint8Array(this.buffer),this.offset=0,this.markedOffset=-1,this.limit=e,this.littleEndian=t,this.noAssert=r};d.VERSION="5.0.1",d.LITTLE_ENDIAN=!0,d.BIG_ENDIAN=!1,d.DEFAULT_CAPACITY=16,d.DEFAULT_ENDIAN=d.BIG_ENDIAN,d.DEFAULT_NOASSERT=!1,d.Long=f||null;var s=d.prototype;s.__isByteBuffer__,Object.defineProperty(s,"__isByteBuffer__",{value:!0,enumerable:!1,configurable:!1});var o=new ArrayBuffer(0),r=String.fromCharCode;function a(e){var t=0;return function(){return t>1,c=-7,h=r?i-1:0,l=r?-1:1,p=e[t+h];for(h+=l,o=p&(1<<-c)-1,p>>=-c,c+=a;0>=-c,c+=n;0>1,l=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:o-1,d=n?1:-1,_=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=c):(s=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-s))<1&&(s--,f*=2),2<=(t+=1<=s+h?l/f:l*Math.pow(2,1-h))*f&&(s++,f/=2),c<=s+h?(a=0,s=c):1<=s+h?(a=(t*f-1)*Math.pow(2,i),s+=h):(a=t*Math.pow(2,h-1)*Math.pow(2,i),s=0));8<=i;e[r+p]=255&a,p+=d,a/=256,i-=8);for(s=s<>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i=t,o=e.length,s=o>>3,a=0;for(t+=this.writeVarint32(o,t);s--;)n=1&!!e[a++]|(1&!!e[a++])<<1|(1&!!e[a++])<<2|(1&!!e[a++])<<3|(1&!!e[a++])<<4|(1&!!e[a++])<<5|(1&!!e[a++])<<6|(1&!!e[a++])<<7,this.writeByte(n,t++);if(a>3,s=0,a=[];for(e+=n.length;o--;)r=this.readByte(e++),a[s++]=!!(1&r),a[s++]=!!(2&r),a[s++]=!!(4&r),a[s++]=!!(8&r),a[s++]=!!(16&r),a[s++]=!!(32&r),a[s++]=!!(64&r),a[s++]=!!(128&r);if(s>f++&1)}return t&&(this.offset=e),a},s.readBytes=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+e>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+"+e+") <= "+this.buffer.byteLength)}var n=this.slice(t,t+e);return r&&(this.offset+=e),n},s.writeBytes=s.append,s.writeInt8=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var n=this.buffer.byteLength;return nt?n:t),t-=1,this.view[t]=e,r&&(this.offset+=1),this},s.writeByte=s.writeInt8,s.readInt8=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=this.view[e];return 128==(128&r)&&(r=-(255-r+1)),t&&(this.offset+=1),r},s.readByte=s.readInt8,s.writeUint8=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var n=this.buffer.byteLength;return nt?n:t),t-=1,this.view[t]=e,r&&(this.offset+=1),this},s.writeUInt8=s.writeUint8,s.readUint8=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=this.view[e];return t&&(this.offset+=1),r},s.readUInt8=s.readUint8,s.writeInt16=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var n=this.buffer.byteLength;return nt?n:t),t-=2,this.littleEndian?(this.view[t+1]=(65280&e)>>>8,this.view[t]=255&e):(this.view[t]=(65280&e)>>>8,this.view[t+1]=255&e),r&&(this.offset+=2),this},s.writeShort=s.writeInt16,s.readInt16=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e],r|=this.view[e+1]<<8):(r=this.view[e]<<8,r|=this.view[e+1]),32768==(32768&r)&&(r=-(65535-r+1)),t&&(this.offset+=2),r},s.readShort=s.readInt16,s.writeUint16=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var n=this.buffer.byteLength;return nt?n:t),t-=2,this.littleEndian?(this.view[t+1]=(65280&e)>>>8,this.view[t]=255&e):(this.view[t]=(65280&e)>>>8,this.view[t+1]=255&e),r&&(this.offset+=2),this},s.writeUInt16=s.writeUint16,s.readUint16=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e],r|=this.view[e+1]<<8):(r=this.view[e]<<8,r|=this.view[e+1]),t&&(this.offset+=2),r},s.readUInt16=s.readUint16,s.writeInt32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var n=this.buffer.byteLength;return nt?n:t),t-=4,this.littleEndian?(this.view[t+3]=e>>>24&255,this.view[t+2]=e>>>16&255,this.view[t+1]=e>>>8&255,this.view[t]=255&e):(this.view[t]=e>>>24&255,this.view[t+1]=e>>>16&255,this.view[t+2]=e>>>8&255,this.view[t+3]=255&e),r&&(this.offset+=4),this},s.writeInt=s.writeInt32,s.readInt32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0):(r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0),r|=0,t&&(this.offset+=4),r},s.readInt=s.readInt32,s.writeUint32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var n=this.buffer.byteLength;return nt?n:t),t-=4,this.littleEndian?(this.view[t+3]=e>>>24&255,this.view[t+2]=e>>>16&255,this.view[t+1]=e>>>8&255,this.view[t]=255&e):(this.view[t]=e>>>24&255,this.view[t+1]=e>>>16&255,this.view[t+2]=e>>>8&255,this.view[t+3]=255&e),r&&(this.offset+=4),this},s.writeUInt32=s.writeUint32,s.readUint32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0):(r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0),t&&(this.offset+=4),r},s.readUInt32=s.readUint32,f&&(s.writeInt64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e)),t+=8;var n=this.buffer.byteLength;nt?n:t),t-=8;var i=e.low,o=e.high;return this.littleEndian?(this.view[t+3]=i>>>24&255,this.view[t+2]=i>>>16&255,this.view[t+1]=i>>>8&255,this.view[t]=255&i,t+=4,this.view[t+3]=o>>>24&255,this.view[t+2]=o>>>16&255,this.view[t+1]=o>>>8&255,this.view[t]=255&o):(this.view[t]=o>>>24&255,this.view[t+1]=o>>>16&255,this.view[t+2]=o>>>8&255,this.view[t+3]=255&o,t+=4,this.view[t]=i>>>24&255,this.view[t+1]=i>>>16&255,this.view[t+2]=i>>>8&255,this.view[t+3]=255&i),r&&(this.offset+=8),this},s.writeLong=s.writeInt64,s.readInt64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=0,n=0;this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0,e+=4,n=this.view[e+2]<<16,n|=this.view[e+1]<<8,n|=this.view[e],n+=this.view[e+3]<<24>>>0):(n=this.view[e+1]<<16,n|=this.view[e+2]<<8,n|=this.view[e+3],n+=this.view[e]<<24>>>0,e+=4,r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0);var i=new f(r,n,!1);return t&&(this.offset+=8),i},s.readLong=s.readInt64,s.writeUint64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e)),t+=8;var n=this.buffer.byteLength;nt?n:t),t-=8;var i=e.low,o=e.high;return this.littleEndian?(this.view[t+3]=i>>>24&255,this.view[t+2]=i>>>16&255,this.view[t+1]=i>>>8&255,this.view[t]=255&i,t+=4,this.view[t+3]=o>>>24&255,this.view[t+2]=o>>>16&255,this.view[t+1]=o>>>8&255,this.view[t]=255&o):(this.view[t]=o>>>24&255,this.view[t+1]=o>>>16&255,this.view[t+2]=o>>>8&255,this.view[t+3]=255&o,t+=4,this.view[t]=i>>>24&255,this.view[t+1]=i>>>16&255,this.view[t+2]=i>>>8&255,this.view[t+3]=255&i),r&&(this.offset+=8),this},s.writeUInt64=s.writeUint64,s.readUint64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=0,n=0;this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0,e+=4,n=this.view[e+2]<<16,n|=this.view[e+1]<<8,n|=this.view[e],n+=this.view[e+3]<<24>>>0):(n=this.view[e+1]<<16,n|=this.view[e+2]<<8,n|=this.view[e+3],n+=this.view[e]<<24>>>0,e+=4,r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0);var i=new f(r,n,!0);return t&&(this.offset+=8),i},s.readUInt64=s.readUint64),s.writeFloat32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var n=this.buffer.byteLength;return nt?n:t),t-=4,i(this.view,e,t,this.littleEndian,23,4),r&&(this.offset+=4),this},s.writeFloat=s.writeFloat32,s.readFloat32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=n(this.view,e,this.littleEndian,23,4);return t&&(this.offset+=4),r},s.readFloat=s.readFloat32,s.writeFloat64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=8;var n=this.buffer.byteLength;return nt?n:t),t-=8,i(this.view,e,t,this.littleEndian,52,8),r&&(this.offset+=8),this},s.writeDouble=s.writeFloat64,s.readFloat64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=n(this.view,e,this.littleEndian,52,8);return t&&(this.offset+=8),r},s.readDouble=s.readFloat64,d.MAX_VARINT32_BYTES=5,d.calculateVarint32=function(e){return(e>>>=0)<128?1:e<16384?2:e<1<<21?3:e<1<<28?4:5},d.zigZagEncode32=function(e){return((e|=0)<<1^e>>31)>>>0},d.zigZagDecode32=function(e){return e>>>1^-(1&e)|0},s.writeVarint32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i=d.calculateVarint32(e);t+=i;var o=this.buffer.byteLength;for(ot?o:t),t-=i,e>>>=0;128<=e;)n=127&e|128,this.view[t++]=n,e>>>=7;return this.view[t++]=e,r?(this.offset=t,this):i},s.writeVarint32ZigZag=function(e,t){return this.writeVarint32(d.zigZagEncode32(e),t)},s.readVarint32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,n=0,i=0;do{if(!this.noAssert&&e>this.limit){var o=Error("Truncated");throw o.truncated=!0,o}r=this.view[e++],n<5&&(i|=(127&r)<<7*n),++n}while(0!=(128&r));return i|=0,t?(this.offset=e,i):{value:i,length:n}},s.readVarint32ZigZag=function(e){var t=this.readVarint32(e);return"object"==typeof t?t.value=d.zigZagDecode32(t.value):t=d.zigZagDecode32(t),t},f&&(d.MAX_VARINT64_BYTES=10,d.calculateVarint64=function(e){"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e));var t=e.toInt()>>>0,r=e.shiftRightUnsigned(28).toInt()>>>0,n=e.shiftRightUnsigned(56).toInt()>>>0;return 0==n?0==r?t<16384?t<128?1:2:t<1<<21?3:4:r<16384?r<128?5:6:r<1<<21?7:8:n<128?9:10},d.zigZagEncode64=function(e){return"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftLeft(1).xor(e.shiftRight(63)).toUnsigned()},d.zigZagDecode64=function(e){return"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftRightUnsigned(1).xor(e.and(f.ONE).toSigned().negate()).toSigned()},s.writeVarint64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned());var n=d.calculateVarint64(e),i=e.toInt()>>>0,o=e.shiftRightUnsigned(28).toInt()>>>0,s=e.shiftRightUnsigned(56).toInt()>>>0;t+=n;var a=this.buffer.byteLength;switch(at?a:t),t-=n,n){case 10:this.view[t+9]=s>>>7&1;case 9:this.view[t+8]=9!==n?128|s:127&s;case 8:this.view[t+7]=8!==n?o>>>21|128:o>>>21&127;case 7:this.view[t+6]=7!==n?o>>>14|128:o>>>14&127;case 6:this.view[t+5]=6!==n?o>>>7|128:o>>>7&127;case 5:this.view[t+4]=5!==n?128|o:127&o;case 4:this.view[t+3]=4!==n?i>>>21|128:i>>>21&127;case 3:this.view[t+2]=3!==n?i>>>14|128:i>>>14&127;case 2:this.view[t+1]=2!==n?i>>>7|128:i>>>7&127;case 1:this.view[t]=1!==n?128|i:127&i}return r?(this.offset+=n,this):n},s.writeVarint64ZigZag=function(e,t){return this.writeVarint64(d.zigZagEncode64(e),t)},s.readVarint64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=e,n=0,i=0,o=0,s=0;if(n=127&(s=this.view[e++]),128&s&&(n|=(127&(s=this.view[e++]))<<7,(128&s||this.noAssert&&void 0===s)&&(n|=(127&(s=this.view[e++]))<<14,(128&s||this.noAssert&&void 0===s)&&(n|=(127&(s=this.view[e++]))<<21,(128&s||this.noAssert&&void 0===s)&&(i=127&(s=this.view[e++]),(128&s||this.noAssert&&void 0===s)&&(i|=(127&(s=this.view[e++]))<<7,(128&s||this.noAssert&&void 0===s)&&(i|=(127&(s=this.view[e++]))<<14,(128&s||this.noAssert&&void 0===s)&&(i|=(127&(s=this.view[e++]))<<21,(128&s||this.noAssert&&void 0===s)&&(o=127&(s=this.view[e++]),(128&s||this.noAssert&&void 0===s)&&(o|=(127&(s=this.view[e++]))<<7,128&s||this.noAssert&&void 0===s))))))))))throw Error("Buffer overrun");var a=f.fromBits(n|i<<28,i>>>4|o<<24,!1);return t?(this.offset=e,a):{value:a,length:e-r}},s.readVarint64ZigZag=function(e){var t=this.readVarint64(e);return t&&t.value instanceof f?t.value=d.zigZagDecode64(t.value):t=d.zigZagDecode64(t),t}),s.writeCString=function(e,t){var r=void 0===t;r&&(t=this.offset);var n,i=e.length;if(!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");for(n=0;n>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}i=l.calculateUTF16asUTF8(a(e))[1],t+=i+1;var o=this.buffer.byteLength;return ot?o:t),t-=i+1,l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),this.view[t++]=0,r?(this.offset=t,this):i},s.readCString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,n=e,i=-1;return l.decodeUTF8toUTF16(function(){if(0===i)return null;if(e>=this.limit)throw RangeError("Illegal range: Truncated data, "+e+" < "+this.limit);return 0===(i=this.view[e++])?null:i}.bind(this),r=u(),!0),t?(this.offset=e,r()):{string:r(),length:e-n}},s.writeIString=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i=t;n=l.calculateUTF16asUTF8(a(e),this.noAssert)[1],t+=4+n;var o=this.buffer.byteLength;if(ot?o:t),t-=4+n,this.littleEndian?(this.view[t+3]=n>>>24&255,this.view[t+2]=n>>>16&255,this.view[t+1]=n>>>8&255,this.view[t]=255&n):(this.view[t]=n>>>24&255,this.view[t+1]=n>>>16&255,this.view[t+2]=n>>>8&255,this.view[t+3]=255&n),t+=4,l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),t!==i+4+n)throw RangeError("Illegal range: Truncated data, "+t+" == "+(t+4+n));return r?(this.offset=t,this):t-i},s.readIString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=e,n=this.readUint32(e),i=this.readUTF8String(n,d.METRICS_BYTES,e+=4);return e+=i.length,t?(this.offset=e,i.string):{string:i.string,length:e-r}},d.METRICS_CHARS="c",d.METRICS_BYTES="b",s.writeUTF8String=function(e,t){var r,n=void 0===t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var i=t;r=l.calculateUTF16asUTF8(a(e))[1],t+=r;var o=this.buffer.byteLength;return ot?o:t),t-=r,l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),n?(this.offset=t,this):t-i},s.writeString=s.writeUTF8String,d.calculateUTF8Chars=function(e){return l.calculateUTF16asUTF8(a(e))[0]},d.calculateUTF8Bytes=function(e){return l.calculateUTF16asUTF8(a(e))[1]},d.calculateString=d.calculateUTF8Bytes,s.readUTF8String=function(e,t,r){"number"==typeof t&&(r=t,t=void 0);var n=void 0===r;if(n&&(r=this.offset),void 0===t&&(t=d.METRICS_CHARS),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal length: "+e+" (not an integer)");if(e|=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}var i,o=0,s=r;if(t===d.METRICS_CHARS){if(i=u(),l.decodeUTF8(function(){return o>>=0)<0||r+e>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+"+e+") <= "+this.buffer.byteLength)}var a=r+e;if(l.decodeUTF8toUTF16(function(){return r>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i,o=t;n=l.calculateUTF16asUTF8(a(e),this.noAssert)[1],i=d.calculateVarint32(n),t+=i+n;var s=this.buffer.byteLength;if(st?s:t),t-=i+n,t+=this.writeVarint32(n,t),l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),t!==o+n+i)throw RangeError("Illegal range: Truncated data, "+t+" == "+(t+n+i));return r?(this.offset=t,this):t-o},s.readVString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=e,n=this.readVarint32(e),i=this.readUTF8String(n.value,d.METRICS_BYTES,e+=n.length);return e+=i.length,t?(this.offset=e,i.string):{string:i.string,length:e-r}},s.append=function(e,t,r){"number"!=typeof t&&"string"==typeof t||(r=t,t=void 0);var n=void 0===r;if(n&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}e instanceof d||(e=d.wrap(e,t));var i=e.limit-e.offset;if(i<=0)return this;r+=i;var o=this.buffer.byteLength;return or?o:r),r-=i,this.view.set(e.view.subarray(e.offset,e.limit),r),e.offset+=i,n&&(this.offset+=i),this},s.appendTo=function(e,t){return e.append(this,t),this},s.assert=function(e){return this.noAssert=!e,this},s.capacity=function(){return this.buffer.byteLength},s.clear=function(){return this.offset=0,this.limit=this.buffer.byteLength,this.markedOffset=-1,this},s.clone=function(e){var t=new d(0,this.littleEndian,this.noAssert);return t.view=e?(t.buffer=new ArrayBuffer(this.buffer.byteLength),new Uint8Array(t.buffer)):(t.buffer=this.buffer,this.view),t.offset=this.offset,t.markedOffset=this.markedOffset,t.limit=this.limit,t},s.compact=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(0===e&&t===this.buffer.byteLength)return this;var r=t-e;if(0===r)return this.buffer=o,this.view=null,0<=this.markedOffset&&(this.markedOffset-=e),this.offset=0,this.limit=0,this;var n=new ArrayBuffer(r),i=new Uint8Array(n);return i.set(this.view.subarray(e,t)),this.buffer=n,this.view=i,0<=this.markedOffset&&(this.markedOffset-=e),this.offset=0,this.limit=r,this},s.copy=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(e===t)return new d(0,this.littleEndian,this.noAssert);var r=t-e,n=new d(r,this.littleEndian,this.noAssert);return n.offset=0,n.limit=r,0<=n.markedOffset&&(n.markedOffset-=e),this.copyTo(n,0,e,t),n},s.copyTo=function(e,t,r,n){var i,o;if(!this.noAssert&&!d.isByteBuffer(e))throw TypeError("Illegal target: Not a ByteBuffer");if(t=(o=void 0===t)?e.offset:0|t,r=(i=void 0===r)?this.offset:0|r,n=void 0===n?this.limit:0|n,t<0||t>e.buffer.byteLength)throw RangeError("Illegal target range: 0 <= "+t+" <= "+e.buffer.byteLength);if(r<0||n>this.buffer.byteLength)throw RangeError("Illegal source range: 0 <= "+r+" <= "+this.buffer.byteLength);var s=n-r;return 0===s?e:(e.ensureCapacity(t+s),e.view.set(this.view.subarray(r,n),t),i&&(this.offset+=s),o&&(e.offset+=s),this)},s.ensureCapacity=function(e){var t=this.buffer.byteLength;return te?t:e):this},s.fill=function(e,t,r){var n=void 0===t;if(n&&(t=this.offset),"string"==typeof e&&0>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal end: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}if(r<=t)return this;for(;t>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}return this.markedOffset=e,this},s.order=function(e){if(!this.noAssert&&"boolean"!=typeof e)throw TypeError("Illegal littleEndian: Not a boolean");return this.littleEndian=!!e,this},s.LE=function(e){return this.littleEndian=void 0===e||!!e,this},s.BE=function(e){return this.littleEndian=void 0!==e&&!e,this},s.prepend=function(e,t,r){"number"!=typeof t&&"string"==typeof t||(r=t,t=void 0);var n=void 0===r;if(n&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}e instanceof d||(e=d.wrap(e,t));var i=e.limit-e.offset;if(i<=0)return this;var o=i-r;if(0>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}return e===t||Array.prototype.reverse.call(this.view.subarray(e,t)),this},s.skip=function(e){if(!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal length: "+e+" (not an integer)");e|=0}var t=this.offset+e;if(!this.noAssert&&(t<0||t>this.buffer.byteLength))throw RangeError("Illegal length: 0 <= "+this.offset+" + "+e+" <= "+this.buffer.byteLength);return this.offset=t,this},s.slice=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}var r=this.clone();return r.offset=e,r.limit=t,r},s.toBuffer=function(e){var t=this.offset,r=this.limit;if(!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: Not an integer");if(t>>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal limit: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}if(!e&&0===t&&r===this.buffer.byteLength)return this.buffer;if(t===r)return o;var n=new ArrayBuffer(r-t);return new Uint8Array(n).set(new Uint8Array(this.buffer).subarray(t,r),0),n},s.toArrayBuffer=s.toBuffer,s.toString=function(e,t,r){if(void 0===e)return"ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";switch("number"==typeof e&&(r=t=e="utf8"),e){case"utf8":return this.toUTF8(t,r);case"base64":return this.toBase64(t,r);case"hex":return this.toHex(t,r);case"binary":return this.toBinary(t,r);case"debug":return this.toDebug();case"columns":return this.toColumns();default:throw Error("Unsupported encoding: "+e)}};var c=function(){for(var e={},i=[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47],s=[],t=0,r=i.length;t>2&63]),n=(3&r)<<4,null!==(r=e())?(t(i[63&((n|=r>>4&15)|r>>4&15)]),n=(15&r)<<2,null!==(r=e())?(t(i[63&(n|r>>6&3)]),t(i[63&r])):(t(i[63&n]),t(61))):(t(i[63&n]),t(61),t(61))},e.decode=function(e,t){var r,n,i;function o(e){throw Error("Illegal character code: "+e)}for(;null!==(r=e());)if(void 0===(n=s[r])&&o(r),null!==(r=e())&&(void 0===(i=s[r])&&o(r),t(n<<2>>>0|(48&i)>>4),null!==(r=e()))){if(void 0===(n=s[r])){if(61===r)break;o(r)}if(t((15&i)<<4>>>0|(60&n)>>2),null!==(r=e())){if(void 0===(i=s[r])){if(61===r)break;o(r)}t((3&n)<<6>>>0|i)}}},e.test=function(e){return/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e)},e}();s.toBase64=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),t|=0,(e|=0)<0||t>this.capacity||tthis.capacity()||t":i+=r===this.markedOffset?"'":e||0!==r&&r!==n?" ":""}if(e&&" "!==i){for(;i.length<51;)i+=" ";s+=i+o+"\n"}return e?s:i},d.fromDebug=function(e,t,r){for(var n,i,o=e.length,s=new d((o+1)/3|0,t,r),a=0,f=0,u=!1,c=!1,h=!1,l=!1,p=!1;a":if(!r){if(l){p=!0;break}l=!0}s.limit=f,u=!1;break;case"'":if(!r){if(h){p=!0;break}h=!0}s.markedOffset=f,u=!1;break;case" ":u=!1;break;default:if(!r&&u){p=!0;break}if(i=parseInt(n+e.charAt(a++),16),!r&&(isNaN(i)||i<0||255>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}for(var r,n=new Array(t-e);e>6&31|192):(r<65536?t(r>>12&15|224):(t(r>>18&7|240),t(r>>12&63|128)),t(r>>6&63|128)),t(63&r|128)),r=null},decodeUTF8:function(e,t){for(var r,n,i,o,s=function(e){e=e.slice(0,e.indexOf(null));var t=Error(e.toString());throw t.name="TruncatedError",t.bytes=e,t};null!==(r=e());)if(0==(128&r))t(r);else if(192==(224&r))null===(n=e())&&s([r,n]),t((31&r)<<6|63&n);else if(224==(240&r))(null===(n=e())||null===(i=e()))&&s([r,n,i]),t((15&r)<<12|(63&n)<<6|63&i);else{if(240!=(248&r))throw RangeError("Illegal starting byte: "+r);(null===(n=e())||null===(i=e())||null===(o=e()))&&s([r,n,i,o]),t((7&r)<<18|(63&n)<<12|(63&i)<<6|63&o)}},UTF16toUTF8:function(e,t){for(var r,n=null;null!==(r=null!==n?n:e());)55296<=r&&r<=57343&&null!==(n=e())&&56320<=n&&n<=57343?(t(1024*(r-55296)+n-56320+65536),n=null):t(r);null!==n&&t(n)},UTF8toUTF16:function(e,t){var r=null;for("number"==typeof e&&(r=e,e=function(){return null});null!==r||null!==(r=e());)r<=65535?t(r):(t(55296+((r-=65536)>>10)),t(r%1024+56320)),r=null},encodeUTF16toUTF8:function(e,t){h.UTF16toUTF8(e,function(e){h.encodeUTF8(e,t)})},decodeUTF8toUTF16:function(e,t){h.decodeUTF8(e,function(e){h.UTF8toUTF16(e,t)})},calculateCodePoint:function(e){return e<128?1:e<2048?2:e<65536?3:4},calculateUTF8:function(e){for(var t,r=0;null!==(t=e());)r+=t<128?1:t<2048?2:t<65536?3:4;return r},calculateUTF16asUTF8:function(e){var t=0,r=0;return h.UTF16toUTF8(e,function(e){++t,r+=e<128?1:e<2048?2:e<65536?3:4}),[t,r]}};return s.toUTF8=function(t,r){if(void 0===t&&(t=this.offset),void 0===r&&(r=this.limit),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal begin: Not an integer");if(t>>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal end: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}var e;try{l.decodeUTF8toUTF16(function(){return tr)?t=("rmd160"===e?new f:u(e)).update(t).digest():t.length>>8^255&i^99,u[r]=i;var o=e[c[i]=r],s=e[o],a=e[s],f=257*e[i]^16843008*i;h[r]=f<<24|f>>>8,l[r]=f<<16|f>>>16,p[r]=f<<8|f>>>24,d[r]=f;f=16843009*a^65537*s^257*o^16843008*r;_[i]=f<<24|f>>>8,g[i]=f<<16|f>>>16,m[i]=f<<8|f>>>24,v[i]=f,r?(r=o^e[e[e[a^o]]],n^=e[e[n]]):r=n=1}}();var y=[0,1,2,4,8,16,32,64,128,27,54],n=r.AES=t.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var e=this._keyPriorReset=this._key,t=e.words,r=e.sigBytes/4,n=4*((this._nRounds=r+6)+1),i=this._keySchedule=[],o=0;o>>24]<<24|u[s>>>16&255]<<16|u[s>>>8&255]<<8|u[255&s]):(s=u[(s=s<<8|s>>>24)>>>24]<<24|u[s>>>16&255]<<16|u[s>>>8&255]<<8|u[255&s],s^=y[o/r|0]<<24),i[o]=i[o-r]^s}for(var a=this._invKeySchedule=[],f=0;f>>24]]^g[u[s>>>16&255]]^m[u[s>>>8&255]]^v[u[255&s]]}}},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,h,l,p,d,u)},decryptBlock:function(e,t){var r=e[t+1];e[t+1]=e[t+3],e[t+3]=r,this._doCryptBlock(e,t,this._invKeySchedule,_,g,m,v,c);r=e[t+1];e[t+1]=e[t+3],e[t+3]=r},_doCryptBlock:function(e,t,r,n,i,o,s,a){for(var f=this._nRounds,u=e[t]^r[0],c=e[t+1]^r[1],h=e[t+2]^r[2],l=e[t+3]^r[3],p=4,d=1;d>>24]^i[c>>>16&255]^o[h>>>8&255]^s[255&l]^r[p++],g=n[c>>>24]^i[h>>>16&255]^o[l>>>8&255]^s[255&u]^r[p++],m=n[h>>>24]^i[l>>>16&255]^o[u>>>8&255]^s[255&c]^r[p++],v=n[l>>>24]^i[u>>>16&255]^o[c>>>8&255]^s[255&h]^r[p++];u=_,c=g,h=m,l=v}_=(a[u>>>24]<<24|a[c>>>16&255]<<16|a[h>>>8&255]<<8|a[255&l])^r[p++],g=(a[c>>>24]<<24|a[h>>>16&255]<<16|a[l>>>8&255]<<8|a[255&u])^r[p++],m=(a[h>>>24]<<24|a[l>>>16&255]<<16|a[u>>>8&255]<<8|a[255&c])^r[p++],v=(a[l>>>24]<<24|a[u>>>16&255]<<16|a[c>>>8&255]<<8|a[255&h])^r[p++];e[t]=_,e[t+1]=g,e[t+2]=m,e[t+3]=v},keySize:8});e.AES=t._createHelper(n)}(),i.AES},"object"==typeof r?t.exports=r=i(e(47),e(48),e(52),e(50),e(46)):i(n.CryptoJS)},{46:46,47:47,48:48,50:50,52:52}],46:[function(e,t,r){var n,i;n=this,i=function(e){var t,r,n,f,i,o,s,a,u,c,h,l,p,d,_,g,m,v;e.lib.Cipher||(r=(t=e).lib,n=r.Base,f=r.WordArray,i=r.BufferedBlockAlgorithm,(o=t.enc).Utf8,s=o.Base64,a=t.algo.EvpKDF,u=r.Cipher=i.extend({cfg:n.extend(),createEncryptor:function(e,t){return this.create(this._ENC_XFORM_MODE,e,t)},createDecryptor:function(e,t){return this.create(this._DEC_XFORM_MODE,e,t)},init:function(e,t,r){this.cfg=this.cfg.extend(r),this._xformMode=e,this._key=t,this.reset()},reset:function(){i.reset.call(this),this._doReset()},process:function(e){return this._append(e),this._process()},finalize:function(e){return e&&this._append(e),this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(){function i(e){return"string"==typeof e?v:g}return function(n){return{encrypt:function(e,t,r){return i(t).encrypt(n,e,t,r)},decrypt:function(e,t,r){return i(t).decrypt(n,e,t,r)}}}}()}),r.StreamCipher=u.extend({_doFinalize:function(){return this._process(!0)},blockSize:1}),c=t.mode={},h=r.BlockCipherMode=n.extend({createEncryptor:function(e,t){return this.Encryptor.create(e,t)},createDecryptor:function(e,t){return this.Decryptor.create(e,t)},init:function(e,t){this._cipher=e,this._iv=t}}),l=c.CBC=function(){var e=h.extend();function o(e,t,r){var n=this._iv;if(n){var i=n;this._iv=void 0}else i=this._prevBlock;for(var o=0;o>>2];e.sigBytes-=t}},r.BlockCipher=u.extend({cfg:u.cfg.extend({mode:l,padding:p}),reset:function(){u.reset.call(this);var e=this.cfg,t=e.iv,r=e.mode;if(this._xformMode==this._ENC_XFORM_MODE)var n=r.createEncryptor;else{n=r.createDecryptor;this._minBufferSize=1}this._mode&&this._mode.__creator==n?this._mode.init(this,t&&t.words):(this._mode=n.call(r,this,t&&t.words),this._mode.__creator=n)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else{t=this._process(!0);e.unpad(t)}return t},blockSize:4}),d=r.CipherParams=n.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),_=(t.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext,r=e.salt;if(r)var n=f.create([1398893684,1701076831]).concat(r).concat(t);else n=t;return n.toString(s)},parse:function(e){var t=s.parse(e),r=t.words;if(1398893684==r[0]&&1701076831==r[1]){var n=f.create(r.slice(2,4));r.splice(0,4),t.sigBytes-=16}return d.create({ciphertext:t,salt:n})}},g=r.SerializableCipher=n.extend({cfg:n.extend({format:_}),encrypt:function(e,t,r,n){n=this.cfg.extend(n);var i=e.createEncryptor(r,n),o=i.finalize(t),s=i.cfg;return d.create({ciphertext:o,key:r,iv:s.iv,algorithm:e,mode:s.mode,padding:s.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,r,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(r,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}}),m=(t.kdf={}).OpenSSL={execute:function(e,t,r,n){n||(n=f.random(8));var i=a.create({keySize:t+r}).compute(e,n),o=f.create(i.words.slice(t),4*r);return i.sigBytes=4*t,d.create({key:i,iv:o,salt:n})}},v=r.PasswordBasedCipher=g.extend({cfg:g.cfg.extend({kdf:m}),encrypt:function(e,t,r,n){var i=(n=this.cfg.extend(n)).kdf.execute(r,e.keySize,e.ivSize);n.iv=i.iv;var o=g.encrypt.call(this,e,t,i.key,n);return o.mixIn(i),o},decrypt:function(e,t,r,n){n=this.cfg.extend(n),t=this._parse(t,n.format);var i=n.kdf.execute(r,e.keySize,e.ivSize,t.salt);return n.iv=i.iv,g.decrypt.call(this,e,t,i.key,n)}}))},"object"==typeof r?t.exports=r=i(e(47),e(50)):i(n.CryptoJS)},{47:47,50:50}],47:[function(e,t,r){var n,i;n=this,i=function(){var c,r,e,t,n,h,i,o,s,a,f,u,l=l||(c=Math,r=Object.create||function(){function r(){}return function(e){var t;return r.prototype=e,t=new r,r.prototype=null,t}}(),t=(e={}).lib={},n=t.Base={extend:function(e){var t=r(this);return e&&t.mixIn(e),t.hasOwnProperty("init")&&this.init!==t.init||(t.init=function(){t.$super.init.apply(this,arguments)}),(t.init.prototype=t).$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},h=t.WordArray=n.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,r=e.words,n=this.sigBytes,i=e.sigBytes;if(this.clamp(),n%4)for(var o=0;o>>2]>>>24-o%4*8&255;t[n+o>>>2]|=s<<24-(n+o)%4*8}else for(o=0;o>>2]=r[o>>>2];return this.sigBytes+=i,this},clamp:function(){var e=this.words,t=this.sigBytes;e[t>>>2]&=4294967295<<32-t%4*8,e.length=c.ceil(t/4)},clone:function(){var e=n.clone.call(this);return e.words=this.words.slice(0),e},random:function(e){for(var t,r=[],n=function(t){t=t;var r=987654321,n=4294967295;return function(){var e=((r=36969*(65535&r)+(r>>16)&n)<<16)+(t=18e3*(65535&t)+(t>>16)&n)&n;return e/=4294967296,(e+=.5)*(.5>>2]>>>24-i%4*8&255;n.push((o>>>4).toString(16)),n.push((15&o).toString(16))}return n.join("")},parse:function(e){for(var t=e.length,r=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new h.init(r,t/2)}},s=i.Latin1={stringify:function(e){for(var t=e.words,r=e.sigBytes,n=[],i=0;i>>2]>>>24-i%4*8&255;n.push(String.fromCharCode(o))}return n.join("")},parse:function(e){for(var t=e.length,r=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new h.init(r,t)}},a=i.Utf8={stringify:function(e){try{return decodeURIComponent(escape(s.stringify(e)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(e){return s.parse(unescape(encodeURIComponent(e)))}},f=t.BufferedBlockAlgorithm=n.extend({reset:function(){this._data=new h.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=a.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(e){var t=this._data,r=t.words,n=t.sigBytes,i=this.blockSize,o=n/(4*i),s=(o=e?c.ceil(o):c.max((0|o)-this._minBufferSize,0))*i,a=c.min(4*s,n);if(s){for(var f=0;f>>2]>>>24-o%4*8&255)<<16|(t[o+1>>>2]>>>24-(o+1)%4*8&255)<<8|t[o+2>>>2]>>>24-(o+2)%4*8&255,a=0;a<4&&o+.75*a>>6*(3-a)&63));var f=n.charAt(64);if(f)for(;i.length%4;)i.push(f);return i.join("")},parse:function(e){var t=e.length,r=this._map,n=this._reverseMap;if(!n){n=this._reverseMap=[];for(var i=0;i>>6-o%4*2;n[i>>>2]|=(s|a)<<24-i%4*8,i++}return f.create(n,i)}(e,t,n)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},e.enc.Base64},"object"==typeof r?t.exports=r=i(e(47)):i(n.CryptoJS)},{47:47}],49:[function(e,t,r){var n,i;n=this,i=function(e){return e.enc.Hex},"object"==typeof r?t.exports=r=i(e(47)):i(n.CryptoJS)},{47:47}],50:[function(e,t,r){var n,i;n=this,i=function(e){var t,r,n,c,i,o,s;return r=(t=e).lib,n=r.Base,c=r.WordArray,i=t.algo,o=i.MD5,s=i.EvpKDF=n.extend({cfg:n.extend({keySize:4,hasher:o,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var r=this.cfg,n=r.hasher.create(),i=c.create(),o=i.words,s=r.keySize,a=r.iterations;o.lengthn&&(t=e.finalize(t)),t.clamp();for(var i=this._oKey=t.clone(),o=this._iKey=t.clone(),s=i.words,a=o.words,f=0;f>>24)|4278255360&(i<<24|i>>>8)}var o=this._hash.words,s=e[t+0],a=e[t+1],f=e[t+2],u=e[t+3],c=e[t+4],h=e[t+5],l=e[t+6],p=e[t+7],d=e[t+8],_=e[t+9],g=e[t+10],m=e[t+11],v=e[t+12],y=e[t+13],b=e[t+14],w=e[t+15],E=o[0],B=o[1],k=o[2],T=o[3];B=O(B=O(B=O(B=O(B=A(B=A(B=A(B=A(B=I(B=I(B=I(B=I(B=x(B=x(B=x(B=x(B,k=x(k,T=x(T,E=x(E,B,k,T,s,7,S[0]),B,k,a,12,S[1]),E,B,f,17,S[2]),T,E,u,22,S[3]),k=x(k,T=x(T,E=x(E,B,k,T,c,7,S[4]),B,k,h,12,S[5]),E,B,l,17,S[6]),T,E,p,22,S[7]),k=x(k,T=x(T,E=x(E,B,k,T,d,7,S[8]),B,k,_,12,S[9]),E,B,g,17,S[10]),T,E,m,22,S[11]),k=x(k,T=x(T,E=x(E,B,k,T,v,7,S[12]),B,k,y,12,S[13]),E,B,b,17,S[14]),T,E,w,22,S[15]),k=I(k,T=I(T,E=I(E,B,k,T,a,5,S[16]),B,k,l,9,S[17]),E,B,m,14,S[18]),T,E,s,20,S[19]),k=I(k,T=I(T,E=I(E,B,k,T,h,5,S[20]),B,k,g,9,S[21]),E,B,w,14,S[22]),T,E,c,20,S[23]),k=I(k,T=I(T,E=I(E,B,k,T,_,5,S[24]),B,k,b,9,S[25]),E,B,u,14,S[26]),T,E,d,20,S[27]),k=I(k,T=I(T,E=I(E,B,k,T,y,5,S[28]),B,k,f,9,S[29]),E,B,p,14,S[30]),T,E,v,20,S[31]),k=A(k,T=A(T,E=A(E,B,k,T,h,4,S[32]),B,k,d,11,S[33]),E,B,m,16,S[34]),T,E,b,23,S[35]),k=A(k,T=A(T,E=A(E,B,k,T,a,4,S[36]),B,k,c,11,S[37]),E,B,p,16,S[38]),T,E,g,23,S[39]),k=A(k,T=A(T,E=A(E,B,k,T,y,4,S[40]),B,k,s,11,S[41]),E,B,u,16,S[42]),T,E,l,23,S[43]),k=A(k,T=A(T,E=A(E,B,k,T,_,4,S[44]),B,k,v,11,S[45]),E,B,w,16,S[46]),T,E,f,23,S[47]),k=O(k,T=O(T,E=O(E,B,k,T,s,6,S[48]),B,k,p,10,S[49]),E,B,b,15,S[50]),T,E,h,21,S[51]),k=O(k,T=O(T,E=O(E,B,k,T,v,6,S[52]),B,k,u,10,S[53]),E,B,g,15,S[54]),T,E,a,21,S[55]),k=O(k,T=O(T,E=O(E,B,k,T,d,6,S[56]),B,k,w,10,S[57]),E,B,l,15,S[58]),T,E,y,21,S[59]),k=O(k,T=O(T,E=O(E,B,k,T,c,6,S[60]),B,k,m,10,S[61]),E,B,f,15,S[62]),T,E,_,21,S[63]),o[0]=o[0]+E|0,o[1]=o[1]+B|0,o[2]=o[2]+k|0,o[3]=o[3]+T|0},_doFinalize:function(){var e=this._data,t=e.words,r=8*this._nDataBytes,n=8*e.sigBytes;t[n>>>5]|=128<<24-n%32;var i=c.floor(r/4294967296),o=r;t[15+(n+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),t[14+(n+64>>>9<<4)]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),e.sigBytes=4*(t.length+1),this._process();for(var s=this._hash,a=s.words,f=0;f<4;f++){var u=a[f];a[f]=16711935&(u<<8|u>>>24)|4278255360&(u<<24|u>>>8)}return s},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});function x(e,t,r,n,i,o,s){var a=e+(t&r|~t&n)+i+s;return(a<>>32-o)+t}function I(e,t,r,n,i,o,s){var a=e+(t&n|r&~n)+i+s;return(a<>>32-o)+t}function A(e,t,r,n,i,o,s){var a=e+(t^r^n)+i+s;return(a<>>32-o)+t}function O(e,t,r,n,i,o,s){var a=e+(r^(t|~n))+i+s;return(a<>>32-o)+t}e.MD5=n._createHelper(o),e.HmacMD5=n._createHmacHelper(o)}(Math),s.MD5},"object"==typeof r?t.exports=r=i(e(47)):i(n.CryptoJS)},{47:47}],53:[function(e,t,r){var n,i;n=this,i=function(e){var t,r,n,i,o,h,s;return r=(t=e).lib,n=r.WordArray,i=r.Hasher,o=t.algo,h=[],s=o.SHA1=i.extend({_doReset:function(){this._hash=new n.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(e,t){for(var r=this._hash.words,n=r[0],i=r[1],o=r[2],s=r[3],a=r[4],f=0;f<80;f++){if(f<16)h[f]=0|e[t+f];else{var u=h[f-3]^h[f-8]^h[f-14]^h[f-16];h[f]=u<<1|u>>>31}var c=(n<<5|n>>>27)+a+h[f];c+=f<20?1518500249+(i&o|~i&s):f<40?1859775393+(i^o^s):f<60?(i&o|i&s|o&s)-1894007588:(i^o^s)-899497514,a=s,s=o,o=i<<30|i>>>2,i=n,n=c}r[0]=r[0]+n|0,r[1]=r[1]+i|0,r[2]=r[2]+o|0,r[3]=r[3]+s|0,r[4]=r[4]+a|0},_doFinalize:function(){var e=this._data,t=e.words,r=8*this._nDataBytes,n=8*e.sigBytes;return t[n>>>5]|=128<<24-n%32,t[14+(n+64>>>9<<4)]=Math.floor(r/4294967296),t[15+(n+64>>>9<<4)]=r,e.sigBytes=4*t.length,this._process(),this._hash},clone:function(){var e=i.clone.call(this);return e._hash=this._hash.clone(),e}}),t.SHA1=i._createHelper(s),t.HmacSHA1=i._createHmacHelper(s),e.SHA1},"object"==typeof r?t.exports=r=i(e(47)):i(n.CryptoJS)},{47:47}],54:[function(e,t,r){var a=Array.prototype.slice,f=e(56),u=e(55),c=t.exports=function(e,t,r){return r||(r={}),e===t||(e instanceof Date&&t instanceof Date?e.getTime()===t.getTime():!e||!t||"object"!=typeof e&&"object"!=typeof t?r.strict?e===t:e==t:function(e,t,r){var n,i;if(h(e)||h(t))return!1;if(e.prototype!==t.prototype)return!1;if(u(e))return!!u(t)&&(e=a.call(e),t=a.call(t),c(e,t,r));if(l(e)){if(!l(t))return!1;if(e.length!==t.length)return!1;for(n=0;nr&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},n.prototype.once=function(e,t){if(!f(t))throw TypeError("listener must be a function");var r=!1;function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}return n.listener=t,this.on(e,n),this},n.prototype.removeListener=function(e,t){var r,n,i,o;if(!f(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(i=(r=this._events[e]).length,n=-1,r===t||f(r.listener)&&r.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(u(r)){for(o=i;0=this._blockSize;){for(var i=this._blockOffset;i>1,c=-7,h=r?i-1:0,l=r?-1:1,p=e[t+h];for(h+=l,o=p&(1<<-c)-1,p>>=-c,c+=a;0>=-c,c+=n;0>1,l=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:o-1,d=n?1:-1,_=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=c):(s=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-s))<1&&(s--,f*=2),2<=(t+=1<=s+h?l/f:l*Math.pow(2,1-h))*f&&(s++,f/=2),c<=s+h?(a=0,s=c):1<=s+h?(a=(t*f-1)*Math.pow(2,i),s+=h):(a=t*Math.pow(2,h-1)*Math.pow(2,i),s=0));8<=i;e[r+p]=255&a,p+=d,a/=256,i-=8);for(s=s<>>=0)&&e<256)&&(n=s[e])?n:(r=_(e,(0|e)<0?-1:0,!0),i&&(s[e]=r),r):(i=-128<=(e|=0)&&e<128)&&(n=o[e])?n:(r=_(e,e<0?-1:0,!1),i&&(o[e]=r),r)}function d(e,t){if(isNaN(e)||!isFinite(e))return t?f:v;if(t){if(e<0)return f;if(i<=e)return w}else{if(e<=-a)return E;if(a<=e+1)return b}return e<0?d(-e,t).neg():_(e%r|0,e/r|0,t)}function _(e,t,r){return new n(e,t,r)}n.fromInt=e,n.fromNumber=d,n.fromBits=_;var c=Math.pow;function h(e,t,r){if(0===e.length)throw Error("empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return v;if(t="number"==typeof t?(r=t,!1):!!t,(r=r||10)<2||36>>0:this.low},t.toNumber=function(){return this.unsigned?(this.high>>>0)*r+(this.low>>>0):this.high*r+(this.low>>>0)},t.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((o=a).isZero())return f+s;for(;f.length<6;)f="0"+f;s=""+f+s}},t.getHighBits=function(){return this.high},t.getHighBitsUnsigned=function(){return this.high>>>0},t.getLowBits=function(){return this.low},t.getLowBitsUnsigned=function(){return this.low>>>0},t.getNumBitsAbs=function(){if(this.isNegative())return this.eq(E)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;0>>31!=1||e.high>>>31!=1)&&(this.high===e.high&&this.low===e.low)},t.eq=t.equals,t.notEquals=function(e){return!this.eq(e)},t.neq=t.notEquals,t.lessThan=function(e){return this.comp(e)<0},t.lt=t.lessThan,t.lessThanOrEqual=function(e){return this.comp(e)<=0},t.lte=t.lessThanOrEqual,t.greaterThan=function(e){return 0>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},t.comp=t.compare,t.negate=function(){return!this.unsigned&&this.eq(E)?E:this.not().add(u)},t.neg=t.negate,t.add=function(e){p(e)||(e=g(e));var t=this.high>>>16,r=65535&this.high,n=this.low>>>16,i=65535&this.low,o=e.high>>>16,s=65535&e.high,a=e.low>>>16,f=0,u=0,c=0,h=0;return c+=(h+=i+(65535&e.low))>>>16,u+=(c+=n+a)>>>16,f+=(u+=r+s)>>>16,f+=t+o,_((c&=65535)<<16|(h&=65535),(f&=65535)<<16|(u&=65535),this.unsigned)},t.subtract=function(e){return p(e)||(e=g(e)),this.add(e.neg())},t.sub=t.subtract,t.multiply=function(e){if(this.isZero())return v;if(p(e)||(e=g(e)),e.isZero())return v;if(this.eq(E))return e.isOdd()?E:v;if(e.eq(E))return this.isOdd()?E:v;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(m)&&e.lt(m))return d(this.toNumber()*e.toNumber(),this.unsigned);var t=this.high>>>16,r=65535&this.high,n=this.low>>>16,i=65535&this.low,o=e.high>>>16,s=65535&e.high,a=e.low>>>16,f=65535&e.low,u=0,c=0,h=0,l=0;return h+=(l+=i*f)>>>16,c+=(h+=n*f)>>>16,h&=65535,c+=(h+=i*a)>>>16,u+=(c+=r*f)>>>16,c&=65535,u+=(c+=n*a)>>>16,c&=65535,u+=(c+=i*s)>>>16,u+=t*f+r*a+n*s+i*o,_((h&=65535)<<16|(l&=65535),(u&=65535)<<16|(c&=65535),this.unsigned)},t.mul=t.multiply,t.divide=function(e){if(p(e)||(e=g(e)),e.isZero())throw Error("division by zero");if(this.isZero())return this.unsigned?f:v;var t,r,n;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return f;if(e.gt(this.shru(1)))return l;n=f}else{if(this.eq(E))return e.eq(u)||e.eq(y)?E:e.eq(E)?u:(t=this.shr(1).div(e).shl(1)).eq(v)?e.isNegative()?u:y:(r=this.sub(e.mul(t)),n=t.add(r.div(e)));else if(e.eq(E))return this.unsigned?f:v;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();n=v}for(r=this;r.gte(e);){t=Math.max(1,Math.floor(r.toNumber()/e.toNumber()));for(var i=Math.ceil(Math.log(t)/Math.LN2),o=i<=48?1:c(2,i-48),s=d(t),a=s.mul(e);a.isNegative()||a.gt(r);)a=(s=d(t-=o,this.unsigned)).mul(e);s.isZero()&&(s=u),n=n.add(s),r=r.sub(a)}return n},t.div=t.divide,t.modulo=function(e){return p(e)||(e=g(e)),this.sub(this.div(e).mul(e))},t.mod=t.modulo,t.not=function(){return _(~this.low,~this.high,this.unsigned)},t.and=function(e){return p(e)||(e=g(e)),_(this.low&e.low,this.high&e.high,this.unsigned)},t.or=function(e){return p(e)||(e=g(e)),_(this.low|e.low,this.high|e.high,this.unsigned)},t.xor=function(e){return p(e)||(e=g(e)),_(this.low^e.low,this.high^e.high,this.unsigned)},t.shiftLeft=function(e){return p(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?_(this.low<>>32-e,this.unsigned):_(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):_(this.high>>e-32,0<=this.high?0:-1,this.unsigned)},t.shr=t.shiftRight,t.shiftRightUnsigned=function(e){if(p(e)&&(e=e.toInt()),0===(e&=63))return this;var t=this.high;return e<32?_(this.low>>>e|t<<32-e,t>>>e,this.unsigned):_(32===e?t:t>>>e-32,0,this.unsigned)},t.shru=t.shiftRightUnsigned,t.toSigned=function(){return this.unsigned?_(this.low,this.high,!1):this},t.toUnsigned=function(){return this.unsigned?this:_(this.low,this.high,!0)},t.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},t.toBytesLE=function(){var e=this.high,t=this.low;return[255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255]},t.toBytesBE=function(){var e=this.high,t=this.low;return[e>>>24&255,e>>>16&255,e>>>8&255,255&e,t>>>24&255,t>>>16&255,t>>>8&255,255&t]},n},"function"==typeof e&&"object"==typeof t&&t&&t.exports?t.exports=i():(n.dcodeIO=n.dcodeIO||{}).Long=i()},{}],69:[function(i,o,e){(function(t){"use strict";var e=i(65),r=i(63),s=new Array(16);function n(){r.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878}function a(e,t){return e<>>32-t}function f(e,t,r,n,i,o,s){return a(e+(t&r|~t&n)+i+o|0,s)+t|0}function u(e,t,r,n,i,o,s){return a(e+(t&n|r&~n)+i+o|0,s)+t|0}function c(e,t,r,n,i,o,s){return a(e+(t^r^n)+i+o|0,s)+t|0}function h(e,t,r,n,i,o,s){return a(e+(r^(t|~n))+i+o|0,s)+t|0}e(n,r),n.prototype._update=function(){for(var e=s,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);var r=this._a,n=this._b,i=this._c,o=this._d;n=h(n=h(n=h(n=h(n=c(n=c(n=c(n=c(n=u(n=u(n=u(n=u(n=f(n=f(n=f(n=f(n,i=f(i,o=f(o,r=f(r,n,i,o,e[0],3614090360,7),n,i,e[1],3905402710,12),r,n,e[2],606105819,17),o,r,e[3],3250441966,22),i=f(i,o=f(o,r=f(r,n,i,o,e[4],4118548399,7),n,i,e[5],1200080426,12),r,n,e[6],2821735955,17),o,r,e[7],4249261313,22),i=f(i,o=f(o,r=f(r,n,i,o,e[8],1770035416,7),n,i,e[9],2336552879,12),r,n,e[10],4294925233,17),o,r,e[11],2304563134,22),i=f(i,o=f(o,r=f(r,n,i,o,e[12],1804603682,7),n,i,e[13],4254626195,12),r,n,e[14],2792965006,17),o,r,e[15],1236535329,22),i=u(i,o=u(o,r=u(r,n,i,o,e[1],4129170786,5),n,i,e[6],3225465664,9),r,n,e[11],643717713,14),o,r,e[0],3921069994,20),i=u(i,o=u(o,r=u(r,n,i,o,e[5],3593408605,5),n,i,e[10],38016083,9),r,n,e[15],3634488961,14),o,r,e[4],3889429448,20),i=u(i,o=u(o,r=u(r,n,i,o,e[9],568446438,5),n,i,e[14],3275163606,9),r,n,e[3],4107603335,14),o,r,e[8],1163531501,20),i=u(i,o=u(o,r=u(r,n,i,o,e[13],2850285829,5),n,i,e[2],4243563512,9),r,n,e[7],1735328473,14),o,r,e[12],2368359562,20),i=c(i,o=c(o,r=c(r,n,i,o,e[5],4294588738,4),n,i,e[8],2272392833,11),r,n,e[11],1839030562,16),o,r,e[14],4259657740,23),i=c(i,o=c(o,r=c(r,n,i,o,e[1],2763975236,4),n,i,e[4],1272893353,11),r,n,e[7],4139469664,16),o,r,e[10],3200236656,23),i=c(i,o=c(o,r=c(r,n,i,o,e[13],681279174,4),n,i,e[0],3936430074,11),r,n,e[3],3572445317,16),o,r,e[6],76029189,23),i=c(i,o=c(o,r=c(r,n,i,o,e[9],3654602809,4),n,i,e[12],3873151461,11),r,n,e[15],530742520,16),o,r,e[2],3299628645,23),i=h(i,o=h(o,r=h(r,n,i,o,e[0],4096336452,6),n,i,e[7],1126891415,10),r,n,e[14],2878612391,15),o,r,e[5],4237533241,21),i=h(i,o=h(o,r=h(r,n,i,o,e[12],1700485571,6),n,i,e[3],2399980690,10),r,n,e[10],4293915773,15),o,r,e[1],2240044497,21),i=h(i,o=h(o,r=h(r,n,i,o,e[8],1873313359,6),n,i,e[15],4264355552,10),r,n,e[6],2734768916,15),o,r,e[13],1309151649,21),i=h(i,o=h(o,r=h(r,n,i,o,e[4],4149444226,6),n,i,e[11],3174756917,10),r,n,e[2],718787259,15),o,r,e[9],3951481745,21),this._a=this._a+r|0,this._b=this._b+n|0,this._c=this._c+i|0,this._d=this._d+o|0},n.prototype._digest=function(){this._block[this._blockOffset++]=128,56this.urls.length-1)return t(new Error("Tried "+(i+1)+" connections, none of which worked: "+JSON.stringify(this.urls.concat(this.url))));var s=function(e,t){return o.logFailure(n),o.connectWithFallback(r,o.urls[i],i+1,e,t)};return e&&t?this.connect(r,n).then(e).catch(function(){s(e,t)}):new Promise(function(e,t){o.connect(r).then(e).catch(function(){s(e,t)})})},n.prototype.checkConnections=function(){var i=0t.highWaterMark&&(t.highWaterMark=(_<=(r=e)?r=_:(r--,r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r++),r)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0));var r}function E(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(b("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?m.nextTick(B,e):B(e))}function B(e){b("emit readable"),e.emit("readable"),I(e)}function k(e,t){t.readingMore||(t.readingMore=!0,m.nextTick(T,e,t))}function T(e,t){for(var r=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):r=function(e,t,r){var n;eo.length?o.length:e;if(s===o.length?i+=o:i+=o.slice(0,e),0===(e-=s)){s===o.length?(++n,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r).data=o.slice(s);break}++n}return t.length-=n,i}(e,t):function(e,t){var r=u.allocUnsafe(e),n=t.head,i=1;n.data.copy(r),e-=n.data.length;for(;n=n.next;){var o=n.data,s=e>o.length?o.length:e;if(o.copy(r,r.length-e,0,s),0===(e-=s)){s===o.length?(++i,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n).data=o.slice(s);break}++i}return t.length-=i,r}(e,t);return n}(e,t.buffer,t.decoder),r);var r}function O(e){var t=e._readableState;if(0=t.highWaterMark||t.ended))return b("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?O(this):E(this),null;if(0===(e=w(e,t))&&t.ended)return 0===t.length&&O(this),null;var n,i=t.needReadable;return b("need readable",i),(0===t.length||t.length-e>>0),o=this.head,s=0;o;)t=o.data,r=i,n=s,t.copy(r,n),s+=o.data.length,o=o.next;return i},e}(),n&&n.inspect&&n.inspect.custom&&(t.exports.prototype[n.inspect.custom]=function(){var e=n.inspect({length:this.length});return this.constructor.name+" "+e})},{34:34,93:93}],85:[function(e,t,r){"use strict";var o=e(76);function s(e,t){e.emit("error",t)}t.exports={destroy:function(e,t){var r=this,n=this._readableState&&this._readableState.destroyed,i=this._writableState&&this._writableState.destroyed;return n||i?t?t(e):!e||this._writableState&&this._writableState.errorEmitted||o.nextTick(s,this,e):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(o.nextTick(s,r,e),r._writableState&&(r._writableState.errorEmitted=!0)):t&&t(e)})),this},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},{76:76}],86:[function(e,t,r){t.exports=e(62).EventEmitter},{62:62}],87:[function(e,t,r){arguments[4][65][0].apply(r,arguments)},{65:65}],88:[function(e,t,r){t.exports=e(89).PassThrough},{89:89}],89:[function(e,t,r){(((r=t.exports=e(81)).Stream=r).Readable=r).Writable=e(83),r.Duplex=e(79),r.Transform=e(82),r.PassThrough=e(80)},{79:79,80:80,81:81,82:82,83:83}],90:[function(e,t,r){t.exports=e(89).Transform},{89:89}],91:[function(e,t,r){t.exports=e(83)},{83:83}],92:[function(e,t,r){"use strict";var n=e(35).Buffer,i=e(65),o=e(63),g=new Array(16),m=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],v=[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11],y=[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],b=[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11],w=[0,1518500249,1859775393,2400959708,2840853838],E=[1352829926,1548603684,1836072691,2053994217,0];function s(){o.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520}function B(e,t){return e<>>32-t}function k(e,t,r,n,i,o,s,a){return B(e+(t^r^n)+o+s|0,a)+i|0}function T(e,t,r,n,i,o,s,a){return B(e+(t&r|~t&n)+o+s|0,a)+i|0}function S(e,t,r,n,i,o,s,a){return B(e+((t|~r)^n)+o+s|0,a)+i|0}function x(e,t,r,n,i,o,s,a){return B(e+(t&n|r&~n)+o+s|0,a)+i|0}function I(e,t,r,n,i,o,s,a){return B(e+(t^(r|~n))+o+s|0,a)+i|0}i(s,o),s.prototype._update=function(){for(var e=g,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);for(var r=0|this._a,n=0|this._b,i=0|this._c,o=0|this._d,s=0|this._e,a=0|this._a,f=0|this._b,u=0|this._c,c=0|this._d,h=0|this._e,l=0;l<80;l+=1){var p,d;d=l<16?(p=k(r,n,i,o,s,e[m[l]],w[0],y[l]),I(a,f,u,c,h,e[v[l]],E[0],b[l])):l<32?(p=T(r,n,i,o,s,e[m[l]],w[1],y[l]),x(a,f,u,c,h,e[v[l]],E[1],b[l])):l<48?(p=S(r,n,i,o,s,e[m[l]],w[2],y[l]),S(a,f,u,c,h,e[v[l]],E[2],b[l])):l<64?(p=x(r,n,i,o,s,e[m[l]],w[3],y[l]),T(a,f,u,c,h,e[v[l]],E[3],b[l])):(p=I(r,n,i,o,s,e[m[l]],w[4],y[l]),k(a,f,u,c,h,e[v[l]],E[4],b[l])),r=s,s=o,o=B(i,10),i=n,n=p,a=h,h=c,c=B(u,10),u=f,f=d}var _=this._b+i+c|0;this._b=this._c+o+h|0,this._c=this._d+s+a|0,this._d=this._e+r+f|0,this._e=this._a+n+u|0,this._a=_},s.prototype._digest=function(){this._block[this._blockOffset++]=128,56=this._finalSize&&(this._update(this._block),this._block.fill(0));var r=8*this._len;if(r<=4294967295)this._block.writeUInt32BE(r,this._blockSize-4);else{var n=(4294967295&r)>>>0,i=(r-n)/4294967296;this._block.writeUInt32BE(i,this._blockSize-8),this._block.writeUInt32BE(n,this._blockSize-4)}this._update(this._block);var o=this._hash();return e?o.toString(e):o},n.prototype._update=function(){throw new Error("_update must be implemented by subclass")},t.exports=n},{93:93}],96:[function(e,t,r){(r=t.exports=function(e){e=e.toLowerCase();var t=r[e];if(!t)throw new Error(e+" is not supported (we accept pull requests)");return new t}).sha=e(97),r.sha1=e(98),r.sha224=e(99),r.sha256=e(100),r.sha384=e(101),r.sha512=e(102)},{100:100,101:101,102:102,97:97,98:98,99:99}],97:[function(e,t,r){var n=e(65),i=e(95),o=e(93).Buffer,m=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function a(){this.init(),this._w=s,i.call(this,64,56)}n(a,i),a.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},a.prototype._update=function(e){for(var t,r,n,i,o,s,a=this._w,f=0|this._a,u=0|this._b,c=0|this._c,h=0|this._d,l=0|this._e,p=0;p<16;++p)a[p]=e.readInt32BE(4*p);for(;p<80;++p)a[p]=a[p-3]^a[p-8]^a[p-14]^a[p-16];for(var d=0;d<80;++d){var _=~~(d/20),g=0|((s=f)<<5|s>>>27)+(n=u,i=c,o=h,0===(r=_)?n&i|~n&o:2===r?n&i|n&o|i&o:n^i^o)+l+a[d]+m[_];l=h,h=c,c=(t=u)<<30|t>>>2,u=f,f=g}this._a=f+this._a|0,this._b=u+this._b|0,this._c=c+this._c|0,this._d=h+this._d|0,this._e=l+this._e|0},a.prototype._hash=function(){var e=o.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},t.exports=a},{65:65,93:93,95:95}],98:[function(e,t,r){var n=e(65),i=e(95),o=e(93).Buffer,v=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function a(){this.init(),this._w=s,i.call(this,64,56)}n(a,i),a.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},a.prototype._update=function(e){for(var t,r,n,i,o,s,a,f=this._w,u=0|this._a,c=0|this._b,h=0|this._c,l=0|this._d,p=0|this._e,d=0;d<16;++d)f[d]=e.readInt32BE(4*d);for(;d<80;++d)f[d]=(t=f[d-3]^f[d-8]^f[d-14]^f[d-16])<<1|t>>>31;for(var _=0;_<80;++_){var g=~~(_/20),m=0|((a=u)<<5|a>>>27)+(i=c,o=h,s=l,0===(n=g)?i&o|~i&s:2===n?i&o|i&s|o&s:i^o^s)+p+f[_]+v[g];p=l,l=h,h=(r=c)<<30|r>>>2,c=u,u=m}this._a=u+this._a|0,this._b=c+this._b|0,this._c=h+this._c|0,this._d=l+this._d|0,this._e=p+this._e|0},a.prototype._hash=function(){var e=o.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},t.exports=a},{65:65,93:93,95:95}],99:[function(e,t,r){var n=e(65),i=e(100),o=e(95),s=e(93).Buffer,a=new Array(64);function f(){this.init(),this._w=a,o.call(this,64,56)}n(f,i),f.prototype.init=function(){return this._a=3238371032,this._b=914150663,this._c=812702999,this._d=4144912697,this._e=4290775857,this._f=1750603025,this._g=1694076839,this._h=3204075428,this},f.prototype._hash=function(){var e=s.allocUnsafe(28);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e},t.exports=f},{100:100,65:65,93:93,95:95}],100:[function(e,t,r){var n=e(65),i=e(95),o=e(93).Buffer,w=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],s=new Array(64);function a(){this.init(),this._w=s,i.call(this,64,56)}n(a,i),a.prototype.init=function(){return this._a=1779033703,this._b=3144134277,this._c=1013904242,this._d=2773480762,this._e=1359893119,this._f=2600822924,this._g=528734635,this._h=1541459225,this},a.prototype._update=function(e){for(var t,r,n,i,o,s,a,f=this._w,u=0|this._a,c=0|this._b,h=0|this._c,l=0|this._d,p=0|this._e,d=0|this._f,_=0|this._g,g=0|this._h,m=0;m<16;++m)f[m]=e.readInt32BE(4*m);for(;m<64;++m)f[m]=0|(((r=f[m-2])>>>17|r<<15)^(r>>>19|r<<13)^r>>>10)+f[m-7]+(((t=f[m-15])>>>7|t<<25)^(t>>>18|t<<14)^t>>>3)+f[m-16];for(var v=0;v<64;++v){var y=g+(((a=p)>>>6|a<<26)^(a>>>11|a<<21)^(a>>>25|a<<7))+((s=_)^p&(d^s))+w[v]+f[v]|0,b=0|(((o=u)>>>2|o<<30)^(o>>>13|o<<19)^(o>>>22|o<<10))+((n=u)&(i=c)|h&(n|i));g=_,_=d,d=p,p=l+y|0,l=h,h=c,c=u,u=y+b|0}this._a=u+this._a|0,this._b=c+this._b|0,this._c=h+this._c|0,this._d=l+this._d|0,this._e=p+this._e|0,this._f=d+this._f|0,this._g=_+this._g|0,this._h=g+this._h|0},a.prototype._hash=function(){var e=o.allocUnsafe(32);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e.writeInt32BE(this._h,28),e},t.exports=a},{65:65,93:93,95:95}],101:[function(e,t,r){var n=e(65),i=e(102),o=e(95),s=e(93).Buffer,a=new Array(160);function f(){this.init(),this._w=a,o.call(this,128,112)}n(f,i),f.prototype.init=function(){return this._ah=3418070365,this._bh=1654270250,this._ch=2438529370,this._dh=355462360,this._eh=1731405415,this._fh=2394180231,this._gh=3675008525,this._hh=1203062813,this._al=3238371032,this._bl=914150663,this._cl=812702999,this._dl=4144912697,this._el=4290775857,this._fl=1750603025,this._gl=1694076839,this._hl=3204075428,this},f.prototype._hash=function(){var n=s.allocUnsafe(48);function e(e,t,r){n.writeInt32BE(e,r),n.writeInt32BE(t,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),n},t.exports=f},{102:102,65:65,93:93,95:95}],102:[function(e,t,r){var n=e(65),i=e(95),o=e(93).Buffer,ee=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591],s=new Array(160);function a(){this.init(),this._w=s,i.call(this,128,112)}function te(e,t,r){return r^e&(t^r)}function re(e,t,r){return e&t|r&(e|t)}function ne(e,t){return(e>>>28|t<<4)^(t>>>2|e<<30)^(t>>>7|e<<25)}function ie(e,t){return(e>>>14|t<<18)^(e>>>18|t<<14)^(t>>>9|e<<23)}function oe(e,t){return e>>>0>>0?1:0}n(a,i),a.prototype.init=function(){return this._ah=1779033703,this._bh=3144134277,this._ch=1013904242,this._dh=2773480762,this._eh=1359893119,this._fh=2600822924,this._gh=528734635,this._hh=1541459225,this._al=4089235720,this._bl=2227873595,this._cl=4271175723,this._dl=1595750129,this._el=2917565137,this._fl=725511199,this._gl=4215389547,this._hl=327033209,this},a.prototype._update=function(e){for(var t,r,n,i,o,s,a,f,u=this._w,c=0|this._ah,h=0|this._bh,l=0|this._ch,p=0|this._dh,d=0|this._eh,_=0|this._fh,g=0|this._gh,m=0|this._hh,v=0|this._al,y=0|this._bl,b=0|this._cl,w=0|this._dl,E=0|this._el,B=0|this._fl,k=0|this._gl,T=0|this._hl,S=0;S<32;S+=2)u[S]=e.readInt32BE(4*S),u[S+1]=e.readInt32BE(4*S+4);for(;S<160;S+=2){var x=u[S-30],I=u[S-30+1],A=((a=x)>>>1|(f=I)<<31)^(a>>>8|f<<24)^a>>>7,O=((o=I)>>>1|(s=x)<<31)^(o>>>8|s<<24)^(o>>>7|s<<25);x=u[S-4],I=u[S-4+1];var L=((n=x)>>>19|(i=I)<<13)^(i>>>29|n<<3)^n>>>6,C=((t=I)>>>19|(r=x)<<13)^(r>>>29|t<<3)^(t>>>6|r<<26),R=u[S-14],U=u[S-14+1],j=u[S-32],M=u[S-32+1],D=O+U|0,q=A+R+oe(D,O)|0;q=(q=q+L+oe(D=D+C|0,C)|0)+j+oe(D=D+M|0,M)|0,u[S]=q,u[S+1]=D}for(var P=0;P<160;P+=2){q=u[P],D=u[P+1];var N=re(c,h,l),z=re(v,y,b),F=ne(c,v),H=ne(v,c),V=ie(d,E),Y=ie(E,d),K=ee[P],W=ee[P+1],Z=te(d,_,g),G=te(E,B,k),J=T+Y|0,X=m+V+oe(J,T)|0;X=(X=(X=X+Z+oe(J=J+G|0,G)|0)+K+oe(J=J+W|0,W)|0)+q+oe(J=J+D|0,D)|0;var $=H+z|0,Q=F+N+oe($,H)|0;m=g,T=k,g=_,k=B,_=d,B=E,d=p+X+oe(E=w+J|0,w)|0,p=l,w=b,l=h,b=y,h=c,y=v,c=X+Q+oe(v=J+$|0,J)|0}this._al=this._al+v|0,this._bl=this._bl+y|0,this._cl=this._cl+b|0,this._dl=this._dl+w|0,this._el=this._el+E|0,this._fl=this._fl+B|0,this._gl=this._gl+k|0,this._hl=this._hl+T|0,this._ah=this._ah+c+oe(this._al,v)|0,this._bh=this._bh+h+oe(this._bl,y)|0,this._ch=this._ch+l+oe(this._cl,b)|0,this._dh=this._dh+p+oe(this._dl,w)|0,this._eh=this._eh+d+oe(this._el,E)|0,this._fh=this._fh+_+oe(this._fl,B)|0,this._gh=this._gh+g+oe(this._gl,k)|0,this._hh=this._hh+m+oe(this._hl,T)|0},a.prototype._hash=function(){var n=o.allocUnsafe(64);function e(e,t,r){n.writeInt32BE(e,r),n.writeInt32BE(t,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),e(this._gh,this._gl,48),e(this._hh,this._hl,56),n},t.exports=a},{65:65,93:93,95:95}],103:[function(e,t,r){t.exports=n;var c=e(62).EventEmitter;function n(){c.call(this)}e(65)(n,c),n.Readable=e(89),n.Writable=e(91),n.Duplex=e(78),n.Transform=e(90),n.PassThrough=e(88),(n.Stream=n).prototype.pipe=function(t,e){var r=this;function n(e){t.writable&&!1===t.write(e)&&r.pause&&r.pause()}function i(){r.readable&&r.resume&&r.resume()}r.on("data",n),t.on("drain",i),t._isStdio||e&&!1===e.end||(r.on("end",s),r.on("close",a));var o=!1;function s(){o||(o=!0,t.end())}function a(){o||(o=!0,"function"==typeof t.destroy&&t.destroy())}function f(e){if(u(),0===c.listenerCount(this,"error"))throw e}function u(){r.removeListener("data",n),t.removeListener("drain",i),r.removeListener("end",s),r.removeListener("close",a),r.removeListener("error",f),t.removeListener("error",f),r.removeListener("end",u),r.removeListener("close",u),t.removeListener("close",u)}return r.on("error",f),t.on("error",f),r.on("end",u),r.on("close",u),t.on("close",u),t.emit("pipe",r),t}},{62:62,65:65,78:78,88:88,89:89,90:90,91:91}],104:[function(e,t,r){"use strict";var n=e(93).Buffer,i=n.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function o(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(n.isEncoding===i||!i(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=f,this.end=u,t=4;break;case"utf8":this.fillLast=a,t=4;break;case"base64":this.text=c,this.end=h,t=3;break;default:return this.write=l,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=n.allocUnsafe(t)}function s(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function a(e){var t=this.lastTotal-this.lastNeed,r=function(e,t,r){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(1=1.1.13-1 <1.2.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "combine-source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.6.1.tgz", + "integrity": "sha1-m0oJwxYDPXaODxHgKfonMOB5rZY=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.5.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.4.2" + } + }, + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "inline-source-map": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.5.0.tgz", + "integrity": "sha1-Skxd2OT7Xps82mDIIt+tyu5m4K8=", + "dev": true, + "requires": { + "source-map": "~0.4.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, "bytebuffer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", @@ -1168,7 +1570,22 @@ "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", "dev": true }, - "caseless": { + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", @@ -1188,6 +1605,12 @@ "supports-color": "^2.0.0" } }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, "cheerio": { "version": "1.0.0-rc.2", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", @@ -1229,12 +1652,41 @@ "safe-buffer": "^5.0.1" } }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "optional": true + "requires": { + "color-name": "1.1.3" + } }, "color-logger": { "version": "0.0.6", @@ -1242,6 +1694,12 @@ "integrity": "sha1-5WJF7ymCJlcRDHy3WpzXhstp7Rs=", "dev": true }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", @@ -1337,6 +1795,12 @@ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "convert-source-map": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", @@ -1390,6 +1854,17 @@ "sha.js": "^2.4.8" } }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -1410,9 +1885,9 @@ } }, "crypto-js": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", - "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=" + "version": "3.1.9-1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", + "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" }, "css-select": { "version": "1.2.0", @@ -1456,6 +1931,12 @@ "es5-ext": "^0.10.9" } }, + "damerau-levenshtein": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz", + "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=", + "dev": true + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -1490,8 +1971,16 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, - "optional": true + "requires": { + "object-keys": "^1.0.12" + } }, "defined": { "version": "1.0.0", @@ -1547,9 +2036,9 @@ } }, "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "diffie-hellman": { @@ -1563,6 +2052,15 @@ "randombytes": "^2.0.0" } }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dom-serializer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", @@ -1655,12 +2153,52 @@ "minimalistic-crypto-utils": "^1.0.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "entities": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", "dev": true }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "es5-ext": { "version": "0.10.45", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", @@ -1752,6 +2290,314 @@ } } }, + "eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "dev": true, + "requires": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", + "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "eslint-config-airbnb": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz", + "integrity": "sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "^13.1.0", + "object.assign": "^4.1.0", + "object.entries": "^1.0.4" + } + }, + "eslint-config-airbnb-base": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz", + "integrity": "sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==", + "dev": true, + "requires": { + "eslint-restricted-globals": "^0.1.1", + "object.assign": "^4.1.0", + "object.entries": "^1.0.4" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz", + "integrity": "sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz", + "integrity": "sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==", + "dev": true, + "requires": { + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.3.0", + "has": "^1.0.3", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "read-pkg-up": "^2.0.0", + "resolve": "^1.9.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.0.tgz", + "integrity": "sha512-KpibpIdKT0nbDG7G/ILWoZoN5G9cj3h1IHARxzvHk5Nt2LQ7oPUutbO9QbT1FKNHLPZB6BaoA1ASSLOiJZVEUQ==", + "dev": true, + "requires": { + "aria-query": "^3.0.0", + "array-includes": "^3.0.3", + "ast-types-flow": "^0.0.7", + "axobject-query": "^2.0.2", + "damerau-levenshtein": "^1.0.4", + "emoji-regex": "^7.0.2", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1" + } + }, + "eslint-plugin-prettier": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz", + "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==", + "dev": true, + "requires": { + "fast-diff": "^1.1.1", + "jest-docblock": "^21.0.0" + } + }, + "eslint-plugin-react": { + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz", + "integrity": "sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1", + "object.fromentries": "^2.0.0", + "prop-types": "^15.6.2", + "resolve": "^1.9.0" + }, + "dependencies": { + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", @@ -1759,12 +2605,29 @@ "dev": true, "optional": true }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true, - "optional": true + "dev": true }, "esutils": { "version": "2.0.2", @@ -1824,6 +2687,17 @@ "dev": true, "optional": true }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, "extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", @@ -1840,26 +2714,68 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, + "falafel": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.1.0.tgz", + "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=", + "dev": true, + "requires": { + "acorn": "^5.0.0", + "foreach": "^2.0.5", + "isarray": "0.0.1", + "object-keys": "^1.0.6" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, "fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true, - "optional": true + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true, - "optional": true + "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, - "optional": true + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } }, "filename-regex": { "version": "2.0.1", @@ -1882,6 +2798,27 @@ "repeat-string": "^1.5.2" } }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -1899,6 +2836,12 @@ "for-in": "^1.0.1" } }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -2476,6 +3419,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "get-assigned-identifiers": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", @@ -2539,9 +3488,9 @@ "dev": true }, "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "har-schema": { @@ -2580,6 +3529,18 @@ "ansi-regex": "^2.0.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "hash-base": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", @@ -2599,6 +3560,12 @@ "minimalistic-assert": "^1.0.1" } }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -2620,6 +3587,12 @@ "os-tmpdir": "^1.0.1" } }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, "htmlescape": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", @@ -2744,10 +3717,24 @@ } } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "ieee754": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, "immutable": { @@ -2755,6 +3742,12 @@ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=" }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -2785,6 +3778,74 @@ "source-map": "~0.5.3" } }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "insert-module-globals": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", @@ -2826,6 +3887,12 @@ "loose-envify": "^1.0.0" } }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -2842,6 +3909,27 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -2881,6 +3969,12 @@ "number-is-nan": "^1.0.0" } }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", @@ -2914,6 +4008,36 @@ "dev": true, "optional": true }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -2927,6 +4051,12 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", @@ -2944,36 +4074,36 @@ "dev": true, "optional": true }, - "jade": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", + "jest-docblock": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", + "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", "dev": true, "requires": { - "commander": "0.6.1", - "mkdirp": "0.3.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, "dependencies": { - "commander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", - "dev": true - }, - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true } } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -3038,8 +4168,7 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true, - "optional": true + "dev": true }, "json-stable-stringify": { "version": "0.0.1", @@ -3050,6 +4179,12 @@ "jsonify": "~0.0.0" } }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -3097,6 +4232,15 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", + "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, + "requires": { + "array-includes": "^3.0.3" + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -3130,36 +4274,45 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, - "optional": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", "dev": true }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true - }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", "dev": true }, - "lodash.pickby": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", - "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=", - "dev": true - }, "long": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", @@ -3175,10 +4328,14 @@ } }, "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } }, "marked": { "version": "0.3.19", @@ -3249,6 +4406,12 @@ "mime-db": "~1.33.0" } }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -3286,75 +4449,47 @@ } }, "mocha": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", - "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", - "dev": true, - "requires": { - "commander": "2.3.0", - "debug": "2.2.0", - "diff": "1.4.0", - "escape-string-regexp": "1.0.2", - "glob": "3.2.11", - "growl": "1.9.2", - "jade": "0.26.3", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", "mkdirp": "0.5.1", - "supports-color": "1.2.0", - "to-iso-string": "0.0.2" + "supports-color": "5.4.0" }, "dependencies": { "commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "escape-string-regexp": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", - "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", - "dev": true - }, - "glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "inherits": "2", - "minimatch": "0.3" + "ms": "2.0.0" } }, - "minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" + "has-flag": "^3.0.0" } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "supports-color": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", - "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", - "dev": true } } }, @@ -3387,6 +4522,12 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", @@ -3394,11 +4535,29 @@ "dev": true, "optional": true }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "next-tick": { "version": "1.0.0", "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, + "normalize-package-data": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.2.tgz", + "integrity": "sha512-YcMnjqeoUckXTPKZSAsPjUPLxH85XotbpqK3w4RyCwdFQSU5FxxBys8buehkSfg0j9fKvV1hn7O0+8reEgkAiw==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -3443,6 +4602,48 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + } + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -3463,12 +4664,20 @@ "wrappy": "1" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, - "optional": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -3478,11 +4687,6 @@ "wordwrap": "~1.0.0" } }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" - }, "os-browserify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz", @@ -3512,6 +4716,30 @@ "object-assign": "^4.1.0" } }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", @@ -3553,6 +4781,15 @@ "is-glob": "^2.0.0" } }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "parse5": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", @@ -3568,12 +4805,24 @@ "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -3586,6 +4835,15 @@ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", "dev": true }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, "pbkdf2": { "version": "3.0.16", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", @@ -3600,17 +4858,10 @@ } }, "peerplaysjs-ws": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/peerplaysjs-ws/-/peerplaysjs-ws-0.1.11.tgz", - "integrity": "sha1-6q6x5yXurfWcpgJ8Zx8yDXAlG+8=", + "version": "git+ssh://git@github.com/PBSA/peerplaysjs-ws.git#a92c3d94297d79e41c75c0c9f63898e59a888a2a", + "from": "git+ssh://git@github.com/PBSA/peerplaysjs-ws.git", "requires": { - "ws": "^1.1.4" - }, - "dependencies": { - "ReconnectingWebSocket": { - "version": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148", - "from": "git+https://github.com/svk31/reconnecting-websocket.git#464ed2e54eb37b90b7f4f8532427ac2753d87148" - } + "ws": "2.3.1" } }, "performance-now": { @@ -3620,6 +4871,27 @@ "dev": true, "optional": true }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -3633,6 +4905,12 @@ "dev": true, "optional": true }, + "prettier": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.3.tgz", + "integrity": "sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==", + "dev": true + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -3651,6 +4929,28 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "prop-types": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", + "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", + "dev": true, + "requires": { + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, "psl": { "version": "1.1.28", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.28.tgz", @@ -3752,6 +5052,27 @@ "readable-stream": "^2.0.2" } }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -3813,6 +5134,12 @@ "is-equal-shallow": "^0.1.3" } }, + "regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true + }, "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", @@ -3916,6 +5243,16 @@ } } }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -3925,6 +5262,47 @@ "path-parse": "^1.0.5" } }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -3934,6 +5312,30 @@ "inherits": "^2.0.1" } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "*" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -3943,8 +5345,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "optional": true + "dev": true }, "sax": { "version": "1.2.4", @@ -3958,6 +5359,12 @@ "resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.1.tgz", "integrity": "sha1-CIDy2MUYX0vLRoQFjINrTdsHFFo=" }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", @@ -3984,6 +5391,21 @@ "sha.js": "~2.4.4" } }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "shell-quote": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", @@ -3996,10 +5418,10 @@ "jsonify": "~0.0.0" } }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "simple-concat": { @@ -4014,6 +5436,15 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -4029,6 +5460,44 @@ "source-map": "^0.5.6" } }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sshpk": { "version": "1.14.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", @@ -4090,6 +5559,33 @@ "readable-stream": "^2.0.2" } }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -4108,6 +5604,18 @@ "ansi-regex": "^2.0.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, "subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -4147,12 +5655,63 @@ "acorn-node": "^1.2.0" } }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "taffydb": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.7.3.tgz", "integrity": "sha1-KtNxaWKUmPylvIQkMJbTzeDsOjQ=", "dev": true }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -4178,6 +5737,15 @@ "process": "~0.11.0" } }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -4190,12 +5758,6 @@ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "dev": true }, - "to-iso-string": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", - "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", - "dev": true - }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -4258,16 +5820,34 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, - "uglifyjs": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/uglifyjs/-/uglifyjs-2.4.11.tgz", - "integrity": "sha1-NEDWTgRXWViVJEGOtkHGi7kNET4=", - "dev": true + "uglify-js": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "dev": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } }, "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, "umd": { "version": "3.0.3", @@ -4321,7 +5901,6 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, "requires": { "inherits": "2.0.1" }, @@ -4329,8 +5908,7 @@ "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" } } }, @@ -4356,6 +5934,16 @@ "user-home": "^1.1.1" } }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -4394,12 +5982,20 @@ "tr46": "~0.0.1" } }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true, - "optional": true + "dev": true }, "wrappy": { "version": "1.0.2", @@ -4407,13 +6003,29 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "ws": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", - "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-2.3.1.tgz", + "integrity": "sha1-a5Sz5EfLajY/eF6vlK9jWejoHIA=", "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" + "safe-buffer": "~5.0.1", + "ultron": "~1.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" + } } }, "xml-name-validator": { @@ -4428,6 +6040,12 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true } } } diff --git a/package.json b/package.json index 8f1dc30..cccf9d9 100644 --- a/package.json +++ b/package.json @@ -1,74 +1,84 @@ { - "name": "peerplaysjs-lib", - "version": "0.4.20", - "description": "Pure JavaScript Peerplays/Graphene library for node.js and browsers.", - "browser": { - "ws": false, - "crypto": false - }, - "scripts": { - "test": "BABEL_ENV=test mocha --compilers js:babel-register --recursive", - "test:chain": "BABEL_ENV=test mocha --compilers js:babel-register ./test/chain --recursive", - "test:ecc": "BABEL_ENV=test mocha --compilers js:babel-register ./test/ecc --recursive", - "test:serializer": "BABEL_ENV=test mocha --compilers js:babel-register ./test/serializer --recursive", - "test:watch": "npm test -- --watch", - "clean": "rm -rf ./dist/* & rm -rf ./build/*", - "prebuild": "npm run clean", - "build": "babel lib -d dist", - "postbuild": "npm run browserify", - "build:watch": "babel lib -d dist --watch", - "prebrowserify": "rm -rf ./build/*", - "browserify": "browserify -t [browserify-package-json --global=true] -p [bundle-collapser/plugin] dist/browser.js --full-path=false --standalone peerplays_js -o build/peerplaysjs-lib.js -d", - "postbrowserify": "uglifyjs --compress --mangle --sequences --drop_console --output build/peerplaysjs-lib.min.js -- build/peerplaysjs-lib.js", - "doc": "esdoc -c esdoc.json", - "example:transfer": "babel-node examples/transfer", - "example:chainStore": "babel-node examples/chainStore", - "example:privKey": "babel-node examples/privKey" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/PBSA/peerplaysjs-lib.git" - }, - "author": "Sigve Kvalsvik (https://github.com/svk31)", - "contributors": [ - "James Calfee (https://github.com/jcalfee/)", - "Daniel Larimer (https://github.com/bytemaster/)", - "Valentine Zavgorodnev (https://github.com/valzav/)" - ], - "license": "BSD-2-Clause-FreeBSD", - "bugs": { - "url": "https://github.com/PBSA/peerplaysjs-lib/issues" - }, - "engines": { - "node": ">= 6.0.0" - }, - "main": "./dist/index.js", - "dependencies": { - "bigi": "^1.4.1", - "bluebird": "^3.5.0", - "bs58": "^3.0.0", - "bytebuffer": "^5.0.0", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "crypto-js": "^3.1.5", - "deep-equal": "^1.0.1", - "ecurve": "^1.0.2", - "event-emitter": "^0.3.4", - "immutable": "^3.7.6", - "peerplaysjs-ws": "^0.1.11", - "secure-random": "^1.1.1" - }, - "devDependencies": { - "assert": "^1.3.0", - "babel-cli": "^6.9.0", - "babel-core": "^6.10.4", - "babel-eslint": "^6.0.4", - "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-preset-es2015": "^6.24.1", - "babel-preset-es2015-generators-async": "^6.3.13", - "browserify": "^13.1.0", - "esdoc": "^1.1.0", - "mocha": "^2.5.3", - "uglifyjs": "^2.4.10" - } + "name": "peerplaysjs-lib", + "version": "0.4.24", + "description": "Pure JavaScript Peerplaysjs library for node.js and browsers.", + "browser": { + "ws": false, + "crypto": false + }, + "scripts": { + "test": "BABEL_ENV=test mocha --compilers js:babel-register --recursive", + "test:chain": "BABEL_ENV=test mocha --compilers js:babel-register ./test/chain --recursive", + "test:ecc": "BABEL_ENV=test mocha --compilers js:babel-register ./test/ecc --recursive", + "test:serializer": "BABEL_ENV=test mocha --compilers js:babel-register ./test/serializer --recursive", + "test:watch": "npm test -- --watch", + "clean": "rm -rf ./dist/* & rm -rf ./build/*", + "prebuild": "npm run clean", + "build": "babel lib -d dist", + "postbuild": "npm run browserify", + "build:watch": "babel lib -d dist --watch", + "prebrowserify": "rm -rf ./build/*", + "browserify": "browserify -t [browserify-package-json --global=true] -p [bundle-collapser/plugin] dist/browser.js --full-path=false --standalone peerplays_js -o build/peerplaysjs-lib.js -d", + "postbrowserify": "uglifyjs --compress --mangle --sequences --drop_console --output build/peerplaysjs-lib.min.js -- build/peerplaysjs-lib.js", + "doc": "esdoc -c esdoc.json", + "example:transfer": "babel-node examples/transfer", + "example:chainStore": "babel-node examples/chainStore", + "example:privKey": "babel-node examples/privKey" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/PBSA/peerplaysjs-lib" + }, + "author": "Sigve Kvalsvik (https://github.com/svk31)", + "contributors": [ + "James Calfee (https://github.com/jcalfee/)", + "Daniel Larimer (https://github.com/bytemaster/)", + "Valentine Zavgorodnev (https://github.com/valzav/)" + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/PBSA/peerplaysjs-lib/issues" + }, + "engines": { + "node": ">= 6.0.0" + }, + "main": "dist/index.js", + "jsnext:main": "lib/index.js", + "dependencies": { + "assert": "^1.3.0", + "bigi": "^1.4.1", + "bs58": "^3.0.0", + "buffer": "^5.1.0", + "bytebuffer": "^5.0.0", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "crypto-js": "^3.1.9-1", + "deep-equal": "^1.0.1", + "ecurve": "^1.0.2", + "event-emitter": "^0.3.4", + "immutable": "^3.7.6", + "peerplaysjs-ws": "git+ssh://git@github.com:PBSA/peerplaysjs-ws.git", + "secure-random": "^1.1.1" + }, + "devDependencies": { + "babel-cli": "^6.18.0", + "babel-core": "^6.21.0", + "babel-eslint": "^7.1.1", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-preset-es2015": "^6.18.0", + "babel-preset-stage-1": "^6.16.0", + "browserify": "^13.1.0", + "browserify-package-json": "^1.0.1", + "bundle-collapser": "^1.3.0", + "esdoc": "^1.1.0", + "eslint": "^4.19.1", + "eslint-config-airbnb": "^17.0.0", + "eslint-plugin-import": "^2.13.0", + "eslint-plugin-jsx-a11y": "^6.1.1", + "eslint-plugin-prettier": "^2.6.2", + "eslint-plugin-react": "^7.10.0", + "mocha": "^5.2.0", + "prettier": "^1.13.7", + "uglify-js": "^3.4.9" + } } From bb01e75e796d18905bdecc8f4c95de03cc2476b6 Mon Sep 17 00:00:00 2001 From: mseaward Date: Fri, 1 Feb 2019 15:19:18 -0400 Subject: [PATCH 07/15] Modified required modules for building with browserify --- lib/browser.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/browser.js b/lib/browser.js index 43551b8..65bcb4b 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -1,9 +1,17 @@ -module.exports = { - PrivateKey: require("./ecc/src/PrivateKey"), - PublicKey: require("./ecc/src/PublicKey"), - Signature: require("./ecc/src/signature"), - key: require("./ecc/src/KeyUtils"), - TransactionBuilder: require("./chain/src/TransactionBuilder"), - Login: require("./chain/src/AccountLogin"), - grapheneWS: require("peerplaysjs-ws") -} +import peerplaysjs_ws from 'peerplaysjs-ws'; +import PrivateKey from './ecc/src/PrivateKey'; +import PublicKey from './ecc/src/PublicKey'; +import Signature from './ecc/src/signature'; +import key from './ecc/src/KeyUtils'; +import TransactionBuilder from './chain/src/TransactionBuilder'; +import Login from './chain/src/AccountLogin'; + +export default { + PrivateKey, + PublicKey, + Signature, + key, + TransactionBuilder, + Login, + peerplaysjs_ws +}; From ce0810bc6fa813475592c24ca842735d13f8c3c3 Mon Sep 17 00:00:00 2001 From: mseaward Date: Fri, 1 Feb 2019 15:32:12 -0400 Subject: [PATCH 08/15] Update built files --- build/peerplaysjs-lib.js | 10582 ++++++++++++++------------------- build/peerplaysjs-lib.min.js | 2 +- lib/browser.js | 26 +- package-lock.json | 2007 +------ package.json | 151 +- 5 files changed, 4855 insertions(+), 7913 deletions(-) diff --git a/build/peerplaysjs-lib.js b/build/peerplaysjs-lib.js index d42ed5e..7ed675b 100644 --- a/build/peerplaysjs-lib.js +++ b/build/peerplaysjs-lib.js @@ -1,194 +1,161 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.peerplays_js = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i} [signer_pubkeys = null] - Optional ["GPHAbc9Def0...", ...]. These are - additional signing keys. Some balance claims require propritary address formats, the - witness node can't tell us which ones are needed so they must be passed in. If the - witness node can figure out a signing key (mostly all other transactions), it should - not be passed in here. - @arg {boolean} [broadcast = false] - */ + /** + This does it all: set fees, finalize, sign, and broadcast (if wanted). + @arg {ConfidentialWallet} cwallet - must be unlocked, used to gather signing keys + @arg {array} [signer_pubkeys = null] - Optional ["GPHAbc9Def0...", ...]. These are additional signing keys. Some balance claims require propritary address formats, the witness node can't tell us which ones are needed so they must be passed in. If the witness node can figure out a signing key (mostly all other transactions), it should not be passed in here. + @arg {boolean} [broadcast = false] + */ + }, { + key: "process_transaction", + value: function process_transaction(cwallet) { + var _this = this; + + var signer_pubkeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var broadcast = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + + var wallet_object = cwallet.wallet.wallet_object; + if (Apis.instance().chain_id !== wallet_object.get("chain_id")) return Promise.reject("Mismatched chain_id; expecting " + wallet_object.get("chain_id") + ", but got " + Apis.instance().chain_id); + + return this.set_required_fees().then(function () { + var signer_pubkeys_added = {}; + if (signer_pubkeys) { + + // Balance claims are by address, only the private + // key holder can know about these additional + // potential keys. + var pubkeys = cwallet.getPubkeys_having_PrivateKey(signer_pubkeys); + if (!pubkeys.length) throw new Error("Missing signing key"); + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = pubkeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var pubkey_string = _step.value; + + var private_key = cwallet.getPrivateKey(pubkey_string); + _this.add_signer(private_key, pubkey_string); + signer_pubkeys_added[pubkey_string] = true; + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + + return _this.get_potential_signatures().then(function (_ref) { + var pubkeys = _ref.pubkeys, + addys = _ref.addys; + + var my_pubkeys = cwallet.getPubkeys_having_PrivateKey(pubkeys, addys); + + //{//Testing only, don't send All public keys! + // var pubkeys_all = PrivateKeyStore.getPubkeys() // All public keys + // this.get_required_signatures(pubkeys_all).then( required_pubkey_strings => + // console.log('get_required_signatures all\t',required_pubkey_strings.sort(), pubkeys_all)) + // this.get_required_signatures(my_pubkeys).then( required_pubkey_strings => + // console.log('get_required_signatures normal\t',required_pubkey_strings.sort(), pubkeys)) + //} + + return _this.get_required_signatures(my_pubkeys).then(function (required_pubkeys) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = required_pubkeys[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var _pubkey_string = _step2.value; + + if (signer_pubkeys_added[_pubkey_string]) continue; + var private_key = cwallet.getPrivateKey(_pubkey_string); + if (!private_key) + // This should not happen, get_required_signatures will only + // returned keys from my_pubkeys + throw new Error("Missing signing key for " + _pubkey_string); + _this.add_signer(private_key, _pubkey_string); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + }); + }).then(function () { + return broadcast ? _this.broadcast() : _this.serialize(); + }); + }); + } - TransactionBuilder.prototype.process_transaction = function process_transaction(cwallet) { - var _this = this; + /** Typically this is called automatically just prior to signing. Once finalized this transaction can not be changed. */ + + }, { + key: "finalize", + value: function finalize() { + var _this2 = this; + + return new Promise(function (resolve, reject) { + + if (_this2.tr_buffer) { + throw new Error("already finalized"); + } + + resolve(Apis.instance().db_api().exec("get_objects", [["2.1.0"]]).then(function (r) { + head_block_time_string = r[0].time; + if (_this2.expiration === 0) _this2.expiration = base_expiration_sec() + ChainConfig.expire_in_secs; + _this2.ref_block_num = r[0].head_block_number & 0xFFFF; + _this2.ref_block_prefix = new Buffer(r[0].head_block_id, 'hex').readUInt32LE(4); + //DEBUG console.log("ref_block",@ref_block_num,@ref_block_prefix,r) + + var iterable = _this2.operations; + for (var i = 0, op; i < iterable.length; i++) { + op = iterable[i]; + if (op[1]["finalize"]) { + op[1].finalize(); + } + + var _type = ops.operation.st_operations[op[0]]; + var hexBuffer = _type.toBuffer(op[1]).toString("hex"); + console.log("Operation %s: %O => %s (%d bytes)", _type.operation_name, op[1], hexBuffer, hexBuffer.length / 2); + } + _this2.tr_buffer = ops.transaction.toBuffer(_this2); + })); + }); + } - var signer_pubkeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - var broadcast = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - var wallet_object = cwallet.wallet.wallet_object; + /** @return {string} hex transaction ID */ + }, { + key: "id", + value: function id() { + if (!this.tr_buffer) { + throw new Error("not finalized"); + } + return hash.sha256(this.tr_buffer).toString('hex').substring(0, 40); + } - if (_peerplaysjsWs.Apis.instance().chain_id !== wallet_object.get('chain_id')) { - var wallet_chain_id = wallet_object.get('chain_id'); - var api_chain_id = _peerplaysjsWs.Apis.instance().chain_id; + /** + Typically one will use {@link this.add_type_operation} instead. + @arg {array} operation - [operation_id, operation] + */ - var error = new Error('Mismatched chain_id; expecting ' + wallet_chain_id + ', but got ' + api_chain_id); + }, { + key: "add_operation", + value: function add_operation(operation) { + if (this.tr_buffer) { + throw new Error("already finalized"); + } + assert(operation, "operation"); + if (!Array.isArray(operation)) { + throw new Error("Expecting array [operation_id, operation]"); + } + this.operations.push(operation); + return; + } + }, { + key: "get_type_operation", + value: function get_type_operation(name, operation) { + if (this.tr_buffer) { + throw new Error("already finalized"); + } + assert(name, "name"); + assert(operation, "operation"); + var _type = ops[name]; + assert(_type, "Unknown operation " + name); + var operation_id = ChainTypes.operations[_type.operation_name]; + if (operation_id === undefined) { + throw new Error("unknown operation: " + _type.operation_name); + } + if (!operation.fee) { + operation.fee = { amount: 0, asset_id: 0 }; + } + if (name === 'proposal_create') { + operation.expiration_time || (operation.expiration_time = base_expiration_sec() + ChainConfig.expire_in_secs_proposal); + } + var operation_instance = _type.fromObject(operation); + return [operation_id, operation_instance]; + } - return Promise.reject(error); - } + /** optional: there is a deafult expiration */ - return this.set_required_fees().then(function () { - var signer_pubkeys_added = {}; + }, { + key: "set_expire_seconds", + value: function set_expire_seconds(sec) { + if (this.tr_buffer) { + throw new Error("already finalized"); + } + return this.expiration = base_expiration_sec() + sec; + } - if (signer_pubkeys) { - // Balance claims are by address, only the private - // key holder can know about these additional - // potential keys. - var pubkeys = cwallet.getPubkeys_having_PrivateKey(signer_pubkeys); + /* Wraps this transaction in a proposal_create transaction */ - if (!pubkeys.length) { - throw new Error('Missing signing key'); - } + }, { + key: "propose", + value: function propose(proposal_create_options) { + if (this.tr_buffer) { + throw new Error("already finalized"); + } + if (!this.operations.length) { + throw new Error("add operation first"); + } - var keys = Object.keys(pubkeys); + assert(proposal_create_options, "proposal_create_options"); + assert(proposal_create_options.fee_paying_account, "proposal_create_options.fee_paying_account"); - for (var i = 0, len = keys.length; i < len; i++) { - var pubkey_string = pubkeys[i]; - var private_key = cwallet.getPrivateKey(pubkey_string); - _this.add_signer(private_key, pubkey_string); - signer_pubkeys_added[pubkey_string] = true; + var proposed_ops = this.operations.map(function (op) { + return { op: op }; + }); + + this.operations = []; + this.signatures = []; + this.signer_private_keys = []; + proposal_create_options.proposed_ops = proposed_ops; + this.add_type_operation("proposal_create", proposal_create_options); + return this; } - } + }, { + key: "has_proposed_operation", + value: function has_proposed_operation() { + var hasProposed = false; + for (var i = 0; i < this.operations.length; i++) { + if ("proposed_ops" in this.operations[i][1]) { + hasProposed = true; + break; + } + } - return _this.get_potential_signatures().then(function (_ref) { - var pubkeys = _ref.pubkeys, - addys = _ref.addys; + return hasProposed; + } - var my_pubkeys = cwallet.getPubkeys_having_PrivateKey(pubkeys, addys); + /** optional: the fees can be obtained from the witness node */ - return _this.get_required_signatures(my_pubkeys).then(function (required_pubkeys) { - var keys = Object.keys(required_pubkeys); + }, { + key: "set_required_fees", + value: function set_required_fees(asset_id) { + var _this3 = this; - for (var _i = 0, _len = keys.length; _i < _len; _i++) { - var _pubkey_string = keys[_i]; + var fee_pool; + if (this.tr_buffer) { + throw new Error("already finalized"); + } + if (!this.operations.length) { + throw new Error("add operations first"); + } + var operations = []; + for (var i = 0, op; i < this.operations.length; i++) { + op = this.operations[i]; + operations.push(ops.operation.toObject(op)); + } - if (!signer_pubkeys_added[_pubkey_string]) { - var _private_key = cwallet.getPrivateKey(_pubkey_string); + if (!asset_id) { + var op1_fee = operations[0][1].fee; + if (op1_fee && op1_fee.asset_id !== null) { + asset_id = op1_fee.asset_id; + } else { + asset_id = "1.3.0"; + } + } - // This should not happen, get_required_signatures will only - // returned keys from my_pubkeys - if (!_private_key) { - throw new Error('Missing signing key for ' + _pubkey_string); - } + var promises = [Apis.instance().db_api().exec("get_required_fees", [operations, asset_id])]; - _this.add_signer(_private_key, _pubkey_string); + var feeAssetPromise = null; + if (asset_id !== "1.3.0") { + // This handles the fallback to paying fees in BTS if the fee pool is empty. + promises.push(Apis.instance().db_api().exec("get_required_fees", [operations, "1.3.0"])); + promises.push(Apis.instance().db_api().exec("get_objects", [[asset_id]])); } - } - }); - }).then(function () { - return broadcast ? _this.broadcast() : _this.serialize(); - }); - }); - }; - /** Typically this is called automatically just prior to signing. - * Once finalized this transaction can not be changed. */ + return Promise.all(promises).then(function (results) { + var _results = _slicedToArray(results, 3), + fees = _results[0], + coreFees = _results[1], + asset = _results[2]; + + asset = asset ? asset[0] : null; + + var dynamicPromise = asset_id !== "1.3.0" && asset ? Apis.instance().db_api().exec("get_objects", [[asset.dynamic_asset_data_id]]) : new Promise(function (resolve, reject) { + resolve(); + }); + + return dynamicPromise.then(function (dynamicObject) { + if (asset_id !== "1.3.0") { + fee_pool = dynamicObject ? dynamicObject[0].fee_pool : 0; + var totalFees = 0; + for (var j = 0, fee; j < coreFees.length; j++) { + fee = coreFees[j]; + totalFees += fee.amount; + } + + if (totalFees > parseInt(fee_pool, 10)) { + fees = coreFees; + asset_id = "1.3.0"; + } + } + + // Proposed transactions need to be flattened + var flat_assets = []; + var flatten = function flatten(obj) { + if (Array.isArray(obj)) { + for (var k = 0, item; k < obj.length; k++) { + item = obj[k]; + flatten(item); + } + } else { + flat_assets.push(obj); + } + return; + }; + flatten(fees); + + var asset_index = 0; + + var set_fee = function set_fee(operation) { + if (!operation.fee || operation.fee.amount === 0 || operation.fee.amount.toString && operation.fee.amount.toString() === "0" // Long + ) { + operation.fee = flat_assets[asset_index]; + // console.log("new operation.fee", operation.fee) + } else { + // console.log("old operation.fee", operation.fee) + } + asset_index++; + if (operation.proposed_ops) { + var result = []; + for (var y = 0; y < operation.proposed_ops.length; y++) { + result.push(set_fee(operation.proposed_ops[y].op[1])); + }return result; + } + }; + for (var _i = 0; _i < _this3.operations.length; _i++) { + set_fee(_this3.operations[_i][1]); + } + }); + //DEBUG console.log('... get_required_fees',operations,asset_id,flat_assets) + }); + } + }, { + key: "get_potential_signatures", + value: function get_potential_signatures() { + var tr_object = ops.signed_transaction.toObject(this); + return Promise.all([Apis.instance().db_api().exec("get_potential_signatures", [tr_object]), Apis.instance().db_api().exec("get_potential_address_signatures", [tr_object])]).then(function (results) { + return { pubkeys: results[0], addys: results[1] }; + }); + } + }, { + key: "get_required_signatures", + value: function get_required_signatures(available_keys) { + if (!available_keys.length) { + return Promise.resolve([]); + } + var tr_object = ops.signed_transaction.toObject(this); + //DEBUG console.log('... tr_object',tr_object) + return Apis.instance().db_api().exec("get_required_signatures", [tr_object, available_keys]).then(function (required_public_keys) { + //DEBUG console.log('... get_required_signatures',required_public_keys) + return required_public_keys; + }); + } + }, { + key: "add_signer", + value: function add_signer(private_key) { + var public_key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : private_key.toPublicKey(); + + assert(private_key.d, "required PrivateKey object"); - TransactionBuilder.prototype.finalize = function finalize() { - var _this2 = this; + if (this.signed) { + throw new Error("already signed"); + } + if (!public_key.Q) { + public_key = PublicKey.fromPublicKeyString(public_key); + } + // prevent duplicates + var spHex = private_key.toHex(); + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.signer_private_keys[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var sp = _step3.value; + + if (sp[0].toHex() === spHex) return; + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } - return new Promise(function (resolve) { - if (_this2.tr_buffer) { - throw new Error('already finalized'); - } + this.signer_private_keys.push([private_key, public_key]); + } + }, { + key: "sign", + value: function sign() { + var chain_id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Apis.instance().chain_id; - resolve(_peerplaysjsWs.Apis.instance().db_api().exec('get_objects', [['2.1.0']]).then(function (r) { - _this2.head_block_time_string = r[0].time; + if (!this.tr_buffer) { + throw new Error("not finalized"); + } + if (this.signed) { + throw new Error("already signed"); + } + if (!this.signer_private_keys.length) { + throw new Error("Transaction was not signed. Do you have a private key? [no_signers]"); + } + var end = this.signer_private_keys.length; + for (var i = 0; 0 < end ? i < end : i > end; 0 < end ? i++ : i++) { + var _signer_private_keys$ = _slicedToArray(this.signer_private_keys[i], 2), + private_key = _signer_private_keys$[0], + public_key = _signer_private_keys$[1]; + + var sig = Signature.signBuffer(Buffer.concat([new Buffer(chain_id, 'hex'), this.tr_buffer]), private_key, public_key); + this.signatures.push(sig.toBuffer()); + } + this.signer_private_keys = []; + this.signed = true; + return; + } + }, { + key: "serialize", + value: function serialize() { + return ops.signed_transaction.toObject(this); + } + }, { + key: "toObject", + value: function toObject() { + return ops.signed_transaction.toObject(this); + } + }, { + key: "broadcast", + value: function broadcast(was_broadcast_callback) { + var _this4 = this; - if (_this2.expiration === 0) { - _this2.expiration = _this2.base_expiration_sec() + _peerplaysjsWs.ChainConfig.expire_in_secs; + if (this.tr_buffer) { + return this._broadcast(was_broadcast_callback); + } else { + return this.finalize().then(function () { + return _this4._broadcast(was_broadcast_callback); + }); + } } + }]); - _this2.ref_block_num = r[0].head_block_number & 0xffff; // eslint-disable-line - _this2.ref_block_prefix = Buffer.from(r[0].head_block_id, 'hex').readUInt32LE(4); - // DEBUG console.log("ref_block",@ref_block_num,@ref_block_prefix,r) + return TransactionBuilder; +}(); - var iterable = _this2.operations; +var base_expiration_sec = function base_expiration_sec() { + var head_block_sec = Math.ceil(getHeadBlockDate().getTime() / 1000); + var now_sec = Math.ceil(Date.now() / 1000); + // The head block time should be updated every 3 seconds. If it isn't + // then help the transaction to expire (use head_block_sec) + if (now_sec - head_block_sec > 30) { + return head_block_sec; + } + // If the user's clock is very far behind, use the head block time. + return Math.max(now_sec, head_block_sec); +}; - for (var i = 0, len = iterable.length; i < len; i++) { - var op = iterable[i]; +function _broadcast(was_broadcast_callback) { + var _this5 = this; - if (op[1].finalize) { - op[1].finalize(); - } + return new Promise(function (resolve, reject) { - var _type = _serializer.ops.operation.st_operations[op[0]]; - var hexBuffer = _type.toBuffer(op[1]).toString('hex'); - console.log('Operation %s: %O => %s (%d bytes)', _type.operation_name, op[1], hexBuffer, hexBuffer.length / 2); + if (!_this5.signed) { + _this5.sign(); + } + if (!_this5.tr_buffer) { + throw new Error("not finalized"); + } + if (!_this5.signatures.length) { + throw new Error("not signed"); + } + if (!_this5.operations.length) { + throw new Error("no operations"); } - _this2.tr_buffer = _serializer.ops.transaction.toBuffer(_this2); - })); + var tr_object = ops.signed_transaction.toObject(_this5); + // console.log('... broadcast_transaction_with_callback !!!') + Apis.instance().network_api().exec("broadcast_transaction_with_callback", [function (res) { + return resolve(res); + }, tr_object]).then(function () { + //console.log('... broadcast success, waiting for callback') + if (was_broadcast_callback) was_broadcast_callback(); + return; + }).catch(function (error) { + // console.log may be redundant for network errors, other errors could occur + console.log(error); + var message = error.message; + if (!message) { + message = ""; + } + reject(new Error(message + "\n" + 'graphene-crypto ' + ' digest ' + hash.sha256(_this5.tr_buffer).toString('hex') + ' transaction ' + _this5.tr_buffer.toString('hex') + ' ' + JSON.stringify(tr_object))); + return; + }); + return; }); - }; +} - /** @return {string} hex transaction ID */ +function getHeadBlockDate() { + return timeStringToDate(head_block_time_string); +} +function timeStringToDate(time_string) { + if (!time_string) return new Date("1970-01-01T00:00:00.000Z"); + if (!/Z$/.test(time_string)) //does not end in Z + // https://github.com/cryptonomex/graphene/issues/368 + time_string = time_string + "Z"; + return new Date(time_string); +} - TransactionBuilder.prototype.id = function id() { - if (!this.tr_buffer) { - throw new Error('not finalized'); - } +module.exports = TransactionBuilder; +}).call(this,require("buffer").Buffer) - return _ecc.hash.sha256(this.tr_buffer).toString('hex').substring(0, 40); - }; +},{"../../ecc":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/index.js","../../serializer":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/index.js","./ChainTypes":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/chain/src/ChainTypes.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","peerplaysjs-ws":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/chain/src/state.js":[function(require,module,exports){ +"use strict"; - /** - Typically one will use {@link this.add_type_operation} instead. - @arg {array} operation - [operation_id, operation] - */ +function get(state) { + return function (key) { + return state[key] || ""; + }; +} +function set(state) { + return function (key, value) { + state[key] = value; + return this; + }; +} - TransactionBuilder.prototype.add_operation = function add_operation(operation) { - if (this.tr_buffer) { - throw new Error('already finalized'); - } +module.exports = { + get: get, + set: set +}; +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/index.js":[function(require,module,exports){ +"use strict"; - (0, _assert2.default)(operation, 'operation'); +module.exports = { + Address: require("./src/address"), + Aes: require("./src/aes"), + PrivateKey: require("./src/PrivateKey"), + PublicKey: require("./src/PublicKey"), + Signature: require("./src/signature"), + brainKey: require("./src/BrainKey"), + hash: require("./src/hash"), + key: require("./src/KeyUtils") +}; +},{"./src/BrainKey":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/BrainKey.js","./src/KeyUtils":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/KeyUtils.js","./src/PrivateKey":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PrivateKey.js","./src/PublicKey":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PublicKey.js","./src/address":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/address.js","./src/aes":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/aes.js","./src/hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/hash.js","./src/signature":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/signature.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/BrainKey.js":[function(require,module,exports){ +'use strict'; - if (!Array.isArray(operation)) { - throw new Error('Expecting array [operation_id, operation]'); +module.exports = function normalize(brainKey) { + if (typeof brainKey !== 'string') { + throw new Error("string required for brainKey"); } + brainKey = brainKey.trim(); + return brainKey.split(/[\t\n\v\f\r ]+/).join(' '); +}; +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/KeyUtils.js":[function(require,module,exports){ +(function (Buffer){ +'use strict'; - this.operations.push(operation); - }; - - TransactionBuilder.prototype.get_type_operation = function get_type_operation(name, operation) { - if (this.tr_buffer) { - throw new Error('already finalized'); - } +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; 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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - (0, _assert2.default)(name, 'name'); - (0, _assert2.default)(operation, 'operation'); - var _type = _serializer.ops[name]; - (0, _assert2.default)(_type, 'Unknown operation ' + name); - var operation_id = _ChainTypes2.default.operations[_type.operation_name]; +var key; +var PrivateKey = require('./PrivateKey'); +var PublicKey = require('./PublicKey'); +var Address = require('./address'); +var Aes = require('./aes'); - if (operation_id === undefined) { - throw new Error('unknown operation: ' + _type.operation_name); - } +var hash = require('./hash'); +// var dictionary = require('./dictionary_en'); +var secureRandom = require('secure-random'); - if (!operation.fee) { - operation.fee = { amount: 0, asset_id: 0 }; - } +var _require = require('peerplaysjs-ws'), + ChainConfig = _require.ChainConfig; - if (name === 'proposal_create') { - /* - * Proposals involving the committee account require a review - * period to be set, look for them here - */ - var requiresReview = false; - var extraReview = 0; - - operation.proposed_ops.forEach(function (op) { - var COMMITTE_ACCOUNT = 0; - var key = void 0; - - switch (op.op[0]) { - case 0: - // transfer - key = 'from'; - break; - - case 6: // account_update - case 17: - // asset_settle - key = 'account'; - break; - - case 10: // asset_create - case 11: // asset_update - case 12: // asset_update_bitasset - case 13: // asset_update_feed_producers - case 14: // asset_issue - case 18: // asset_global_settle - case 43: - // asset_claim_fees - key = 'issuer'; - break; - - case 15: - // asset_reserve - key = 'payer'; - break; - - case 16: - // asset_fund_fee_pool - key = 'from_account'; - break; - - case 22: // proposal_create - case 23: // proposal_update - case 24: - // proposal_delete - key = 'fee_paying_account'; - break; - - case 31: - // committee_member_update_global_parameters - requiresReview = true; - extraReview = 60 * 60 * 24 * 13; // Make the review period 2 weeks total - break; - default: - break; - } +// hash for .25 second - if (key in op.op[1] && op.op[1][key] === COMMITTE_ACCOUNT) { - requiresReview = true; - } - }); - if (!operation.expiration_time) { - var experationTime = this.base_expiration_sec(); - operation.expiration_time = experationTime + _peerplaysjsWs.ChainConfig.expire_in_secs_proposal; - } +var HASH_POWER_MILLS = 250; - if (requiresReview) { - var one_day = 24 * 60 * 60; // One day in seconds - var max = Math.max(this.commitee_min_review, one_day, _peerplaysjsWs.ChainConfig.review_in_secs_committee); +module.exports = key = { - operation.review_period_seconds = extraReview + max; - /* - * Expiration time must be at least equal to - * now + review_period_seconds, so we add one hour to make sure - */ - operation.expiration_time += 60 * 60 + extraReview; - } + /** Uses 1 second of hashing power to create a key/password checksum. An + implementation can re-call this method with the same password to re-match + the strength of the CPU (either after moving from a desktop to a mobile, + mobile to desktop, or N years from now when CPUs are presumably stronger). + A salt is used for all the normal reasons... + @return object { + aes_private: Aes, + checksum: "{hash_iteration_count},{salt},{checksum}" } + */ + aes_checksum: function aes_checksum(password) { + if (!(typeof password === "string")) { + throw new "password string required"(); + } + var salt = secureRandom.randomBuffer(4).toString('hex'); + var iterations = 0; + var secret = salt + password; + // hash for .1 second + var start_t = Date.now(); + while (Date.now() - start_t < HASH_POWER_MILLS) { + secret = hash.sha256(secret); + iterations += 1; + } - var operation_instance = _type.fromObject(operation); - return [operation_id, operation_instance]; - }; - - /* optional: fetch the current head block */ - - TransactionBuilder.prototype.update_head_block = function update_head_block() { - var _this3 = this; - - return _peerplaysjsWs.Apis.instance().db_api().exec('get_objects', [['2.0.0', '2.1.0']]).then(function (res) { - var g = res[0], - r = res[1]; + var checksum = hash.sha256(secret); + var checksum_string = [iterations, salt.toString('hex'), checksum.slice(0, 4).toString('hex')].join(','); - _this3.head_block_time_string = r[0].time; - _this3.committee_min_review = g[0].parameters.committee_proposal_review_period; - }); - }; + return { aes_private: Aes.fromSeed(secret), + checksum: checksum_string + }; + }, - /** optional: there is a deafult expiration */ + /** Provide a matching password and key_checksum. A "wrong password" + error is thrown if the password does not match. If this method takes + much more or less than 1 second to return, one should consider updating + all encyrpted fields using a new key.key_checksum. + */ + aes_private: function aes_private(password, key_checksum) { + var _key_checksum$split = key_checksum.split(','), + _key_checksum$split2 = _slicedToArray(_key_checksum$split, 3), + iterations = _key_checksum$split2[0], + salt = _key_checksum$split2[1], + checksum = _key_checksum$split2[2]; + + var secret = salt + password; + for (var i = 0; 0 < iterations ? i < iterations : i > iterations; 0 < iterations ? i++ : i++) { + secret = hash.sha256(secret); + } + var new_checksum = hash.sha256(secret); + if (!(new_checksum.slice(0, 4).toString('hex') === checksum)) { + throw new Error("wrong password"); + } + return Aes.fromSeed(secret); + }, - TransactionBuilder.prototype.set_expire_seconds = function set_expire_seconds(sec) { - if (this.tr_buffer) { - throw new Error('already finalized'); - } - this.expiration = this.base_expiration_sec() + sec; + /** + A week random number generator can run out of entropy. This should ensure even the worst random number implementation will be reasonably safe. + @param1 string entropy of at least 32 bytes + */ + random32ByteBuffer: function random32ByteBuffer() { + var entropy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.browserEntropy(); - return this.expiration; - }; - /* Wraps this transaction in a proposal_create transaction */ + if (!(typeof entropy === 'string')) { + throw new Error("string required for entropy"); + } + if (entropy.length < 32) { + throw new Error("expecting at least 32 bytes of entropy"); + } - TransactionBuilder.prototype.propose = function propose(proposal_create_options) { - if (this.tr_buffer) { - throw new Error('already finalized'); - } + var start_t = Date.now(); - if (!this.operations.length) { - throw new Error('add operation first'); - } + while (Date.now() - start_t < HASH_POWER_MILLS) { + entropy = hash.sha256(entropy); + }var hash_array = []; + hash_array.push(entropy); - (0, _assert2.default)(proposal_create_options, 'proposal_create_options'); - (0, _assert2.default)(proposal_create_options.fee_paying_account, 'proposal_create_options.fee_paying_account'); + // Hashing for 1 second may helps the computer is not low on entropy (this method may be called back-to-back). + hash_array.push(secureRandom.randomBuffer(32)); - var proposed_ops = this.operations.map(function (op) { - return { op: op }; - }); + return hash.sha256(Buffer.concat(hash_array)); + }, - this.operations = []; - this.signatures = []; - this.signer_private_keys = []; - proposal_create_options.proposed_ops = proposed_ops; - this.add_type_operation('proposal_create', proposal_create_options); - return this; - }; - TransactionBuilder.prototype.has_proposed_operation = function has_proposed_operation() { - var hasProposed = false; + suggest_brain_key: function suggest_brain_key() { + var dictionary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ","; + var entropy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.browserEntropy(); - for (var i = 0; i < this.operations.length; i++) { - if ('proposed_ops' in this.operations[i][1]) { - hasProposed = true; - break; - } - } - return hasProposed; - }; + var randomBuffer = this.random32ByteBuffer(entropy); + + var word_count = 16; + var dictionary_lines = dictionary.split(','); - /** optional: the fees can be obtained from the witness node */ + if (!(dictionary_lines.length === 49744)) { + throw new Error('expecting ' + 49744 + ' but got ' + dictionary_lines.length + ' dictionary words'); + } + var brainkey = []; + var end = word_count * 2; - TransactionBuilder.prototype.set_required_fees = function set_required_fees(asset_id) { - var _this4 = this; + for (var i = 0; i < end; i += 2) { - var fee_pool = void 0; + // randomBuffer has 256 bits / 16 bits per word == 16 words + var num = (randomBuffer[i] << 8) + randomBuffer[i + 1]; - if (this.tr_buffer) { - throw new Error('already finalized'); - } + // convert into a number between 0 and 1 (inclusive) + var rndMultiplier = num / Math.pow(2, 16); + var wordIndex = Math.round(dictionary_lines.length * rndMultiplier); - if (!this.operations.length) { - throw new Error('add operations first'); - } + brainkey.push(dictionary_lines[wordIndex]); + } + return this.normalize_brainKey(brainkey.join(' ')); + }, - var operations = []; + get_random_key: function get_random_key(entropy) { + return PrivateKey.fromBuffer(this.random32ByteBuffer(entropy)); + }, + get_brainPrivateKey: function get_brainPrivateKey(brainKey) { + var sequence = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - for (var i = 0, len = this.operations.length; i < len; i++) { - var op = this.operations[i]; - operations.push(_serializer.ops.operation.toObject(op)); - } + if (sequence < 0) { + throw new Error("invalid sequence"); + } + brainKey = key.normalize_brainKey(brainKey); + return PrivateKey.fromBuffer(hash.sha256(hash.sha512(brainKey + " " + sequence))); + }, - if (!asset_id) { - var op1_fee = operations[0][1].fee; - if (op1_fee && op1_fee.asset_id !== null) { - asset_id = op1_fee.asset_id; - } else { - asset_id = '1.3.0'; - } - } + // Turn invisible space like characters into a single space + normalize_brainKey: function normalize_brainKey(brainKey) { + if (!(typeof brainKey === 'string')) { + throw new Error("string required for brainKey"); + } - var promises = [_peerplaysjsWs.Apis.instance().db_api().exec('get_required_fees', [operations, asset_id])]; + brainKey = brainKey.trim(); + return brainKey.split(/[\t\n\v\f\r ]+/).join(' '); + }, + browserEntropy: function browserEntropy() { - if (asset_id !== '1.3.0') { - // This handles the fallback to paying fees in BTS if the fee pool is empty. - promises.push(_peerplaysjsWs.Apis.instance().db_api().exec('get_required_fees', [operations, '1.3.0'])); - promises.push(_peerplaysjsWs.Apis.instance().db_api().exec('get_objects', [[asset_id]])); - } + var entropyStr = ""; + try { + entropyStr = new Date().toString() + " " + window.screen.height + " " + window.screen.width + " " + window.screen.colorDepth + " " + " " + window.screen.availHeight + " " + window.screen.availWidth + " " + window.screen.pixelDepth + navigator.language + " " + window.location + " " + window.history.length; - return Promise.all(promises).then(function (results) { - var fees = results[0], - coreFees = results[1], - asset = results[2]; + for (var i = 0, mimeType; i < navigator.mimeTypes.length; i++) { + mimeType = navigator.mimeTypes[i]; + entropyStr += mimeType.description + " " + mimeType.type + " " + mimeType.suffixes + " "; + } + console.log("INFO\tbrowserEntropy gathered"); + } catch (error) { + //nodejs:ReferenceError: window is not defined + entropyStr = hash.sha256(new Date().toString()); + } - asset = asset ? asset[0] : null; + var b = new Buffer(entropyStr); + entropyStr += b.toString('binary') + " " + new Date().toString(); + return entropyStr; + }, - var dynamicPromise = asset_id !== '1.3.0' && asset ? _peerplaysjsWs.Apis.instance().db_api().exec('get_objects', [[asset.dynamic_asset_data_id]]) : new Promise(function (resolve) { - resolve(); - }); - return dynamicPromise.then(function (dynamicObject) { - if (asset_id !== '1.3.0') { - fee_pool = dynamicObject ? dynamicObject[0].fee_pool : 0; - var totalFees = 0; + // @return array of 5 legacy addresses for a pubkey string parameter. + addresses: function addresses(pubkey) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ChainConfig.address_prefix; - for (var j = 0, fee; j < coreFees.length; j++) { - fee = coreFees[j]; - totalFees += fee.amount; - } + var public_key = PublicKey.fromPublicKeyString(pubkey, address_prefix); + // S L O W + var address_string = [Address.fromPublic(public_key, false, 0).toString(address_prefix), // btc_uncompressed + Address.fromPublic(public_key, true, 0).toString(address_prefix), // btc_compressed + Address.fromPublic(public_key, false, 56).toString(address_prefix), // pts_uncompressed + Address.fromPublic(public_key, true, 56).toString(address_prefix), // pts_compressed + public_key.toAddressString(address_prefix) // bts_short, most recent format + ]; + return address_string; + } +}; +}).call(this,require("buffer").Buffer) - if (totalFees > parseInt(fee_pool, 10)) { - fees = coreFees; - asset_id = '1.3.0'; - } - } +},{"./PrivateKey":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PrivateKey.js","./PublicKey":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PublicKey.js","./address":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/address.js","./aes":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/aes.js","./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/hash.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","peerplaysjs-ws":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/index.js","secure-random":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/secure-random/lib/secure-random.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PrivateKey.js":[function(require,module,exports){ +(function (Buffer){ +'use strict'; - // Proposed transactions need to be flattened - var flat_assets = []; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - var flatten = function flatten(obj) { - if (Array.isArray(obj)) { - for (var k = 0, _len2 = obj.length; k < _len2; k++) { - var item = obj[k]; - flatten(item); - } - } else { - flat_assets.push(obj); - } - }; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - flatten(fees); +var ecurve = require('ecurve'); - var asset_index = 0; +var _require = require('ecurve'), + Point = _require.Point, + getCurveByName = _require.getCurveByName; - var set_fee = function set_fee(operation) { - if (!operation.fee || operation.fee.amount === 0 || operation.fee.amount.toString && operation.fee.amount.toString() === '0' // Long - ) { - operation.fee = flat_assets[asset_index]; - // console.log("new operation.fee", operation.fee) - } else { - // console.log("old operation.fee", operation.fee) - } +var secp256k1 = getCurveByName('secp256k1'); +var BigInteger = require('bigi'); - asset_index++; +var _require2 = require('bs58'), + encode = _require2.encode, + decode = _require2.decode; - if (operation.proposed_ops) { - var result = []; +var assert = require('assert'); +var hash = require('./hash'); +var PublicKey = require('./PublicKey'); +var deepEqual = require("deep-equal"); - for (var y = 0; y < operation.proposed_ops.length; y++) { - result.push(set_fee(operation.proposed_ops[y].op[1])); - } +var G = secp256k1.G, + n = secp256k1.n; - return result; - } - }; +var PrivateKey = function () { - for (var _i2 = 0; _i2 < _this4.operations.length; _i2++) { - set_fee(_this4.operations[_i2][1]); + /** + @private see static functions + @param {BigInteger} + */ + function PrivateKey(d) { + _classCallCheck(this, PrivateKey); + + this.d = d; + } + + _createClass(PrivateKey, [{ + key: 'toWif', + value: function toWif() { + var private_key = this.toBuffer(); + // checksum includes the version + private_key = Buffer.concat([new Buffer([0x80]), private_key]); + var checksum = hash.sha256(private_key); + checksum = hash.sha256(checksum); + checksum = checksum.slice(0, 4); + var private_wif = Buffer.concat([private_key, checksum]); + return encode(private_wif); } - }); - // DEBUG console.log('... get_required_fees',operations,asset_id,flat_assets) - }); - }; - TransactionBuilder.prototype.get_potential_signatures = function get_potential_signatures() { - var tr_object = _serializer.ops.signed_transaction.toObject(this); - return Promise.all([_peerplaysjsWs.Apis.instance().db_api().exec('get_potential_signatures', [tr_object]), _peerplaysjsWs.Apis.instance().db_api().exec('get_potential_address_signatures', [tr_object])]).then(function (results) { - return { pubkeys: results[0], addys: results[1] }; - }); - }; + /** + @return {Point} + */ - TransactionBuilder.prototype.get_required_signatures = function get_required_signatures(available_keys) { - if (!available_keys.length) { - return Promise.resolve([]); - } + }, { + key: 'toPublicKeyPoint', + value: function toPublicKeyPoint() { + var Q; + return Q = secp256k1.G.multiply(this.d); + } + }, { + key: 'toPublicKey', + value: function toPublicKey() { + if (this.public_key) { + return this.public_key; + } + return this.public_key = PublicKey.fromPoint(this.toPublicKeyPoint()); + } + }, { + key: 'toBuffer', + value: function toBuffer() { + return this.d.toBuffer(32); + } - var tr_object = _serializer.ops.signed_transaction.toObject(this); - // DEBUG console.log('... tr_object',tr_object) - return _peerplaysjsWs.Apis.instance().db_api().exec('get_required_signatures', [tr_object, available_keys]).then(function (required_public_keys) { - return required_public_keys; - }); - }; + /** ECIES */ + + }, { + key: 'get_shared_secret', + value: function get_shared_secret(public_key) { + var legacy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + public_key = toPublic(public_key); + var KB = public_key.toUncompressed().toBuffer(); + var KBP = Point.fromAffine(secp256k1, BigInteger.fromBuffer(KB.slice(1, 33)), // x + BigInteger.fromBuffer(KB.slice(33, 65)) // y + ); + var r = this.toBuffer(); + var P = KBP.multiply(BigInteger.fromBuffer(r)); + var S = P.affineX.toBuffer({ size: 32 }); + /* + the input to sha512 must be exactly 32-bytes, to match the c++ implementation + of get_shared_secret. Right now S will be shorter if the most significant + byte(s) is zero. Pad it back to the full 32-bytes + */ + if (!legacy && S.length < 32) { + pad = new Buffer(32 - S.length).fill(0); + S = Buffer.concat([pad, S]); + } - TransactionBuilder.prototype.add_signer = function add_signer(private_key) { - var public_key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : private_key.toPublicKey(); + // SHA512 used in ECIES + return hash.sha512(S); + } - (0, _assert2.default)(private_key.d, 'required PrivateKey object'); + // /** ECIES (does not always match the Point.fromAffine version above) */ + // get_shared_secret(public_key){ + // public_key = toPublic(public_key) + // var P = public_key.Q.multiply( this.d ); + // var S = P.affineX.toBuffer({size: 32}); + // // ECIES, adds an extra sha512 + // return hash.sha512(S); + // } - if (this.signed) { - throw new Error('already signed'); - } + /** @throws {Error} - overflow of the key could not be derived */ - if (!public_key.Q) { - public_key = _ecc.PublicKey.fromPublicKeyString(public_key); - } + }, { + key: 'child', + value: function child(offset) { + offset = Buffer.concat([this.toPublicKey().toBuffer(), offset]); + offset = hash.sha256(offset); + var c = BigInteger.fromBuffer(offset); - // prevent duplicates - var spHex = private_key.toHex(); + if (c.compareTo(n) >= 0) throw new Error("Child offset went out of bounds, try again"); - var keys = Object.keys(this.signer_private_keys); + var derived = this.d.add(c); //.mod(n) - for (var i = 0, len = keys.length; i < len; i++) { - var sp = this.signer_private_keys[keys[i]]; + if (derived.signum() === 0) throw new Error("Child offset derived to an invalid key, try again"); - if (sp[0].toHex() === spHex) { - return; - } - } + return new PrivateKey(derived); + } - this.signer_private_keys.push([private_key, public_key]); - }; + /* */ - TransactionBuilder.prototype.sign = function sign() { - var chain_id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.Apis.instance().chain_id; + }, { + key: 'toByteBuffer', + value: function toByteBuffer() { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + } + }, { + key: 'toHex', + value: function toHex() { + return this.toBuffer().toString('hex'); + } - if (!this.tr_buffer) { - throw new Error('not finalized'); - } + /* */ - if (this.signed) { - throw new Error('already signed'); - } + }], [{ + key: 'fromBuffer', + value: function fromBuffer(buf) { + if (!Buffer.isBuffer(buf)) { + throw new Error("Expecting paramter to be a Buffer type"); + } + if (32 !== buf.length) { + console.log('WARN: Expecting 32 bytes, instead got ' + buf.length + ', stack trace:', new Error().stack); + } + if (buf.length === 0) { + throw new Error("Empty buffer"); + } + return new PrivateKey(BigInteger.fromBuffer(buf)); + } - if (!this.signer_private_keys.length) { - throw new Error('Transaction was not signed. Do you have a private key? [no_signers]'); - } + /** @arg {string} seed - any length string. This is private, the same seed produces the same private key every time. */ - var end = this.signer_private_keys.length; + }, { + key: 'fromSeed', + value: function fromSeed(seed) { + // generate_private_key + if (!(typeof seed === 'string')) { + throw new Error('seed must be of type string'); + } + return PrivateKey.fromBuffer(hash.sha256(seed)); + } - for (var i = 0; end > 0 ? i < end : i > end; end > 0 ? i++ : i++) { - var _signer_private_keys$ = this.signer_private_keys[i], - private_key = _signer_private_keys$[0], - public_key = _signer_private_keys$[1]; + /** @return {string} Wallet Import Format (still a secret, Not encrypted) */ + + }, { + key: 'fromWif', + value: function fromWif(_private_wif) { + var private_wif = new Buffer(decode(_private_wif)); + var version = private_wif.readUInt8(0); + assert.equal(0x80, version, 'Expected version ' + 0x80 + ', instead got ' + version); + // checksum includes the version + var private_key = private_wif.slice(0, -4); + var checksum = private_wif.slice(-4); + var new_checksum = hash.sha256(private_key); + new_checksum = hash.sha256(new_checksum); + new_checksum = new_checksum.slice(0, 4); + var isEqual = deepEqual(checksum, new_checksum); //, 'Invalid checksum' + if (!isEqual) { + throw new Error("Checksum did not match"); + } + private_key = private_key.slice(1); + private_key = private_key.slice(0, 32); + return PrivateKey.fromBuffer(private_key); + } + }, { + key: 'fromHex', + value: function fromHex(hex) { + return PrivateKey.fromBuffer(new Buffer(hex, 'hex')); + } + }]); - var sig = _ecc.Signature.signBuffer(Buffer.concat([Buffer.from(chain_id, 'hex'), this.tr_buffer]), private_key, public_key); - this.signatures.push(sig.toBuffer()); - } + return PrivateKey; +}(); - this.signer_private_keys = []; - this.signed = true; - }; +module.exports = PrivateKey; - TransactionBuilder.prototype.serialize = function serialize() { - return _serializer.ops.signed_transaction.toObject(this); - }; +var toPublic = function toPublic(data) { + return data == null ? data : data.Q ? data : PublicKey.fromStringOrThrow(data); +}; +}).call(this,require("buffer").Buffer) - TransactionBuilder.prototype.toObject = function toObject() { - return _serializer.ops.signed_transaction.toObject(this); - }; +},{"./PublicKey":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PublicKey.js","./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/hash.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/index.js","bs58":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bs58/index.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","deep-equal":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/deep-equal/index.js","ecurve":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PublicKey.js":[function(require,module,exports){ +(function (Buffer){ +'use strict'; - TransactionBuilder.prototype.broadcast = function broadcast(was_broadcast_callback) { - var _this5 = this; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - if (this.tr_buffer) { - return this._broadcast(was_broadcast_callback); - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - return this.finalize().then(function () { - return _this5._broadcast(was_broadcast_callback); - }); - }; +var BigInteger = require('bigi'); - TransactionBuilder.prototype._broadcast = function _broadcast(was_broadcast_callback) { - var _this6 = this; +var _require = require('ecurve'), + Point = _require.Point, + getCurveByName = _require.getCurveByName; - return new Promise(function (resolve, reject) { - if (!_this6.signed) { - _this6.sign(); - } +var secp256k1 = getCurveByName('secp256k1'); - if (!_this6.tr_buffer) { - throw new Error('not finalized'); - } +var _require2 = require('bs58'), + encode = _require2.encode, + decode = _require2.decode; - if (!_this6.signatures.length) { - throw new Error('not signed'); - } +var hash = require('./hash'); - if (!_this6.operations.length) { - throw new Error('no operations'); - } +var _require3 = require('peerplaysjs-ws'), + ChainConfig = _require3.ChainConfig; - var tr_object = _serializer.ops.signed_transaction.toObject(_this6); - // console.log('... broadcast_transaction_with_callback !!!') - _peerplaysjsWs.Apis.instance().network_api().exec('broadcast_transaction_with_callback', [function (res) { - return resolve(res); - }, tr_object]).then(function () { - // console.log('... broadcast success, waiting for callback') - if (was_broadcast_callback) { - was_broadcast_callback(); - } - }).catch(function (error) { - // console.log may be redundant for network errors, other errors could occur - console.log(error); - var message = error.message; +var assert = require('assert'); +var deepEqual = require("deep-equal"); +var G = secp256k1.G, + n = secp256k1.n; - if (!message) { - message = ''; - } +var PublicKey = function () { - reject(new Error(message + '\n' + 'peerplays-crypto ' + (' digest ' + _ecc.hash.sha256(_this6.tr_buffer).toString('hex') + ' transaction ' + _this6.tr_buffer.toString('hex') + ' ' + JSON.stringify(tr_object)))); - }); - }); - }; + /** @param {Point} public key */ + function PublicKey(Q) { + _classCallCheck(this, PublicKey); - TransactionBuilder.timeStringToDate = function timeStringToDate(time_string) { - if (!time_string) { - time_string = '1970-01-01T00:00:00.000Z'; + this.Q = Q; } - if (!/Z$/.test(time_string)) { - // does not end in Z - // https://github.com/cryptonomex/graphene/issues/368 - time_string += 'Z'; - } + _createClass(PublicKey, [{ + key: 'toBuffer', + value: function toBuffer() { + var compressed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.Q ? this.Q.compressed : null; - return new Date(time_string); - }; + if (this.Q === null) return new Buffer('000000000000000000000000000000000000000000000000000000000000000000', 'hex'); + return this.Q.getEncoded(compressed); + } + }, { + key: 'toUncompressed', + value: function toUncompressed() { + var buf = this.Q.getEncoded(false); + var point = Point.decodeFrom(secp256k1, buf); + return PublicKey.fromPoint(point); + } - TransactionBuilder.prototype.getHeadBlockDate = function getHeadBlockDate() { - return TransactionBuilder.timeStringToDate(this.head_block_time_string); - }; + /** bts::blockchain::address (unique but not a full public key) */ - TransactionBuilder.prototype.base_expiration_sec = function base_expiration_sec() { - var head_block_sec = Math.ceil(this.getHeadBlockDate().getTime() / 1000); - var now_sec = Math.ceil(Date.now() / 1000); + }, { + key: 'toBlockchainAddress', + value: function toBlockchainAddress() { + var pub_buf = this.toBuffer(); + var pub_sha = hash.sha512(pub_buf); + return hash.ripemd160(pub_sha); + } - // The head block time should be updated every 3 seconds. If it isn't - // then help the transaction to expire (use head_block_sec) - if (now_sec - head_block_sec > 30) { - return head_block_sec; - } + /** Alias for {@link toPublicKeyString} */ - // If the user's clock is very far behind, use the head block time. - return Math.max(now_sec, head_block_sec); - }; + }, { + key: 'toString', + value: function toString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChainConfig.address_prefix; - return TransactionBuilder; -}(); + return this.toPublicKeyString(address_prefix); + } -exports.default = TransactionBuilder; -module.exports = exports['default']; -}).call(this,require(35).Buffer) + /** + Full public key + {return} string + */ -},{"19":19,"27":27,"3":3,"35":35,"7":7,"70":70}],6:[function(require,module,exports){ -'use strict'; + }, { + key: 'toPublicKeyString', + value: function toPublicKeyString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChainConfig.address_prefix; -exports.__esModule = true; -function get(state) { - return function (key) { - return state[key] || ''; - }; -} + var pub_buf = this.toBuffer(); + var checksum = hash.ripemd160(pub_buf); + // Slice from the buffer directly, slicing from the checksum Uint8array will return the entire array each time. + var sliced = new Uint8Array(checksum.buffer.slice(0, 4)); -function set(state) { - var _this = this; + // concat only accepts buffers so initialize the sliced Uint8array as a Buffer. + var addy = Buffer.concat([pub_buf, Buffer.from(sliced)]); + return address_prefix + encode(addy); + } - return function (key, value) { - state[key] = value; - return _this; - }; -} + /** + @arg {string} public_key - like GPHXyz... + @arg {string} address_prefix - like GPH + @return PublicKey or `null` (if the public_key string is invalid) + */ -exports.get = get; -exports.set = set; -},{}],7:[function(require,module,exports){ -'use strict'; + }, { + key: 'toAddressString', + value: function toAddressString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChainConfig.address_prefix; + + var pub_buf = this.toBuffer(); + var pub_sha = hash.sha512(pub_buf); + var addy = hash.ripemd160(pub_sha); + var checksum = hash.ripemd160(addy); + addy = Buffer.concat([addy, checksum.slice(0, 4)]); + return address_prefix + encode(addy); + } + }, { + key: 'toPtsAddy', + value: function toPtsAddy() { + var pub_buf = this.toBuffer(); + var pub_sha = hash.sha256(pub_buf); + var addy = hash.ripemd160(pub_sha); + addy = Buffer.concat([new Buffer([0x38]), addy]); //version 56(decimal) + + var checksum = hash.sha256(addy); + checksum = hash.sha256(checksum); + + addy = Buffer.concat([addy, checksum.slice(0, 4)]); + return encode(addy); + } + }, { + key: 'child', + value: function child(offset) { -exports.__esModule = true; -exports.key = exports.hash = exports.brainKey = exports.Signature = exports.PublicKey = exports.PrivateKey = exports.Aes = exports.Address = undefined; + assert(Buffer.isBuffer(offset), "Buffer required: offset"); + assert.equal(offset.length, 32, "offset length"); -var _address = require(12); + offset = Buffer.concat([this.toBuffer(), offset]); + offset = hash.sha256(offset); -var _address2 = _interopRequireDefault(_address); + var c = BigInteger.fromBuffer(offset); -var _aes = require(13); + if (c.compareTo(n) >= 0) throw new Error("Child offset went out of bounds, try again"); -var _aes2 = _interopRequireDefault(_aes); + var cG = G.multiply(c); + var Qprime = this.Q.add(cG); -var _PrivateKey = require(10); + if (secp256k1.isInfinity(Qprime)) throw new Error("Child offset derived to an invalid key, try again"); -var _PrivateKey2 = _interopRequireDefault(_PrivateKey); + return PublicKey.fromPoint(Qprime); + } -var _PublicKey = require(11); + /* */ -var _PublicKey2 = _interopRequireDefault(_PublicKey); + }, { + key: 'toByteBuffer', + value: function toByteBuffer() { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + } + }, { + key: 'toHex', + value: function toHex() { + return this.toBuffer().toString('hex'); + } + }], [{ + key: 'fromBinary', + value: function fromBinary(bin) { + return PublicKey.fromBuffer(new Buffer(bin, 'binary')); + } + }, { + key: 'fromBuffer', + value: function fromBuffer(buffer) { + if (buffer.toString('hex') === '000000000000000000000000000000000000000000000000000000000000000000') return new PublicKey(null); + return new PublicKey(Point.decodeFrom(secp256k1, buffer)); + } + }, { + key: 'fromPoint', + value: function fromPoint(point) { + return new PublicKey(point); + } + }, { + key: 'fromPublicKeyString', + value: function fromPublicKeyString(public_key) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ChainConfig.address_prefix; + + try { + return PublicKey.fromStringOrThrow(public_key, address_prefix); + } catch (e) { + return null; + } + } -var _signature = require(18); + /** + @arg {string} public_key - like GPHXyz... + @arg {string} address_prefix - like GPH + @throws {Error} if public key is invalid + @return PublicKey + */ -var _signature2 = _interopRequireDefault(_signature); + }, { + key: 'fromStringOrThrow', + value: function fromStringOrThrow(public_key) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ChainConfig.address_prefix; + + var prefix = public_key.slice(0, address_prefix.length); + assert.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix); + public_key = public_key.slice(address_prefix.length); + + public_key = new Buffer(decode(public_key), 'binary'); + var checksum = public_key.slice(-4); + public_key = public_key.slice(0, -4); + var new_checksum = hash.ripemd160(public_key); + new_checksum = new_checksum.slice(0, 4); + var isEqual = deepEqual(checksum, new_checksum); //, 'Invalid checksum' + if (!isEqual) { + throw new Error("Checksum did not match"); + } + return PublicKey.fromBuffer(public_key); + } + }, { + key: 'fromHex', + value: function fromHex(hex) { + return PublicKey.fromBuffer(new Buffer(hex, 'hex')); + } + }, { + key: 'fromPublicKeyStringHex', + value: function fromPublicKeyStringHex(hex) { + return PublicKey.fromPublicKeyString(new Buffer(hex, 'hex')); + } -var _BrainKey = require(8); + /* */ -var _BrainKey2 = _interopRequireDefault(_BrainKey); + }]); -var _hash = require(17); + return PublicKey; +}(); -var hash = _interopRequireWildcard(_hash); +module.exports = PublicKey; +}).call(this,require("buffer").Buffer) -var _KeyUtils = require(9); +},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/hash.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/index.js","bs58":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bs58/index.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","deep-equal":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/deep-equal/index.js","ecurve":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/index.js","peerplaysjs-ws":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/address.js":[function(require,module,exports){ +(function (Buffer){ +'use strict'; -var _KeyUtils2 = _interopRequireDefault(_KeyUtils); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var assert = require('assert'); -exports.Address = _address2.default; -exports.Aes = _aes2.default; -exports.PrivateKey = _PrivateKey2.default; -exports.PublicKey = _PublicKey2.default; -exports.Signature = _signature2.default; -exports.brainKey = _BrainKey2.default; -exports.hash = hash; -exports.key = _KeyUtils2.default; -},{"10":10,"11":11,"12":12,"13":13,"17":17,"18":18,"8":8,"9":9}],8:[function(require,module,exports){ -'use strict'; +var _require = require('peerplaysjs-ws'), + ChainConfig = _require.ChainConfig; -exports.__esModule = true; -exports.default = normalize; -function normalize(brainKey) { - if (typeof brainKey !== 'string') { - throw new Error('string required for brainKey'); - } +var hash = require('./hash'); - brainKey = brainKey.trim(); - return brainKey.split(/[\t\n\v\f\r ]+/).join(' '); -} -module.exports = exports['default']; -},{}],9:[function(require,module,exports){ -(function (Buffer){ -'use strict'; +var _require2 = require('bs58'), + encode = _require2.encode, + decode = _require2.decode; -exports.__esModule = true; +var deepEqual = require("deep-equal"); -var _secureRandom = require(94); +/** Addresses are shortened non-reversable hashes of a public key. The full PublicKey is preferred. + @deprecated +*/ -var _secureRandom2 = _interopRequireDefault(_secureRandom); +var Address = function () { + function Address(addy) { + _classCallCheck(this, Address); -var _peerplaysjsWs = require(70); + this.addy = addy; + } -var _PrivateKey = require(10); + _createClass(Address, [{ + key: 'toBuffer', + value: function toBuffer() { + return this.addy; + } + }, { + key: 'toString', + value: function toString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChainConfig.address_prefix; + + var checksum = hash.ripemd160(this.addy); + var addy = Buffer.concat([this.addy, checksum.slice(0, 4)]); + return address_prefix + encode(addy); + } + }], [{ + key: 'fromBuffer', + value: function fromBuffer(buffer) { + var _hash = hash.sha512(buffer); + var addy = hash.ripemd160(_hash); + return new Address(addy); + } + }, { + key: 'fromString', + value: function fromString(string) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ChainConfig.address_prefix; + + var prefix = string.slice(0, address_prefix.length); + assert.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix); + var addy = string.slice(address_prefix.length); + addy = new Buffer(decode(addy), 'binary'); + var checksum = addy.slice(-4); + addy = addy.slice(0, -4); + var new_checksum = hash.ripemd160(addy); + new_checksum = new_checksum.slice(0, 4); + var isEqual = deepEqual(checksum, new_checksum); //, 'Invalid checksum' + if (!isEqual) { + throw new Error("Checksum did not match"); + } + return new Address(addy); + } + }, { + key: 'fromPublic', + + + /** @return Address - Compressed PTS format (by default) */ + value: function fromPublic(public_key) { + var compressed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var version = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 56; + + var sha2 = hash.sha256(public_key.toBuffer(compressed)); + var rep = hash.ripemd160(sha2); + var versionBuffer = new Buffer(1); + versionBuffer.writeUInt8(0xFF & version, 0); + var addr = Buffer.concat([versionBuffer, rep]); + var check = hash.sha256(addr); + check = hash.sha256(check); + var buffer = Buffer.concat([addr, check.slice(0, 4)]); + return new Address(hash.ripemd160(buffer)); + } + }]); -var _PrivateKey2 = _interopRequireDefault(_PrivateKey); + return Address; +}(); -var _PublicKey = require(11); +module.exports = Address; +}).call(this,require("buffer").Buffer) -var _PublicKey2 = _interopRequireDefault(_PublicKey); +},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/hash.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","bs58":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bs58/index.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","deep-equal":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/deep-equal/index.js","peerplaysjs-ws":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/aes.js":[function(require,module,exports){ +(function (Buffer){ +"use strict"; -var _address = require(12); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -var _address2 = _interopRequireDefault(_address); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var _aes = require(13); +// https://code.google.com/p/crypto-js +var AES = require("crypto-js/aes"); +var encHex = require("crypto-js/enc-hex"); +var encBase64 = require("crypto-js/enc-base64"); +var assert = require("assert"); -var _aes2 = _interopRequireDefault(_aes); +var _require = require("bytebuffer"), + Long = _require.Long; -var _hash = require(17); +var hash = require('./hash'); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/** Provides symetric encrypt and decrypt via AES. */ -// import dictionary from './dictionary_en'; +var Aes = function () { -// hash for .25 second -var HASH_POWER_MILLS = 250; + /** @private */ + function Aes(iv, key) { + _classCallCheck(this, Aes); -var key = { - /** Uses 1 second of hashing power to create a key/password checksum. An - implementation can re-call this method with the same password to re-match - the strength of the CPU (either after moving from a desktop to a mobile, - mobile to desktop, or N years from now when CPUs are presumably stronger). - A salt is used for all the normal reasons... - @return object { - aes_private: Aes, - checksum: "{hash_iteration_count},{salt},{checksum}" - } - */ - aes_checksum: function aes_checksum(password) { - if (!(typeof password === 'string')) { - throw new 'password string required'(); + this.iv = iv, this.key = key; } - var salt = _secureRandom2.default.randomBuffer(4).toString('hex'); - var iterations = 0; - var secret = salt + password; - // hash for .1 second - var start_t = Date.now(); + /** This is an excellent way to ensure that all references to Aes can not operate anymore (example: a wallet becomes locked). An application should ensure there is only one Aes object instance for a given secret `seed`. */ - while (Date.now() - start_t < HASH_POWER_MILLS) { - secret = (0, _hash.sha256)(secret); - iterations += 1; - } - var checksum = (0, _hash.sha256)(secret); - var checksum_string = [iterations, salt.toString('hex'), checksum.slice(0, 4).toString('hex')].join(','); + _createClass(Aes, [{ + key: "clear", + value: function clear() { + return this.iv = this.key = undefined; + } - return { - aes_private: _aes2.default.fromSeed(secret), - checksum: checksum_string - }; - }, + /** @arg {string} seed - secret seed may be used to encrypt or decrypt. */ + }, { + key: "_decrypt_word_array", - /** Provide a matching password and key_checksum. A "wrong password" - error is thrown if the password does not match. If this method takes - much more or less than 1 second to return, one should consider updating - all encyrpted fields using a new key.key_checksum. - */ - aes_private: function aes_private(password, key_checksum) { - var _key_checksum$split = key_checksum.split(','), - iterations = _key_checksum$split[0], - salt = _key_checksum$split[1], - checksum = _key_checksum$split[2]; - var secret = salt + password; + /** @private */ + value: function _decrypt_word_array(cipher) { + // https://code.google.com/p/crypto-js/#Custom_Key_and_IV + // see wallet_records.cpp master_key::decrypt_key + return AES.decrypt({ ciphertext: cipher, salt: null }, this.key, { iv: this.iv }); + } - for (var i = 0; iterations > 0 ? i < iterations : i > iterations; iterations > 0 ? i++ : i++) { - secret = (0, _hash.sha256)(secret); - } + /** @private */ - var new_checksum = (0, _hash.sha256)(secret); + }, { + key: "_encrypt_word_array", + value: function _encrypt_word_array(plaintext) { + //https://code.google.com/p/crypto-js/issues/detail?id=85 + var cipher = AES.encrypt(plaintext, this.key, { iv: this.iv }); + return encBase64.parse(cipher.toString()); + } - if (!(new_checksum.slice(0, 4).toString('hex') === checksum)) { - throw new Error('wrong password'); - } + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} ciphertext + @return {Buffer} binary + */ - return _aes2.default.fromSeed(secret); - }, + }, { + key: "decrypt", + value: function decrypt(ciphertext) { + if (typeof ciphertext === "string") { + ciphertext = new Buffer(ciphertext, 'binary'); + } + if (!Buffer.isBuffer(ciphertext)) { + throw new Error("buffer required"); + } + assert(ciphertext, "Missing cipher text"); + // hex is the only common format + var hex = this.decryptHex(ciphertext.toString('hex')); + return new Buffer(hex, 'hex'); + } + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} plaintext + @return {Buffer} binary + */ - /** - A week random number generator can run out of entropy. - This should ensure even the worst random number implementation will be reasonably safe. - @param1 string entropy of at least 32 bytes - */ - random32ByteBuffer: function random32ByteBuffer() { - var entropy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.browserEntropy(); + }, { + key: "encrypt", + value: function encrypt(plaintext) { + if (typeof plaintext === "string") { + plaintext = new Buffer(plaintext, 'binary'); + } + if (!Buffer.isBuffer(plaintext)) { + throw new Error("buffer required"); + } + //assert plaintext, "Missing plain text" + // hex is the only common format + var hex = this.encryptHex(plaintext.toString('hex')); + return new Buffer(hex, 'hex'); + } - if (!(typeof entropy === 'string')) { - throw new Error('string required for entropy'); - } + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string|Buffer} plaintext + @return {string} hex + */ - if (entropy.length < 32) { - throw new Error('expecting at least 32 bytes of entropy'); - } + }, { + key: "encryptToHex", + value: function encryptToHex(plaintext) { + if (typeof plaintext === "string") { + plaintext = new Buffer(plaintext, 'binary'); + } + if (!Buffer.isBuffer(plaintext)) { + throw new Error("buffer required"); + } + //assert plaintext, "Missing plain text" + // hex is the only common format + return this.encryptHex(plaintext.toString('hex')); + } - var start_t = Date.now(); + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @return {string} binary (could easily be readable text) + */ - while (Date.now() - start_t < HASH_POWER_MILLS) { - entropy = (0, _hash.sha256)(entropy); - } + }, { + key: "decryptHex", + value: function decryptHex(cipher) { + assert(cipher, "Missing cipher text"); + // Convert data into word arrays (used by Crypto) + var cipher_array = encHex.parse(cipher); + var plainwords = this._decrypt_word_array(cipher_array); + return encHex.stringify(plainwords); + } - var hash_array = []; - hash_array.push(entropy); + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @return {Buffer} encoded as specified by the parameter + */ - // Hashing for 1 second may helps the computer is not low on entropy - // (this method may be called back-to-back). - hash_array.push(_secureRandom2.default.randomBuffer(32)); + }, { + key: "decryptHexToBuffer", + value: function decryptHexToBuffer(cipher) { + assert(cipher, "Missing cipher text"); + // Convert data into word arrays (used by Crypto) + var cipher_array = encHex.parse(cipher); + var plainwords = this._decrypt_word_array(cipher_array); + var plainhex = encHex.stringify(plainwords); + return new Buffer(plainhex, 'hex'); + } - return (0, _hash.sha256)(Buffer.concat(hash_array)); - }, - suggest_brain_key: function suggest_brain_key() { - var dictionary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ','; - var entropy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.browserEntropy(); + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @arg {string} [encoding = 'binary'] - a valid Buffer encoding + @return {String} encoded as specified by the parameter + */ - var randomBuffer = this.random32ByteBuffer(entropy); + }, { + key: "decryptHexToText", + value: function decryptHexToText(cipher) { + var encoding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'binary'; - var word_count = 16; - var dictionary_lines = dictionary.split(','); + return this.decryptHexToBuffer(cipher).toString(encoding); + } - if (!(dictionary_lines.length === 49744)) { - throw new Error('expecting ' + 49744 + ' but got ' + dictionary_lines.length + ' dictionary words'); - } + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} plainhex - hex format + @return {String} hex + */ + + }, { + key: "encryptHex", + value: function encryptHex(plainhex) { + var plain_array = encHex.parse(plainhex); + var cipher_array = this._encrypt_word_array(plain_array); + return encHex.stringify(cipher_array); + } + }], [{ + key: "fromSeed", + value: function fromSeed(seed) { + if (seed === undefined) { + throw new Error("seed is required"); + } + var _hash = hash.sha512(seed); + _hash = _hash.toString('hex'); + // DEBUG console.log('... fromSeed _hash',_hash) + return Aes.fromSha512(_hash); + } + }, { + key: "fromSha512", - var brainkey = []; - var end = word_count * 2; - for (var i = 0; i < end; i += 2) { - // randomBuffer has 256 bits / 16 bits per word == 16 words - var num = (randomBuffer[i] << 8) + randomBuffer[i + 1]; // eslint-disable-line + /** @arg {string} hash - A 128 byte hex string, typically one would call {@link fromSeed} instead. */ + value: function fromSha512(hash) { + assert.equal(hash.length, 128, "A Sha512 in HEX should be 128 characters long, instead got " + hash.length); + var iv = encHex.parse(hash.substring(64, 96)); + var key = encHex.parse(hash.substring(0, 64)); + return new Aes(iv, key); + } + }, { + key: "fromBuffer", + value: function fromBuffer(buf) { + assert(Buffer.isBuffer(buf), "Expecting Buffer"); + assert.equal(buf.length, 64, "A Sha512 Buffer should be 64 characters long, instead got " + buf.length); + return Aes.fromSha512(buf.toString("hex")); + } + /** + @throws {Error} - "Invalid Key, ..." + @arg {PrivateKey} private_key - required and used for decryption + @arg {PublicKey} public_key - required and used to calcualte the shared secret + @arg {string} [nonce = ""] optional but should always be provided and be unique when re-using the same private/public keys more than once. This nonce is not a secret. + @arg {string|Buffer} message - Encrypted message containing a checksum + @return {Buffer} + */ - // convert into a number between 0 and 1 (inclusive) - var rndMultiplier = num / Math.pow(2, 16); - var wordIndex = Math.round(dictionary_lines.length * rndMultiplier); + }, { + key: "decrypt_with_checksum", + value: function decrypt_with_checksum(private_key, public_key, nonce, message) { + var legacy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; - brainkey.push(dictionary_lines[wordIndex]); - } - return this.normalize_brainKey(brainkey.join(' ')); - }, - get_random_key: function get_random_key(entropy) { - return _PrivateKey2.default.fromBuffer(this.random32ByteBuffer(entropy)); - }, - get_brainPrivateKey: function get_brainPrivateKey(brainKey) { - var sequence = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string + if (nonce == null) // null or undefined + nonce = ""; - if (sequence < 0) { - throw new Error('invalid sequence'); - } + if (!Buffer.isBuffer(message)) { + message = new Buffer(message, 'hex'); + } - brainKey = key.normalize_brainKey(brainKey); - return _PrivateKey2.default.fromBuffer((0, _hash.sha256)((0, _hash.sha512)(brainKey + ' ' + sequence))); - }, + var S = private_key.get_shared_secret(public_key, legacy); + // D E B U G + // console.log('decrypt_with_checksum', { + // priv_to_pub: private_key.toPublicKey().toString(), + // pub: public_key.toPublicKeyString(), + // nonce: nonce, + // message: message.length, + // S: S.toString('hex') + // }) + + var aes = Aes.fromSeed(Buffer.concat([ + // A null or empty string nonce will not effect the hash + new Buffer("" + nonce), new Buffer(S.toString('hex'))])); + + var planebuffer = aes.decrypt(message); + if (!(planebuffer.length >= 4)) { + throw new Error("Invalid key, could not decrypt message(1)"); + } + // DEBUG console.log('... planebuffer',planebuffer) + var checksum = planebuffer.slice(0, 4); + var plaintext = planebuffer.slice(4); - // Turn invisible space like characters into a single space - normalize_brainKey: function normalize_brainKey(brainKey) { - if (!(typeof brainKey === 'string')) { - throw new Error('string required for brainKey'); - } + // console.log('... checksum',checksum.toString('hex')) + // console.log('... plaintext',plaintext.toString()) - brainKey = brainKey.trim(); - return brainKey.split(/[\t\n\v\f\r ]+/).join(' '); - }, - browserEntropy: function browserEntropy() { - var entropyStr = ''; + var new_checksum = hash.sha256(plaintext); + new_checksum = new_checksum.slice(0, 4); + new_checksum = new_checksum.toString('hex'); - try { - entropyStr = new Date().toString() + ' ' + window.screen.height + ' ' + window.screen.width; - entropyStr = entropyStr + ' ' + window.screen.colorDepth + ' ' + window.screen.availHeight; - entropyStr = entropyStr + ' ' + window.screen.availWidth + ' ' + window.screen.pixelDepth; - entropyStr = entropyStr + ' ' + navigator.language + ' ' + window.location; - entropyStr = entropyStr + ' ' + window.history.length; - - for (var i = 0, len = navigator.mimeTypes.length; i < len; i++) { - var mimeType = navigator.mimeTypes[i]; - entropyStr += mimeType.description + ' ' + mimeType.type + ' ' + mimeType.suffixes + ' '; - } + if (!(checksum.toString('hex') === new_checksum)) { + throw new Error("Invalid key, could not decrypt message(2)"); + } - console.log('INFO\tbrowserEntropy gathered'); - } catch (error) { - // nodejs:ReferenceError: window is not defined - entropyStr = (0, _hash.sha256)(new Date().toString()); - } + return plaintext; + } + }, { + key: "encrypt_with_checksum", - var b = Buffer.from(entropyStr); - entropyStr += b.toString('binary') + ' ' + new Date().toString(); - return entropyStr; - }, + /** Identical to {@link decrypt_with_checksum} but used to encrypt. Should not throw an error. + @return {Buffer} message - Encrypted message which includes a checksum + */ + value: function encrypt_with_checksum(private_key, public_key, nonce, message) { - // @return array of 5 legacy addresses for a pubkey string parameter. - addresses: function addresses(pubkey) { - var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _peerplaysjsWs.ChainConfig.address_prefix; + // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string - var public_key = _PublicKey2.default.fromPublicKeyString(pubkey, address_prefix); - // S L O W - var address_string = [_address2.default.fromPublic(public_key, false, 0).toString(address_prefix), // btc_uncompressed - _address2.default.fromPublic(public_key, true, 0).toString(address_prefix), // btc_compressed - _address2.default.fromPublic(public_key, false, 56).toString(address_prefix), // pts_uncompressed - _address2.default.fromPublic(public_key, true, 56).toString(address_prefix), // pts_compressed - public_key.toAddressString(address_prefix) // bts_short, most recent format - ]; - return address_string; - } -}; + if (nonce == null) // null or undefined + nonce = ""; + + if (!Buffer.isBuffer(message)) { + message = new Buffer(message, 'binary'); + } + + var S = private_key.get_shared_secret(public_key); + + // D E B U G + // console.log('encrypt_with_checksum', { + // priv_to_pub: private_key.toPublicKey().toString() + // pub: public_key.toPublicKeyString() + // nonce: nonce + // message: message.length + // S: S.toString('hex') + // }) + + var aes = Aes.fromSeed(Buffer.concat([ + // A null or empty string nonce will not effect the hash + new Buffer("" + nonce), new Buffer(S.toString('hex'))])); + // DEBUG console.log('... S',S.toString('hex')) + var checksum = hash.sha256(message).slice(0, 4); + var payload = Buffer.concat([checksum, message]); + // DEBUG console.log('... payload',payload.toString()) + return aes.encrypt(payload); + } + }]); + + return Aes; +}(); -exports.default = key; -module.exports = exports['default']; -}).call(this,require(35).Buffer) +module.exports = Aes; +}).call(this,require("buffer").Buffer) -},{"10":10,"11":11,"12":12,"13":13,"17":17,"35":35,"70":70,"94":94}],10:[function(require,module,exports){ +},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/hash.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","bytebuffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bytebuffer/dist/bytebuffer.js","crypto-js/aes":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/aes.js","crypto-js/enc-base64":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/enc-base64.js","crypto-js/enc-hex":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/enc-hex.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/ecdsa.js":[function(require,module,exports){ (function (Buffer){ 'use strict'; -exports.__esModule = true; +var assert = require('assert'); // from github.com/bitcoinjs/bitcoinjs-lib from github.com/cryptocoinjs/ecdsa +var crypto = require('./hash'); +var enforceType = require('./enforce_types'); -var _ecurve = require(59); +var BigInteger = require('bigi'); +var ECSignature = require('./ecsignature'); -var _bigi = require(32); +// https://tools.ietf.org/html/rfc6979#section-3.2 +function deterministicGenerateK(curve, hash, d, checkSig, nonce) { -var _bigi2 = _interopRequireDefault(_bigi); + enforceType('Buffer', hash); + enforceType(BigInteger, d); -var _bs = require(37); + if (nonce) { + hash = crypto.sha256(Buffer.concat([hash, new Buffer(nonce)])); + } -var _deepEqual = require(54); + // sanity check + assert.equal(hash.length, 32, 'Hash must be 256 bit'); -var _deepEqual2 = _interopRequireDefault(_deepEqual); + var x = d.toBuffer(32); + var k = new Buffer(32); + var v = new Buffer(32); -var _assert = require(27); + // Step B + v.fill(1); -var _assert2 = _interopRequireDefault(_assert); + // Step C + k.fill(0); -var _hash = require(17); + // Step D + k = crypto.HmacSHA256(Buffer.concat([v, new Buffer([0]), x, hash]), k); -var _PublicKey = require(11); + // Step E + v = crypto.HmacSHA256(v, k); -var _PublicKey2 = _interopRequireDefault(_PublicKey); + // Step F + k = crypto.HmacSHA256(Buffer.concat([v, new Buffer([1]), x, hash]), k); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + // Step G + v = crypto.HmacSHA256(v, k); -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* global ByteBuffer */ + // Step H1/H2a, ignored as tlen === qlen (256 bit) + // Step H2b + v = crypto.HmacSHA256(v, k); + var T = BigInteger.fromBuffer(v); -var secp256k1 = (0, _ecurve.getCurveByName)('secp256k1'); -var n = secp256k1.n; + // Step H3, repeat until T is within the interval [1, n - 1] + while (T.signum() <= 0 || T.compareTo(curve.n) >= 0 || !checkSig(T)) { + k = crypto.HmacSHA256(Buffer.concat([v, new Buffer([0])]), k); + v = crypto.HmacSHA256(v, k); + // Step H1/H2a, again, ignored as tlen === qlen (256 bit) + // Step H2b again + v = crypto.HmacSHA256(v, k); -function toPublic(data) { - if (!data || data.Q) { - return data; + T = BigInteger.fromBuffer(v); } - return _PublicKey2.default.fromStringOrThrow(data); + return T; } -var PrivateKey = function () { - /** - @private see static functions - @param {BigInteger} - */ - function PrivateKey(d) { - _classCallCheck(this, PrivateKey); - - this.d = d; - } +function sign(curve, hash, d, nonce) { - PrivateKey.fromBuffer = function fromBuffer(buf) { - if (!Buffer.isBuffer(buf)) { - throw new Error('Expecting paramter to be a Buffer type'); - } + var e = BigInteger.fromBuffer(hash); + var n = curve.n; + var G = curve.G; - if (buf.length !== 32) { - console.log('WARN: Expecting 32 bytes, instead got ' + buf.length + ', stack trace:', new Error().stack); - } + var r, s; + var k = deterministicGenerateK(curve, hash, d, function (k) { + // find canonically valid signature + var Q = G.multiply(k); - if (buf.length === 0) { - throw new Error('Empty buffer'); - } + if (curve.isInfinity(Q)) return false; - return new PrivateKey(_bigi2.default.fromBuffer(buf)); - }; + r = Q.affineX.mod(n); + if (r.signum() === 0) return false; - /** @arg {string} seed - any length string. This is private, - * the same seed produces the same private key every time. */ + s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n); + if (s.signum() === 0) return false; + return true; + }, nonce); - PrivateKey.fromSeed = function fromSeed(seed) { - // generate_private_key - if (!(typeof seed === 'string')) { - throw new Error('seed must be of type string'); - } + var N_OVER_TWO = n.shiftRight(1); - return PrivateKey.fromBuffer((0, _hash.sha256)(seed)); - }; + // enforce low S values, see bip62: 'low s values in signatures' + if (s.compareTo(N_OVER_TWO) > 0) { + s = n.subtract(s); + } - /** @return {string} Wallet Import Format (still a secret, Not encrypted) */ + return new ECSignature(r, s); +} +function verifyRaw(curve, e, signature, Q) { + var n = curve.n; + var G = curve.G; - PrivateKey.fromWif = function fromWif(_private_wif) { - var private_wif = Buffer.from((0, _bs.decode)(_private_wif)); - var version = private_wif.readUInt8(0); - _assert2.default.equal(0x80, version, 'Expected version ' + 0x80 + ', instead got ' + version); - // checksum includes the version - var private_key = private_wif.slice(0, -4); - var checksum = private_wif.slice(-4); - var new_checksum = (0, _hash.sha256)(private_key); - new_checksum = (0, _hash.sha256)(new_checksum); - new_checksum = new_checksum.slice(0, 4); - var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); // , 'Invalid checksum' + var r = signature.r; + var s = signature.s; - if (!isEqual) { - throw new Error('Checksum did not match'); - } + // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] + if (r.signum() <= 0 || r.compareTo(n) >= 0) return false; + if (s.signum() <= 0 || s.compareTo(n) >= 0) return false; - private_key = private_key.slice(1); - private_key = private_key.slice(0, 32); - return PrivateKey.fromBuffer(private_key); - }; + // c = s^-1 mod n + var c = s.modInverse(n); - PrivateKey.prototype.toWif = function toWif() { - var private_key = this.toBuffer(); - // checksum includes the version - private_key = Buffer.concat([Buffer.from([0x80]), private_key]); - var checksum = (0, _hash.sha256)(private_key); - checksum = (0, _hash.sha256)(checksum); - checksum = checksum.slice(0, 4); - var private_wif = Buffer.concat([private_key, checksum]); - return (0, _bs.encode)(private_wif); - }; + // 1.4.4 Compute u1 = es^−1 mod n + // u2 = rs^−1 mod n + var u1 = e.multiply(c).mod(n); + var u2 = r.multiply(c).mod(n); - /** - @return {Point} - */ + // 1.4.5 Compute R = (xR, yR) = u1G + u2Q + var R = G.multiplyTwo(u1, Q, u2); + // 1.4.5 (cont.) Enforce R is not at infinity + if (curve.isInfinity(R)) return false; - PrivateKey.prototype.toPublicKeyPoint = function toPublicKeyPoint() { - var Q = secp256k1.G.multiply(this.d); - return Q; - }; + // 1.4.6 Convert the field element R.x to an integer + var xR = R.affineX; - PrivateKey.prototype.toPublicKey = function toPublicKey() { - if (this.public_key) { - return this.public_key; - } + // 1.4.7 Set v = xR mod n + var v = xR.mod(n); - this.public_key = _PublicKey2.default.fromPoint(this.toPublicKeyPoint()); + // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" + return v.equals(r); +} - return this.public_key; - }; +function verify(curve, hash, signature, Q) { + // 1.4.2 H = Hash(M), already done by the user + // 1.4.3 e = H + var e = BigInteger.fromBuffer(hash); + return verifyRaw(curve, e, signature, Q); +} - PrivateKey.prototype.toBuffer = function toBuffer() { - return this.d.toBuffer(32); - }; +/** + * Recover a public key from a signature. + * + * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public + * Key Recovery Operation". + * + * http://www.secg.org/download/aid-780/sec1-v2.pdf + */ +function recoverPubKey(curve, e, signature, i) { + assert.strictEqual(i & 3, i, 'Recovery param is more than two bits'); - /** ECIES */ + var n = curve.n; + var G = curve.G; + var r = signature.r; + var s = signature.s; - PrivateKey.prototype.get_shared_secret = function get_shared_secret(public_key) { - var legacy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + assert(r.signum() > 0 && r.compareTo(n) < 0, 'Invalid r value'); + assert(s.signum() > 0 && s.compareTo(n) < 0, 'Invalid s value'); - public_key = toPublic(public_key); - var KB = public_key.toUncompressed().toBuffer(); - var KBP = _ecurve.Point.fromAffine(secp256k1, _bigi2.default.fromBuffer(KB.slice(1, 33)), // x - _bigi2.default.fromBuffer(KB.slice(33, 65)) // y - ); - var r = this.toBuffer(); - var P = KBP.multiply(_bigi2.default.fromBuffer(r)); - var S = P.affineX.toBuffer({ size: 32 }); + // A set LSB signifies that the y-coordinate is odd + var isYOdd = i & 1; - /* - the input to sha512 must be exactly 32-bytes, to match the c++ implementation - of get_shared_secret. Right now S will be shorter if the most significant - byte(s) is zero. Pad it back to the full 32-bytes - */ - if (!legacy && S.length < 32) { - var pad = Buffer.alloc(32 - S.length, 0); - S = Buffer.concat([pad, S]); - } + // The more significant bit specifies whether we should use the + // first or second candidate key. + var isSecondKey = i >> 1; - // SHA512 used in ECIES - return (0, _hash.sha512)(S); - }; + // 1.1 Let x = r + jn + var x = isSecondKey ? r.add(n) : r; + var R = curve.pointFromX(isYOdd, x); - // /** ECIES (does not always match the Point.fromAffine version above) */ - // get_shared_secret(public_key){ - // public_key = toPublic(public_key) - // var P = public_key.Q.multiply( this.d ); - // var S = P.affineX.toBuffer({size: 32}); - // // ECIES, adds an extra sha512 - // return sha512(S); - // } + // 1.4 Check that nR is at infinity + var nR = R.multiply(n); + assert(curve.isInfinity(nR), 'nR is not a valid curve point'); - /** @throws {Error} - overflow of the key could not be derived */ + // Compute -e from e + var eNeg = e.negate().mod(n); + // 1.6.1 Compute Q = r^-1 (sR - eG) + // Q = r^-1 (sR + -eG) + var rInv = r.modInverse(n); - PrivateKey.prototype.child = function child(offset) { - offset = Buffer.concat([this.toPublicKey().toBuffer(), offset]); - offset = (0, _hash.sha256)(offset); - var c = _bigi2.default.fromBuffer(offset); + var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv); + curve.validate(Q); - if (c.compareTo(n) >= 0) { - throw new Error('Child offset went out of bounds, try again'); - } + return Q; +} - var derived = this.d.add(c); // .mod(n) +/** + * Calculate pubkey extraction parameter. + * + * When extracting a pubkey from a signature, we have to + * distinguish four different cases. Rather than putting this + * burden on the verifier, Bitcoin includes a 2-bit value with the + * signature. + * + * This function simply tries all four cases and returns the value + * that resulted in a successful pubkey recovery. + */ +function calcPubKeyRecoveryParam(curve, e, signature, Q) { + for (var i = 0; i < 4; i++) { + var Qprime = recoverPubKey(curve, e, signature, i); - if (derived.signum() === 0) { - throw new Error('Child offset derived to an invalid key, try again'); + // 1.6.2 Verify Q + if (Qprime.equals(Q)) { + return i; } + } - return new PrivateKey(derived); - }; - - /* */ - - PrivateKey.prototype.toByteBuffer = function toByteBuffer() { - var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); - this.appendByteBuffer(b); - return b.copy(0, b.offset); - }; - - PrivateKey.fromHex = function fromHex(hex) { - return PrivateKey.fromBuffer(Buffer.from(hex, 'hex')); - }; - - PrivateKey.prototype.toHex = function toHex() { - return this.toBuffer().toString('hex'); - }; - - /* */ - - - return PrivateKey; -}(); + throw new Error('Unable to find valid recovery factor'); +} -exports.default = PrivateKey; -module.exports = exports['default']; -}).call(this,require(35).Buffer) +module.exports = { + calcPubKeyRecoveryParam: calcPubKeyRecoveryParam, + deterministicGenerateK: deterministicGenerateK, + recoverPubKey: recoverPubKey, + sign: sign, + verify: verify, + verifyRaw: verifyRaw +}; +}).call(this,require("buffer").Buffer) -},{"11":11,"17":17,"27":27,"32":32,"35":35,"37":37,"54":54,"59":59}],11:[function(require,module,exports){ +},{"./ecsignature":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/ecsignature.js","./enforce_types":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/enforce_types.js","./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/hash.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/index.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/ecsignature.js":[function(require,module,exports){ (function (Buffer){ 'use strict'; -exports.__esModule = true; - -var _bigi = require(32); - -var _bigi2 = _interopRequireDefault(_bigi); +var assert = require('assert'); // from https://github.com/bitcoinjs/bitcoinjs-lib +var enforceType = require('./enforce_types'); -var _ecurve = require(59); +var BigInteger = require('bigi'); -var _bs = require(37); - -var _peerplaysjsWs = require(70); +function ECSignature(r, s) { + enforceType(BigInteger, r); + enforceType(BigInteger, s); -var _assert = require(27); + this.r = r; + this.s = s; +} -var _assert2 = _interopRequireDefault(_assert); +// Import operations +ECSignature.parseCompact = function (buffer) { + assert.equal(buffer.length, 65, 'Invalid signature length'); + var i = buffer.readUInt8(0) - 27; -var _deepEqual = require(54); + // At most 3 bits + assert.equal(i, i & 7, 'Invalid signature parameter'); + var compressed = !!(i & 4); -var _deepEqual2 = _interopRequireDefault(_deepEqual); + // Recovery param only + i = i & 3; -var _hash = require(17); + var r = BigInteger.fromBuffer(buffer.slice(1, 33)); + var s = BigInteger.fromBuffer(buffer.slice(33)); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + return { + compressed: compressed, + i: i, + signature: new ECSignature(r, s) + }; +}; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* global ByteBuffer */ +ECSignature.fromDER = function (buffer) { + assert.equal(buffer.readUInt8(0), 0x30, 'Not a DER sequence'); + assert.equal(buffer.readUInt8(1), buffer.length - 2, 'Invalid sequence length'); + assert.equal(buffer.readUInt8(2), 0x02, 'Expected a DER integer'); + var rLen = buffer.readUInt8(3); + assert(rLen > 0, 'R length is zero'); -var secp256k1 = (0, _ecurve.getCurveByName)('secp256k1'); + var offset = 4 + rLen; + assert.equal(buffer.readUInt8(offset), 0x02, 'Expected a DER integer (2)'); -var G = secp256k1.G, - n = secp256k1.n; + var sLen = buffer.readUInt8(offset + 1); + assert(sLen > 0, 'S length is zero'); -var PublicKey = function () { - /** @param {Point} public key */ - function PublicKey(Q) { - _classCallCheck(this, PublicKey); + var rB = buffer.slice(4, offset); + var sB = buffer.slice(offset + 2); + offset += 2 + sLen; - this.Q = Q; + if (rLen > 1 && rB.readUInt8(0) === 0x00) { + assert(rB.readUInt8(1) & 0x80, 'R value excessively padded'); } - PublicKey.fromBinary = function fromBinary(bin) { - return PublicKey.fromBuffer(Buffer.from(bin, 'binary')); - }; - - PublicKey.fromBuffer = function fromBuffer(buffer) { - if (buffer.toString('hex') === '000000000000000000000000000000000000000000000000000000000000000000') { - return new PublicKey(null); - } + if (sLen > 1 && sB.readUInt8(0) === 0x00) { + assert(sB.readUInt8(1) & 0x80, 'S value excessively padded'); + } - return new PublicKey(_ecurve.Point.decodeFrom(secp256k1, buffer)); - }; + assert.equal(offset, buffer.length, 'Invalid DER encoding'); + var r = BigInteger.fromDERInteger(rB); + var s = BigInteger.fromDERInteger(sB); - PublicKey.prototype.toBuffer = function toBuffer() { - var compressed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.Q ? this.Q.compressed : null; + assert(r.signum() >= 0, 'R value is negative'); + assert(s.signum() >= 0, 'S value is negative'); - if (this.Q === null) { - return Buffer.from('000000000000000000000000000000000000000000000000000000000000000000', 'hex'); - } + return new ECSignature(r, s); +}; - return this.Q.getEncoded(compressed); - }; +// FIXME: 0x00, 0x04, 0x80 are SIGHASH_* boundary constants, importing Transaction causes a circular dependency +ECSignature.parseScriptSignature = function (buffer) { + var hashType = buffer.readUInt8(buffer.length - 1); + var hashTypeMod = hashType & ~0x80; - PublicKey.fromPoint = function fromPoint(point) { - return new PublicKey(point); - }; + assert(hashTypeMod > 0x00 && hashTypeMod < 0x04, 'Invalid hashType'); - PublicKey.prototype.toUncompressed = function toUncompressed() { - var buf = this.Q.getEncoded(false); - var point = _ecurve.Point.decodeFrom(secp256k1, buf); - return PublicKey.fromPoint(point); + return { + signature: ECSignature.fromDER(buffer.slice(0, -1)), + hashType: hashType }; +}; - /** bts::blockchain::address (unique but not a full public key) */ +// Export operations +ECSignature.prototype.toCompact = function (i, compressed) { + if (compressed) i += 4; + i += 27; + var buffer = new Buffer(65); + buffer.writeUInt8(i, 0); - PublicKey.prototype.toBlockchainAddress = function toBlockchainAddress() { - var pub_buf = this.toBuffer(); - var pub_sha = (0, _hash.sha512)(pub_buf); - return (0, _hash.ripemd160)(pub_sha); - }; + this.r.toBuffer(32).copy(buffer, 1); + this.s.toBuffer(32).copy(buffer, 33); - /** Alias for {@link toPublicKeyString} */ + return buffer; +}; +ECSignature.prototype.toDER = function () { + var rBa = this.r.toDERInteger(); + var sBa = this.s.toDERInteger(); - PublicKey.prototype.toString = function toString() { - var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.ChainConfig.address_prefix; + var sequence = []; - return this.toPublicKeyString(address_prefix); - }; + // INTEGER + sequence.push(0x02, rBa.length); + sequence = sequence.concat(rBa); - /** - Full public key - {return} string - */ + // INTEGER + sequence.push(0x02, sBa.length); + sequence = sequence.concat(sBa); + // SEQUENCE + sequence.unshift(0x30, sequence.length); - PublicKey.prototype.toPublicKeyString = function toPublicKeyString() { - var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.ChainConfig.address_prefix; + return new Buffer(sequence); +}; - var pub_buf = this.toBuffer(); - var checksum = (0, _hash.ripemd160)(pub_buf); - // Slice from the buffer directly, slicing from the checksum - // Uint8array will return the entire array each time. - var sliced = new Uint8Array(checksum.buffer.slice(0, 4)); +ECSignature.prototype.toScriptSignature = function (hashType) { + var hashTypeBuffer = new Buffer(1); + hashTypeBuffer.writeUInt8(hashType, 0); - // concat only accepts buffers so initialize the sliced Uint8array as a Buffer. - var addy = Buffer.concat([pub_buf, Buffer.from(sliced)]); - return address_prefix + (0, _bs.encode)(addy); - }; + return Buffer.concat([this.toDER(), hashTypeBuffer]); +}; - /** - @arg {string} public_key - like GPHXyz... - @arg {string} address_prefix - like GPH - @return PublicKey or `null` (if the public_key string is invalid) - */ +module.exports = ECSignature; +}).call(this,require("buffer").Buffer) +},{"./enforce_types":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/enforce_types.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/index.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/enforce_types.js":[function(require,module,exports){ +(function (Buffer){ +'use strict'; - PublicKey.fromPublicKeyString = function fromPublicKeyString(public_key) { - var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _peerplaysjsWs.ChainConfig.address_prefix; - - try { - return PublicKey.fromStringOrThrow(public_key, address_prefix); - } catch (e) { - return null; - } - }; - - /** - @arg {string} public_key - like GPHXyz... - @arg {string} address_prefix - like GPH - @throws {Error} if public key is invalid - @return PublicKey - */ - +module.exports = function enforce(type, value) { + // Copied from https://github.com/bitcoinjs/bitcoinjs-lib + switch (type) { + case 'Array': + { + if (Array.isArray(value)) return; + break; + } - PublicKey.fromStringOrThrow = function fromStringOrThrow(public_key) { - var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _peerplaysjsWs.ChainConfig.address_prefix; + case 'Boolean': + { + if (typeof value === 'boolean') return; + break; + } - var prefix = public_key.slice(0, address_prefix.length); - _assert2.default.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix); - public_key = public_key.slice(address_prefix.length); + case 'Buffer': + { + if (Buffer.isBuffer(value)) return; + break; + } - public_key = Buffer.from((0, _bs.decode)(public_key), 'binary'); - var checksum = public_key.slice(-4); - public_key = public_key.slice(0, -4); - var new_checksum = (0, _hash.ripemd160)(public_key); - new_checksum = new_checksum.slice(0, 4); - var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); // , 'Invalid checksum' + case 'Number': + { + if (typeof value === 'number') return; + break; + } - if (!isEqual) { - throw new Error('Checksum did not match'); - } + case 'String': + { + if (typeof value === 'string') return; + break; + } - return PublicKey.fromBuffer(public_key); - }; + default: + { + if (getName(value.constructor) === getName(type)) return; + } + } - PublicKey.prototype.toAddressString = function toAddressString() { - var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.ChainConfig.address_prefix; + throw new TypeError('Expected ' + (getName(type) || type) + ', got ' + value); +}; - var pub_buf = this.toBuffer(); - var pub_sha = (0, _hash.sha512)(pub_buf); - var addy = (0, _hash.ripemd160)(pub_sha); - var checksum = (0, _hash.ripemd160)(addy); - addy = Buffer.concat([addy, checksum.slice(0, 4)]); - return address_prefix + (0, _bs.encode)(addy); - }; +function getName(fn) { + // Why not fn.name: https://kangax.github.io/compat-table/es6/#function_name_property + var match = fn.toString().match(/function (.*?)\(/); + return match ? match[1] : null; +} +}).call(this,{"isBuffer":require("../../../node_modules/is-buffer/index.js")}) - PublicKey.prototype.toPtsAddy = function toPtsAddy() { - var pub_buf = this.toBuffer(); - var pub_sha = (0, _hash.sha256)(pub_buf); - var addy = (0, _hash.ripemd160)(pub_sha); - addy = Buffer.concat([Buffer.from([0x38]), addy]); // version 56(decimal) +},{"../../../node_modules/is-buffer/index.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/is-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/hash.js":[function(require,module,exports){ +"use strict"; - var checksum = (0, _hash.sha256)(addy); - checksum = (0, _hash.sha256)(checksum); +var createHash = require("create-hash"); +var createHmac = require("create-hmac"); - addy = Buffer.concat([addy, checksum.slice(0, 4)]); - return (0, _bs.encode)(addy); - }; +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha1(data, encoding) { + return createHash('sha1').update(data).digest(encoding); +} - PublicKey.prototype.child = function child(offset) { - (0, _assert2.default)(Buffer.isBuffer(offset), 'Buffer required: offset'); - _assert2.default.equal(offset.length, 32, 'offset length'); +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha256(data, encoding) { + return createHash('sha256').update(data).digest(encoding); +} - offset = Buffer.concat([this.toBuffer(), offset]); - offset = (0, _hash.sha256)(offset); +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha512(data, encoding) { + return createHash('sha512').update(data).digest(encoding); +} - var c = _bigi2.default.fromBuffer(offset); +function HmacSHA256(buffer, secret) { + return createHmac('sha256', secret).update(buffer).digest(); +} - if (c.compareTo(n) >= 0) { - throw new Error('Child offset went out of bounds, try again'); - } +function ripemd160(data) { + return createHash('rmd160').update(data).digest(); +} - var cG = G.multiply(c); - var Qprime = this.Q.add(cG); +// function hash160(buffer) { +// return ripemd160(sha256(buffer)) +// } +// +// function hash256(buffer) { +// return sha256(sha256(buffer)) +// } - if (secp256k1.isInfinity(Qprime)) { - throw new Error('Child offset derived to an invalid key, try again'); - } +// +// function HmacSHA512(buffer, secret) { +// return crypto.createHmac('sha512', secret).update(buffer).digest() +// } - return PublicKey.fromPoint(Qprime); - }; +module.exports = { + sha1: sha1, + sha256: sha256, + sha512: sha512, + HmacSHA256: HmacSHA256, + ripemd160: ripemd160 + // hash160: hash160, + // hash256: hash256, + // HmacSHA512: HmacSHA512 +}; +},{"create-hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/create-hash/browser.js","create-hmac":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/create-hmac/browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/signature.js":[function(require,module,exports){ +(function (Buffer){ +'use strict'; - /* */ +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - PublicKey.prototype.toByteBuffer = function toByteBuffer() { - var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); - this.appendByteBuffer(b); - return b.copy(0, b.offset); - }; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - PublicKey.fromHex = function fromHex(hex) { - return PublicKey.fromBuffer(Buffer.from(hex, 'hex')); - }; +var ecdsa = require('./ecdsa'); +var hash = require('./hash'); - PublicKey.prototype.toHex = function toHex() { - return this.toBuffer().toString('hex'); - }; +var _require = require('ecurve'), + getCurveByName = _require.getCurveByName; - PublicKey.fromPublicKeyStringHex = function fromPublicKeyStringHex(hex) { - return PublicKey.fromPublicKeyString(Buffer.from(hex, 'hex')); - }; +var secp256k1 = getCurveByName('secp256k1'); +var assert = require('assert'); +var BigInteger = require('bigi'); +var PublicKey = require('./PublicKey'); - /* */ +var Signature = function () { + function Signature(r1, s1, i1) { + _classCallCheck(this, Signature); + + this.r = r1; + this.s = s1; + this.i = i1; + assert.equal(this.r != null, true, 'Missing parameter'); + assert.equal(this.s != null, true, 'Missing parameter'); + assert.equal(this.i != null, true, 'Missing parameter'); + } + + _createClass(Signature, [{ + key: 'toBuffer', + value: function toBuffer() { + var buf; + buf = new Buffer(65); + buf.writeUInt8(this.i, 0); + this.r.toBuffer(32).copy(buf, 1); + this.s.toBuffer(32).copy(buf, 33); + return buf; + } + }, { + key: 'recoverPublicKeyFromBuffer', + value: function recoverPublicKeyFromBuffer(buffer) { + return this.recoverPublicKey(hash.sha256(buffer)); + } + }, { + key: 'recoverPublicKey', - return PublicKey; -}(); + /** + @return {PublicKey} + */ + value: function recoverPublicKey(sha256_buffer) { + var Q = void 0, + e = void 0, + i = void 0; + e = BigInteger.fromBuffer(sha256_buffer); + i = this.i; + i -= 27; + i = i & 3; + Q = ecdsa.recoverPubKey(secp256k1, e, this, i); + return PublicKey.fromPoint(Q); + } + }, { + key: 'verifyBuffer', -exports.default = PublicKey; -module.exports = exports['default']; -}).call(this,require(35).Buffer) -},{"17":17,"27":27,"32":32,"35":35,"37":37,"54":54,"59":59,"70":70}],12:[function(require,module,exports){ -(function (Buffer){ -'use strict'; + /** + @param {Buffer} un-hashed + @param {./PublicKey} + @return {boolean} + */ + value: function verifyBuffer(buf, public_key) { + var _hash = hash.sha256(buf); + return this.verifyHash(_hash, public_key); + } + }, { + key: 'verifyHash', + value: function verifyHash(hash, public_key) { + assert.equal(hash.length, 32, "A SHA 256 should be 32 bytes long, instead got " + hash.length); + return ecdsa.verify(secp256k1, hash, { + r: this.r, + s: this.s + }, public_key.Q); + } + }, { + key: 'toByteBuffer', -exports.__esModule = true; -var _assert = require(27); + /* */ -var _assert2 = _interopRequireDefault(_assert); + value: function toByteBuffer() { + var b; + b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + } + }, { + key: 'toHex', + value: function toHex() { + return this.toBuffer().toString("hex"); + } + }, { + key: 'verifyHex', + value: function verifyHex(hex, public_key) { + var buf; + buf = new Buffer(hex, 'hex'); + return this.verifyBuffer(buf, public_key); + } + }], [{ + key: 'fromBuffer', + value: function fromBuffer(buf) { + var i, r, s; + assert.equal(buf.length, 65, 'Invalid signature length'); + i = buf.readUInt8(0); + assert.equal(i - 27, i - 27 & 7, 'Invalid signature parameter'); + r = BigInteger.fromBuffer(buf.slice(1, 33)); + s = BigInteger.fromBuffer(buf.slice(33)); + return new Signature(r, s, i); + } + }, { + key: 'signBuffer', -var _peerplaysjsWs = require(70); -var _bs = require(37); + /** + @param {Buffer} buf + @param {PrivateKey} private_key + @return {Signature} + */ + value: function signBuffer(buf, private_key) { + var _hash = hash.sha256(buf); + return Signature.signBufferSha256(_hash, private_key); + } -var _deepEqual = require(54); + /** Sign a buffer of exactally 32 bytes in size (sha256(text)) + @param {Buffer} buf - 32 bytes binary + @param {PrivateKey} private_key + @return {Signature} + */ -var _deepEqual2 = _interopRequireDefault(_deepEqual); + }, { + key: 'signBufferSha256', + value: function signBufferSha256(buf_sha256, private_key) { + if (buf_sha256.length !== 32 || !Buffer.isBuffer(buf_sha256)) throw new Error("buf_sha256: 32 byte buffer requred"); + var der, e, ecsignature, i, lenR, lenS, nonce; + i = null; + nonce = 0; + e = BigInteger.fromBuffer(buf_sha256); + while (true) { + ecsignature = ecdsa.sign(secp256k1, buf_sha256, private_key.d, nonce++); + der = ecsignature.toDER(); + lenR = der[3]; + lenS = der[5 + lenR]; + if (lenR === 32 && lenS === 32) { + i = ecdsa.calcPubKeyRecoveryParam(secp256k1, e, ecsignature, private_key.toPublicKey().Q); + i += 4; // compressed + i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) + break; + } + if (nonce % 10 === 0) { + console.log("WARN: " + nonce + " attempts to find canonical signature"); + } + } + return new Signature(ecsignature.r, ecsignature.s, i); + } + }, { + key: 'sign', + value: function sign(string, private_key) { + return Signature.signBuffer(new Buffer(string), private_key); + } + }, { + key: 'fromHex', + value: function fromHex(hex) { + return Signature.fromBuffer(new Buffer(hex, "hex")); + } + }, { + key: 'signHex', + value: function signHex(hex, private_key) { + var buf; + buf = new Buffer(hex, 'hex'); + return Signature.signBuffer(buf, private_key); + } + }]); -var _hash2 = require(17); + return Signature; +}(); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +module.exports = Signature; +}).call(this,require("buffer").Buffer) -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +},{"./PublicKey":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PublicKey.js","./ecdsa":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/ecdsa.js","./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/hash.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/index.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","ecurve":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/index.js":[function(require,module,exports){ +'use strict'; -/** Addresses are shortened non-reversable hashes of a public key. The full PublicKey is preferred. - @deprecated -*/ -var Address = function () { - function Address(addy) { - _classCallCheck(this, Address); +module.exports = { - this.addy = addy; - } + // Primary class for creating operations + Serializer: require('./src/serializer'), - Address.fromBuffer = function fromBuffer(buffer) { - var _hash = (0, _hash2.sha512)(buffer); - var addy = (0, _hash2.ripemd160)(_hash); - return new Address(addy); - }; + // helper functions for creating operations + fp: require('./src/FastParser'), - Address.fromString = function fromString(string) { - var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _peerplaysjsWs.ChainConfig.address_prefix; - - var prefix = string.slice(0, address_prefix.length); - _assert2.default.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix); - var addy = string.slice(address_prefix.length); - addy = Buffer.from((0, _bs.decode)(addy), 'binary'); - var checksum = addy.slice(-4); - addy = addy.slice(0, -4); - var new_checksum = (0, _hash2.ripemd160)(addy); - new_checksum = new_checksum.slice(0, 4); - var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); // , 'Invalid checksum' - - if (!isEqual) { - throw new Error('Checksum did not match'); - } + // Low level types + types: require('./src/types'), - return new Address(addy); - }; + // Higher level operations (made out of generic types) + ops: require('./src/operations'), - /** @return Address - Compressed PTS format (by default) */ + // Utility that generates JSON examples + template: require('./src/template'), + // Serializer validation + SerializerValidation: require('./src/SerializerValidation') +}; +},{"./src/FastParser":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/FastParser.js","./src/SerializerValidation":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/SerializerValidation.js","./src/operations":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/operations.js","./src/serializer":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/serializer.js","./src/template":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/template.js","./src/types":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/types.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/FastParser.js":[function(require,module,exports){ +(function (Buffer){ +'use strict'; - Address.fromPublic = function fromPublic(public_key) { - var compressed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - var version = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 56; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - var sha2 = (0, _hash2.sha256)(public_key.toBuffer(compressed)); - var rep = (0, _hash2.ripemd160)(sha2); - var versionBuffer = Buffer.alloc(1); - versionBuffer.writeUInt8(0xff & version, 0); // eslint-disable-line - var addr = Buffer.concat([versionBuffer, rep]); - var check = (0, _hash2.sha256)(addr); - check = (0, _hash2.sha256)(check); - var buffer = Buffer.concat([addr, check.slice(0, 4)]); - return new Address((0, _hash2.ripemd160)(buffer)); - }; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - Address.prototype.toBuffer = function toBuffer() { - return this.addy; - }; +var PublicKey = require("../../ecc/src/PublicKey"); - Address.prototype.toString = function toString() { - var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _peerplaysjsWs.ChainConfig.address_prefix; +var FastParser = function () { + function FastParser() { + _classCallCheck(this, FastParser); + } - var checksum = (0, _hash2.ripemd160)(this.addy); - var addy = Buffer.concat([this.addy, checksum.slice(0, 4)]); - return address_prefix + (0, _bs.encode)(addy); - }; + _createClass(FastParser, null, [{ + key: 'fixed_data', + value: function fixed_data(b, len, buffer) { + if (!b) { + return; + } + if (buffer) { + var data = buffer.slice(0, len).toString('binary'); + b.append(data, 'binary'); + while (len-- > data.length) { + b.writeUint8(0); + } + } else { + var b_copy = b.copy(b.offset, b.offset + len); + b.skip(len); + return new Buffer(b_copy.toBinary(), 'binary'); + } + } + }, { + key: 'public_key', + value: function public_key(b, _public_key) { + if (!b) { + return; + } + if (_public_key) { + var buffer = _public_key.toBuffer(); + b.append(buffer.toString('binary'), 'binary'); + return; + } else { + buffer = FastParser.fixed_data(b, 33); + return PublicKey.fromBuffer(buffer); + } + } + }, { + key: 'ripemd160', + value: function ripemd160(b, _ripemd) { + if (!b) { + return; + } + if (_ripemd) { + FastParser.fixed_data(b, 20, _ripemd); + return; + } else { + return FastParser.fixed_data(b, 20); + } + } + }, { + key: 'sha256', + value: function sha256(b, _sha) { + if (!b) { + return; + } + if (_sha) { + FastParser.fixed_data(b, 32, _sha); + return; + } else { + return FastParser.fixed_data(b, 32); + } + } + }, { + key: 'time_point_sec', + value: function time_point_sec(b, epoch) { + if (epoch) { + epoch = Math.ceil(epoch / 1000); + b.writeInt32(epoch); + return; + } else { + epoch = b.readInt32(); // fc::time_point_sec + return new Date(epoch * 1000); + } + } + }]); - return Address; + return FastParser; }(); -exports.default = Address; -module.exports = exports['default']; -}).call(this,require(35).Buffer) +module.exports = FastParser; +}).call(this,require("buffer").Buffer) -},{"17":17,"27":27,"35":35,"37":37,"54":54,"70":70}],13:[function(require,module,exports){ -(function (Buffer){ +},{"../../ecc/src/PublicKey":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PublicKey.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/SerializerValidation.js":[function(require,module,exports){ 'use strict'; -exports.__esModule = true; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; -var _aes = require(45); +var _require = require('bytebuffer'), + Long = _require.Long; -var _aes2 = _interopRequireDefault(_aes); +var ChainTypes = require('../../chain/src/ChainTypes'); -var _encHex = require(49); +var MAX_SAFE_INT = 9007199254740991; +var MIN_SAFE_INT = -9007199254740991; -var _encHex2 = _interopRequireDefault(_encHex); +/** + Most validations are skipped and the value returned unchanged when an empty string, null, or undefined is encountered (except "required"). -var _encBase = require(48); + Validations support a string format for dealing with large numbers. +*/ +var _my = { -var _encBase2 = _interopRequireDefault(_encBase); + is_empty: function is_empty(value) { + return value === null || value === undefined; + }, -var _assert = require(27); + required: function required(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; -var _assert2 = _interopRequireDefault(_assert); + if (this.is_empty(value)) { + throw new Error('value required ' + field_name + ' ' + value); + } + return value; + }, + require_long: function require_long(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; -var _hash2 = require(17); + if (!Long.isLong(value)) { + throw new Error('Long value required ' + field_name + ' ' + value); + } + return value; + }, + string: function string(value) { + if (this.is_empty(value)) { + return value; + } + if (typeof value !== "string") { + throw new Error('string required: ' + value); + } + return value; + }, + number: function number(value) { + if (this.is_empty(value)) { + return value; + } + if (typeof value !== "number") { + throw new Error('number required: ' + value); + } + return value; + }, + whole_number: function whole_number(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (this.is_empty(value)) { + return value; + } + if (/\./.test(value)) { + throw new Error('whole number required ' + field_name + ' ' + value); + } + return value; + }, + unsigned: function unsigned(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // https://code.google.com/p/crypto-js + if (this.is_empty(value)) { + return value; + } + if (/-/.test(value)) { + throw new Error('unsigned required ' + field_name + ' ' + value); + } + return value; + }, -/** Provides symetric encrypt and decrypt via AES. */ -var Aes = function () { - /** @private */ - function Aes(iv, key) { - _classCallCheck(this, Aes); + is_digits: function is_digits(value) { + if (typeof value === "numeric") { + return true; + } + return (/^[0-9]+$/.test(value) + ); + }, - this.iv = iv; - this.key = key; - } + to_number: function to_number(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - /** This is an excellent way to ensure that all references to Aes can not operate anymore - * (example: a wallet becomes locked). An application should ensure there is only one - * Aes object instance for a given secret `seed`. */ + if (this.is_empty(value)) { + return value; + } + this.no_overflow53(value, field_name); + var int_value = function () { + if (typeof value === "number") { + return value; + } else { + return parseInt(value); + } + }(); + return int_value; + }, + to_long: function to_long(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - Aes.prototype.clear = function clear() { - this.iv = undefined; - this.key = undefined; - return undefined; - }; + if (this.is_empty(value)) { + return value; + } + if (Long.isLong(value)) { + return value; + } - /** @arg {string} seed - secret seed may be used to encrypt or decrypt. */ + this.no_overflow64(value, field_name); + if (typeof value === "number") { + value = "" + value; + } + return Long.fromString(value); + }, + to_ulong: function to_ulong(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + if (this.is_empty(value)) { + return value; + } + if (Long.isLong(value)) { + return value; + } - Aes.fromSeed = function fromSeed(seed) { - if (seed === undefined) { - throw new Error('seed is required'); - } + this.no_overflow64(value, field_name, true); + if (typeof value === "number") { + value = "" + value; + } + return Long.fromString(value, true); + }, + to_string: function to_string(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - var _hash = (0, _hash2.sha512)(seed); - _hash = _hash.toString('hex'); - // DEBUG console.log('... fromSeed _hash',_hash) - return Aes.fromSha512(_hash); - }; + if (this.is_empty(value)) { + return value; + } + if (typeof value === "string") { + return value; + } + if (typeof value === "number") { + this.no_overflow53(value, field_name); + return "" + value; + } + if (Long.isLong(value)) { + return value.toString(); + } + throw 'unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value; + }, + require_test: function require_test(regex, value) { + var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; - /** @arg {string} hash - A 128 byte hex string, typically one - * would call {@link fromSeed} instead. */ + if (this.is_empty(value)) { + return value; + } + if (!regex.test(value)) { + throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value); + } + return value; + }, - Aes.fromSha512 = function fromSha512(hash) { - _assert2.default.equal(hash.length, 128, 'A Sha512 in HEX should be 128 characters long, instead got ' + hash.length); - var iv = _encHex2.default.parse(hash.substring(64, 96)); - var key = _encHex2.default.parse(hash.substring(0, 64)); - return new Aes(iv, key); - }; + require_match: function require_match(regex, value) { + var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; - Aes.fromBuffer = function fromBuffer(buf) { - (0, _assert2.default)(Buffer.isBuffer(buf), 'Expecting Buffer'); - _assert2.default.equal(buf.length, 64, 'A Sha512 Buffer should be 64 characters long, instead got ' + buf.length); - return Aes.fromSha512(buf.toString('hex')); - }; + if (this.is_empty(value)) { + return value; + } + var match = value.match(regex); + if (match === null) { + throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value); + } + return match; + }, - /** - @throws {Error} - "Invalid Key, ..." - @arg {PrivateKey} private_key - required and used for decryption - @arg {PublicKey} public_key - required and used to calcualte the shared secret - @arg {string} [nonce = ""] optional but should always be provided and be unique - when re-using the same private/public keys more than once. This nonce is not a secret. - @arg {string|Buffer} message - Encrypted message containing a checksum - @return {Buffer} - */ + require_object_id: function require_object_id(value, field_name) { + return require_match(/^([0-9]+)\.([0-9]+)\.([0-9]+)$/, value, field_name); + }, + // Does not support over 53 bits + require_range: function require_range(min, max, value) { + var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ""; - Aes.decrypt_with_checksum = function decrypt_with_checksum(private_key, public_key, nonce, message) { - var legacy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + if (this.is_empty(value)) { + return value; + } + var number = this.to_number(value); + if (value < min || value > max) { + throw new Error('out of range ' + value + ' ' + field_name + ' ' + value); + } + return value; + }, - // Warning: Do not put `nonce = ""` in the arguments, in es6 this will - // not convert "null" into an emtpy string - if (nonce == null) { - nonce = ''; - } - if (!Buffer.isBuffer(message)) { - message = Buffer.from(message, 'hex'); - } + require_object_type: function require_object_type() { + var reserved_spaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + var type = arguments[1]; + var value = arguments[2]; + var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ""; - var S = private_key.get_shared_secret(public_key, legacy); - // D E B U G - // console.log('decrypt_with_checksum', { - // priv_to_pub: private_key.toPublicKey().toString(), - // pub: public_key.toPublicKeyString(), - // nonce: nonce, - // message: message.length, - // S: S.toString('hex') - // }) + if (this.is_empty(value)) { + return value; + } + var object_type = ChainTypes.object_type[type]; + if (!object_type) { + throw new Error('Unknown object type ' + type + ' ' + field_name + ' ' + value); + } + var re = new RegExp(reserved_spaces + '.' + object_type + '.[0-9]+$'); + if (!re.test(value)) { + throw new Error('Expecting ' + type + ' in format ' + (reserved_spaces + '.' + object_type + '.[0-9]+ ') + ('instead of ' + value + ' ' + field_name + ' ' + value)); + } + return value; + }, - var aes = Aes.fromSeed(Buffer.concat([ - // A null or empty string nonce will not effect the hash - Buffer.from('' + nonce), Buffer.from(S.toString('hex'))])); + get_instance: function get_instance(reserve_spaces, type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_type(reserve_spaces, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, - var planebuffer = aes.decrypt(message); + require_relative_type: function require_relative_type(type, value, field_name) { + this.require_object_type(0, type, value, field_name); + return value; + }, - if (!(planebuffer.length >= 4)) { - throw new Error('Invalid key, could not decrypt message(1)'); - } + get_relative_instance: function get_relative_instance(type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_type(0, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, - // DEBUG console.log('... planebuffer',planebuffer) - var checksum = planebuffer.slice(0, 4); - var plaintext = planebuffer.slice(4); + require_protocol_type: function require_protocol_type(type, value, field_name) { + this.require_object_type(1, type, value, field_name); + return value; + }, - // console.log('... checksum',checksum.toString('hex')) - // console.log('... plaintext',plaintext.toString()) + get_protocol_instance: function get_protocol_instance(type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_type(1, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, - var new_checksum = (0, _hash2.sha256)(plaintext); - new_checksum = new_checksum.slice(0, 4); - new_checksum = new_checksum.toString('hex'); + get_protocol_type: function get_protocol_type(value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_id(value, field_name); + var values = value.split('.'); + return this.to_number(values[1]); + }, - if (!(checksum.toString('hex') === new_checksum)) { - throw new Error('Invalid key, could not decrypt message(2)'); - } + get_protocol_type_name: function get_protocol_type_name(value, field_name) { + if (this.is_empty(value)) { + return value; + } + var type_id = this.get_protocol_type(value, field_name); + return Object.keys(ChainTypes.object_type)[type_id]; + }, - return plaintext; - }; - /** Identical to {@link decrypt_with_checksum} but used to encrypt. Should not throw an error. - @return {Buffer} message - Encrypted message which includes a checksum - */ + require_implementation_type: function require_implementation_type(type, value, field_name) { + this.require_object_type(2, type, value, field_name); + return value; + }, + get_implementation_instance: function get_implementation_instance(type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_type(2, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, - Aes.encrypt_with_checksum = function encrypt_with_checksum(private_key, public_key, nonce, message) { - // Warning: Do not put `nonce = ""` in the arguments, in es6 this will - // not convert "null" into an emtpy string + // signed / unsigned decimal + no_overflow53: function no_overflow53(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - if (nonce == null) { - nonce = ''; - } + if (typeof value === "number") { + if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { + throw new Error('overflow ' + field_name + ' ' + value); + } + return; + } + if (typeof value === "string") { + var int = parseInt(value); + if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { + throw new Error('overflow ' + field_name + ' ' + value); + } + return; + } + if (Long.isLong(value)) { + // typeof value.toInt() is 'number' + this.no_overflow53(value.toInt(), field_name); + return; + } + throw 'unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value; + }, - if (!Buffer.isBuffer(message)) { - message = Buffer.from(message, 'binary'); - } - var S = private_key.get_shared_secret(public_key); - - // D E B U G - // console.log('encrypt_with_checksum', { - // priv_to_pub: private_key.toPublicKey().toString() - // pub: public_key.toPublicKeyString() - // nonce: nonce - // message: message.length - // S: S.toString('hex') - // }) - - var aes = Aes.fromSeed(Buffer.concat([ - // A null or empty string nonce will not effect the hash - Buffer.from('' + nonce), Buffer.from(S.toString('hex'))])); - // DEBUG console.log('... S',S.toString('hex')) - var checksum = (0, _hash2.sha256)(message).slice(0, 4); - var payload = Buffer.concat([checksum, message]); - // DEBUG console.log('... payload',payload.toString()) - return aes.encrypt(payload); - }; + // signed / unsigned whole numbers only + no_overflow64: function no_overflow64(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + var unsigned = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - /** @private */ + // https://github.com/dcodeIO/Long.js/issues/20 + if (Long.isLong(value)) { + return; + } + // BigInteger#isBigInteger https://github.com/cryptocoinjs/bigi/issues/20 + if (value.t !== undefined && value.s !== undefined) { + this.no_overflow64(value.toString(), field_name, unsigned); - Aes.prototype._decrypt_word_array = function _decrypt_word_array(cipher) { - // https://code.google.com/p/crypto-js/#Custom_Key_and_IV - // see wallet_records.cpp master_key::decrypt_key - return _aes2.default.decrypt({ ciphertext: cipher, salt: null }, this.key, { iv: this.iv }); - }; + return; + } - /** @private */ + if (typeof value === "string") { + // remove leading zeros, will cause a false positive + value = value.replace(/^0+/, ''); + // remove trailing zeros + while (/0$/.test(value)) { + value = value.substring(0, value.length - 1); + } + if (/\.$/.test(value)) { + // remove trailing dot + value = value.substring(0, value.length - 1); + } + if (value === "") { + value = "0"; + } + var long_string = Long.fromString(value, unsigned).toString(); - Aes.prototype._encrypt_word_array = function _encrypt_word_array(plaintext) { - // https://code.google.com/p/crypto-js/issues/detail?id=85 - var cipher = _aes2.default.encrypt(plaintext, this.key, { iv: this.iv }); - return _encBase2.default.parse(cipher.toString()); - }; + if (long_string !== value.trim()) { + throw new Error('overflow ' + field_name + ' ' + value); + } + return; + } + if (typeof value === "number") { + if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { + throw new Error('overflow ' + field_name + ' ' + value); + } + return; + } - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} ciphertext - @return {Buffer} binary - */ + throw 'unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value; + } +}; +module.exports = _my; +},{"../../chain/src/ChainTypes":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/chain/src/ChainTypes.js","bytebuffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bytebuffer/dist/bytebuffer.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/error_with_cause.js":[function(require,module,exports){ +"use strict"; - Aes.prototype.decrypt = function decrypt(ciphertext) { - if (typeof ciphertext === 'string') { - ciphertext = Buffer.from(ciphertext, 'binary'); - } +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - if (!Buffer.isBuffer(ciphertext)) { - throw new Error('buffer required'); - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - (0, _assert2.default)(ciphertext, 'Missing cipher text'); - // hex is the only common format - var hex = this.decryptHex(ciphertext.toString('hex')); - return Buffer.from(hex, 'hex'); - }; +/** Exception nesting. */ +var ErrorWithCause = function () { + function ErrorWithCause(message, cause) { + _classCallCheck(this, ErrorWithCause); - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} plaintext - @return {Buffer} binary - */ + this.message = message; + if (typeof cause !== "undefined" && cause !== null ? cause.message : undefined) { + this.message = "cause\t" + cause.message + "\t" + this.message; + } + var stack = ""; //(new Error).stack + if (typeof cause !== "undefined" && cause !== null ? cause.stack : undefined) { + stack = "caused by\n\t" + cause.stack + "\t" + stack; + } - Aes.prototype.encrypt = function encrypt(plaintext) { - if (typeof plaintext === 'string') { - plaintext = Buffer.from(plaintext, 'binary'); + this.stack = this.message + "\n" + stack; } - if (!Buffer.isBuffer(plaintext)) { - throw new Error('buffer required'); - } + _createClass(ErrorWithCause, null, [{ + key: "throw", + value: function _throw(message, cause) { + var msg = message; + if (typeof cause !== "undefined" && cause !== null ? cause.message : undefined) { + msg += "\t cause: " + cause.message + " "; + } + if (typeof cause !== "undefined" && cause !== null ? cause.stack : undefined) { + msg += "\n stack: " + cause.stack + " "; + } + throw new Error(msg); + } + }]); - // assert plaintext, "Missing plain text" - // hex is the only common format - var hex = this.encryptHex(plaintext.toString('hex')); - return Buffer.from(hex, 'hex'); - }; + return ErrorWithCause; +}(); - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string|Buffer} plaintext - @return {string} hex - */ +module.exports = ErrorWithCause; +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/operations.js":[function(require,module,exports){ +"use strict"; +var types = require("./types"); +var SerializerImpl = require("./serializer"); + +var uint8 = types.uint8, + uint16 = types.uint16, + uint32 = types.uint32, + int64 = types.int64, + uint64 = types.uint64, + string = types.string, + bytes = types.bytes, + bool = types.bool, + array = types.array, + fixed_array = types.fixed_array, + protocol_id_type = types.protocol_id_type, + object_id_type = types.object_id_type, + vote_id = types.vote_id, + future_extensions = types.future_extensions, + static_variant = types.static_variant, + map = types.map, + set = types.set, + public_key = types.public_key, + address = types.address, + time_point_sec = types.time_point_sec, + optional = types.optional, + variant = types.variant, + variant_object = types.variant_object, + enumeration = types.enumeration, + sha256 = types.sha256; + + +future_extensions = types.void; - Aes.prototype.encryptToHex = function encryptToHex(plaintext) { - if (typeof plaintext === 'string') { - plaintext = Buffer.from(plaintext, 'binary'); - } +/* +When updating generated code +Replace: operation = static_variant [ +with: operation.st_operations = [ - if (!Buffer.isBuffer(plaintext)) { - throw new Error('buffer required'); - } +Delete: +public_key = new Serializer( + "public_key" + key_data: bytes 33 +) - // assert plaintext, "Missing plain text" - // hex is the only common format - return this.encryptHex(plaintext.toString('hex')); - }; +*/ +// Place-holder, their are dependencies on "operation" .. The final list of +// operations is not avialble until the very end of the generated code. +// See: operation.st_operations = ... +var operation = static_variant(); +module.exports["operation"] = operation; - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} cipher - hex - @return {string} binary (could easily be readable text) - */ +// For module.exports +var Serializer = function Serializer(operation_name, serilization_types_object) { + var s = new SerializerImpl(operation_name, serilization_types_object); + return module.exports[operation_name] = s; +}; +// Custom-types follow Generated code: - Aes.prototype.decryptHex = function decryptHex(cipher) { - (0, _assert2.default)(cipher, 'Missing cipher text'); - // Convert data into word arrays (used by Crypto) - var cipher_array = _encHex2.default.parse(cipher); - var plainwords = this._decrypt_word_array(cipher_array); - return _encHex2.default.stringify(plainwords); - }; +// ## Generated code follows +// # programs/js_operation_serializer > npm i -g decaffeinate +// ## ------------------------------- +var transfer_operation_fee_parameters = new Serializer("transfer_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} cipher - hex - @return {Buffer} encoded as specified by the parameter - */ +var limit_order_create_operation_fee_parameters = new Serializer("limit_order_create_operation_fee_parameters", { fee: uint64 }); +var limit_order_cancel_operation_fee_parameters = new Serializer("limit_order_cancel_operation_fee_parameters", { fee: uint64 }); - Aes.prototype.decryptHexToBuffer = function decryptHexToBuffer(cipher) { - (0, _assert2.default)(cipher, 'Missing cipher text'); - // Convert data into word arrays (used by Crypto) - var cipher_array = _encHex2.default.parse(cipher); - var plainwords = this._decrypt_word_array(cipher_array); - var plainhex = _encHex2.default.stringify(plainwords); - return Buffer.from(plainhex, 'hex'); - }; +var call_order_update_operation_fee_parameters = new Serializer("call_order_update_operation_fee_parameters", { fee: uint64 }); - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} cipher - hex - @arg {string} [encoding = 'binary'] - a valid Buffer encoding - @return {String} encoded as specified by the parameter - */ +var fill_order_operation_fee_parameters = new Serializer("fill_order_operation_fee_parameters"); +var account_create_operation_fee_parameters = new Serializer("account_create_operation_fee_parameters", { basic_fee: uint64, + premium_fee: uint64, + price_per_kbyte: uint32 }); - Aes.prototype.decryptHexToText = function decryptHexToText(cipher) { - var encoding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'binary'; +var account_update_operation_fee_parameters = new Serializer("account_update_operation_fee_parameters", { fee: int64, + price_per_kbyte: uint32 }); - return this.decryptHexToBuffer(cipher).toString(encoding); - }; +var account_whitelist_operation_fee_parameters = new Serializer("account_whitelist_operation_fee_parameters", { fee: int64 }); - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} plainhex - hex format - @return {String} hex - */ +var account_upgrade_operation_fee_parameters = new Serializer("account_upgrade_operation_fee_parameters", { membership_annual_fee: uint64, + membership_lifetime_fee: uint64 }); +var account_transfer_operation_fee_parameters = new Serializer("account_transfer_operation_fee_parameters", { fee: uint64 }); - Aes.prototype.encryptHex = function encryptHex(plainhex) { - var plain_array = _encHex2.default.parse(plainhex); - var cipher_array = this._encrypt_word_array(plain_array); - return _encHex2.default.stringify(cipher_array); - }; +var asset_create_operation_fee_parameters = new Serializer("asset_create_operation_fee_parameters", { symbol3: uint64, + symbol4: uint64, + long_symbol: uint64, + price_per_kbyte: uint32 }); - return Aes; -}(); +var asset_update_operation_fee_parameters = new Serializer("asset_update_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); -exports.default = Aes; -module.exports = exports['default']; -}).call(this,require(35).Buffer) +var asset_update_bitasset_operation_fee_parameters = new Serializer("asset_update_bitasset_operation_fee_parameters", { fee: uint64 }); -},{"17":17,"27":27,"35":35,"45":45,"48":48,"49":49}],14:[function(require,module,exports){ -(function (Buffer){ -'use strict'; +var asset_update_feed_producers_operation_fee_parameters = new Serializer("asset_update_feed_producers_operation_fee_parameters", { fee: uint64 }); -exports.__esModule = true; -exports.verifyRaw = exports.verify = exports.sign = exports.recoverPubKey = exports.deterministicGenerateK = exports.calcPubKeyRecoveryParam = undefined; +var asset_issue_operation_fee_parameters = new Serializer("asset_issue_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); -var _assert = require(27); +var asset_reserve_operation_fee_parameters = new Serializer("asset_reserve_operation_fee_parameters", { fee: uint64 }); -var _assert2 = _interopRequireDefault(_assert); +var asset_fund_fee_pool_operation_fee_parameters = new Serializer("asset_fund_fee_pool_operation_fee_parameters", { fee: uint64 }); -var _bigi = require(32); +var asset_settle_operation_fee_parameters = new Serializer("asset_settle_operation_fee_parameters", { fee: uint64 }); -var _bigi2 = _interopRequireDefault(_bigi); +var asset_global_settle_operation_fee_parameters = new Serializer("asset_global_settle_operation_fee_parameters", { fee: uint64 }); -var _hash = require(17); +var asset_publish_feed_operation_fee_parameters = new Serializer("asset_publish_feed_operation_fee_parameters", { fee: uint64 }); -var _enforce_types = require(16); +var witness_create_operation_fee_parameters = new Serializer("witness_create_operation_fee_parameters", { fee: uint64 }); -var _enforce_types2 = _interopRequireDefault(_enforce_types); +var witness_update_operation_fee_parameters = new Serializer("witness_update_operation_fee_parameters", { fee: int64 }); -var _ecsignature = require(15); +var proposal_create_operation_fee_parameters = new Serializer("proposal_create_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); -var _ecsignature2 = _interopRequireDefault(_ecsignature); +var proposal_update_operation_fee_parameters = new Serializer("proposal_update_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +var proposal_delete_operation_fee_parameters = new Serializer("proposal_delete_operation_fee_parameters", { fee: uint64 }); -// https://tools.ietf.org/html/rfc6979#section-3.2 +var withdraw_permission_create_operation_fee_parameters = new Serializer("withdraw_permission_create_operation_fee_parameters", { fee: uint64 }); -// from github.com/bitcoinjs/bitcoinjs-lib from github.com/cryptocoinjs/ecdsa -function deterministicGenerateK(curve, hash, d, checkSig, nonce) { - (0, _enforce_types2.default)('Buffer', hash); - (0, _enforce_types2.default)(_bigi2.default, d); +var withdraw_permission_update_operation_fee_parameters = new Serializer("withdraw_permission_update_operation_fee_parameters", { fee: uint64 }); - if (nonce) { - hash = (0, _hash.sha256)(Buffer.concat([hash, Buffer.alloc(nonce)])); - } +var withdraw_permission_claim_operation_fee_parameters = new Serializer("withdraw_permission_claim_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); - // sanity check - _assert2.default.equal(hash.length, 32, 'Hash must be 256 bit'); +var withdraw_permission_delete_operation_fee_parameters = new Serializer("withdraw_permission_delete_operation_fee_parameters", { fee: uint64 }); - var x = d.toBuffer(32); - var k = Buffer.alloc(32); - var v = Buffer.alloc(32); +var committee_member_create_operation_fee_parameters = new Serializer("committee_member_create_operation_fee_parameters", { fee: uint64 }); - // Step B - v.fill(1); +var committee_member_update_operation_fee_parameters = new Serializer("committee_member_update_operation_fee_parameters", { fee: uint64 }); - // Step C - k.fill(0); +var committee_member_update_global_parameters_operation_fee_parameters = new Serializer("committee_member_update_global_parameters_operation_fee_parameters", { fee: uint64 }); - // Step D - k = (0, _hash.HmacSHA256)(Buffer.concat([v, Buffer.from([0]), x, hash]), k); +var vesting_balance_create_operation_fee_parameters = new Serializer("vesting_balance_create_operation_fee_parameters", { fee: uint64 }); - // Step E - v = (0, _hash.HmacSHA256)(v, k); +var vesting_balance_withdraw_operation_fee_parameters = new Serializer("vesting_balance_withdraw_operation_fee_parameters", { fee: uint64 }); - // Step F - k = (0, _hash.HmacSHA256)(Buffer.concat([v, Buffer.from([1]), x, hash]), k); +var worker_create_operation_fee_parameters = new Serializer("worker_create_operation_fee_parameters", { fee: uint64 }); - // Step G - v = (0, _hash.HmacSHA256)(v, k); +var custom_operation_fee_parameters = new Serializer("custom_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); - // Step H1/H2a, ignored as tlen === qlen (256 bit) - // Step H2b - v = (0, _hash.HmacSHA256)(v, k); +var assert_operation_fee_parameters = new Serializer("assert_operation_fee_parameters", { fee: uint64 }); - var T = _bigi2.default.fromBuffer(v); +var balance_claim_operation_fee_parameters = new Serializer("balance_claim_operation_fee_parameters"); - // Step H3, repeat until T is within the interval [1, n - 1] - while (T.signum() <= 0 || T.compareTo(curve.n) >= 0 || !checkSig(T)) { - k = (0, _hash.HmacSHA256)(Buffer.concat([v, Buffer.from([0])]), k); - v = (0, _hash.HmacSHA256)(v, k); +var override_transfer_operation_fee_parameters = new Serializer("override_transfer_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); - // Step H1/H2a, again, ignored as tlen === qlen (256 bit) - // Step H2b again - v = (0, _hash.HmacSHA256)(v, k); +var transfer_to_blind_operation_fee_parameters = new Serializer("transfer_to_blind_operation_fee_parameters", { fee: uint64, + price_per_output: uint32 }); - T = _bigi2.default.fromBuffer(v); - } +var blind_transfer_operation_fee_parameters = new Serializer("blind_transfer_operation_fee_parameters", { fee: uint64, + price_per_output: uint32 }); - return T; -} +var transfer_from_blind_operation_fee_parameters = new Serializer("transfer_from_blind_operation_fee_parameters", { fee: uint64 }); -function sign(curve, hash, d, nonce) { - var e = _bigi2.default.fromBuffer(hash); - var n = curve.n; - var G = curve.G; +var asset_settle_cancel_operation_fee_parameters = new Serializer("asset_settle_cancel_operation_fee_parameters"); - var r = void 0; - var s = void 0; +var asset_claim_fees_operation_fee_parameters = new Serializer("asset_claim_fees_operation_fee_parameters", { fee: uint64 }); - deterministicGenerateK(curve, hash, d, function (key) { - // find canonically valid signature - var Q = G.multiply(key); +var fba_distribute_operation_fee_parameters = new Serializer("fba_distribute_operation_fee_parameters", {}); - if (curve.isInfinity(Q)) { - return false; - } +var tournament_create_operation_fee_parameters = new Serializer("tournament_create_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); - r = Q.affineX.mod(n); +var tournament_join_operation_fee_parameters = new Serializer("tournament_join_operation_fee_parameters", { fee: uint64 }); - if (r.signum() === 0) { - return false; - } +var fee_parameters = static_variant([transfer_operation_fee_parameters, limit_order_create_operation_fee_parameters, limit_order_cancel_operation_fee_parameters, call_order_update_operation_fee_parameters, fill_order_operation_fee_parameters, account_create_operation_fee_parameters, account_update_operation_fee_parameters, account_whitelist_operation_fee_parameters, account_upgrade_operation_fee_parameters, account_transfer_operation_fee_parameters, asset_create_operation_fee_parameters, asset_update_operation_fee_parameters, asset_update_bitasset_operation_fee_parameters, asset_update_feed_producers_operation_fee_parameters, asset_issue_operation_fee_parameters, asset_reserve_operation_fee_parameters, asset_fund_fee_pool_operation_fee_parameters, asset_settle_operation_fee_parameters, asset_global_settle_operation_fee_parameters, asset_publish_feed_operation_fee_parameters, witness_create_operation_fee_parameters, witness_update_operation_fee_parameters, proposal_create_operation_fee_parameters, proposal_update_operation_fee_parameters, proposal_delete_operation_fee_parameters, withdraw_permission_create_operation_fee_parameters, withdraw_permission_update_operation_fee_parameters, withdraw_permission_claim_operation_fee_parameters, withdraw_permission_delete_operation_fee_parameters, committee_member_create_operation_fee_parameters, committee_member_update_operation_fee_parameters, committee_member_update_global_parameters_operation_fee_parameters, vesting_balance_create_operation_fee_parameters, vesting_balance_withdraw_operation_fee_parameters, worker_create_operation_fee_parameters, custom_operation_fee_parameters, assert_operation_fee_parameters, balance_claim_operation_fee_parameters, override_transfer_operation_fee_parameters, transfer_to_blind_operation_fee_parameters, blind_transfer_operation_fee_parameters, transfer_from_blind_operation_fee_parameters, asset_settle_cancel_operation_fee_parameters, asset_claim_fees_operation_fee_parameters, fba_distribute_operation_fee_parameters, tournament_create_operation_fee_parameters, tournament_join_operation_fee_parameters]); - s = key.modInverse(n).multiply(e.add(d.multiply(r))).mod(n); +var fee_schedule = new Serializer("fee_schedule", { parameters: set(fee_parameters), + scale: uint32 }); - if (s.signum() === 0) { - return false; - } +var void_result = new Serializer("void_result"); - return true; - }, nonce); +var asset = new Serializer("asset", { amount: int64, + asset_id: protocol_id_type("asset") }); - var N_OVER_TWO = n.shiftRight(1); +var operation_result = static_variant([void_result, object_id_type, asset]); - // enforce low S values, see bip62: 'low s values in signatures' - if (s.compareTo(N_OVER_TWO) > 0) { - s = n.subtract(s); - } +var processed_transaction = new Serializer("processed_transaction", { ref_block_num: uint16, + ref_block_prefix: uint32, + expiration: time_point_sec, + operations: array(operation), + extensions: set(future_extensions), + signatures: array(bytes(65)), + operation_results: array(operation_result) }); + +var signed_block = new Serializer("signed_block", { previous: bytes(20), + timestamp: time_point_sec, + witness: protocol_id_type("witness"), + transaction_merkle_root: bytes(20), + extensions: set(future_extensions), + witness_signature: bytes(65), + transactions: array(processed_transaction) }); + +var block_header = new Serializer("block_header", { previous: bytes(20), + timestamp: time_point_sec, + witness: protocol_id_type("witness"), + transaction_merkle_root: bytes(20), + extensions: set(future_extensions) }); + +var signed_block_header = new Serializer("signed_block_header", { previous: bytes(20), + timestamp: time_point_sec, + witness: protocol_id_type("witness"), + transaction_merkle_root: bytes(20), + extensions: set(future_extensions), + witness_signature: bytes(65) }); + +var memo_data = new Serializer("memo_data", { from: public_key, + to: public_key, + nonce: uint64, + message: bytes() }); + +var transfer = new Serializer("transfer", { fee: asset, + from: protocol_id_type("account"), + to: protocol_id_type("account"), + amount: asset, + memo: optional(memo_data), + extensions: set(future_extensions) }); + +var limit_order_create = new Serializer("limit_order_create", { fee: asset, + seller: protocol_id_type("account"), + amount_to_sell: asset, + min_to_receive: asset, + expiration: time_point_sec, + fill_or_kill: bool, + extensions: set(future_extensions) }); + +var limit_order_cancel = new Serializer("limit_order_cancel", { fee: asset, + fee_paying_account: protocol_id_type("account"), + order: protocol_id_type("limit_order"), + extensions: set(future_extensions) }); + +var call_order_update = new Serializer("call_order_update", { fee: asset, + funding_account: protocol_id_type("account"), + delta_collateral: asset, + delta_debt: asset, + extensions: set(future_extensions) }); + +var fill_order = new Serializer("fill_order", { fee: asset, + order_id: object_id_type, + account_id: protocol_id_type("account"), + pays: asset, + receives: asset }); + +var authority = new Serializer("authority", { weight_threshold: uint32, + account_auths: map(protocol_id_type("account"), uint16), + key_auths: map(public_key, uint16), + address_auths: map(address, uint16) }); + +var account_options = new Serializer("account_options", { memo_key: public_key, + voting_account: protocol_id_type("account"), + num_witness: uint16, + num_committee: uint16, + votes: set(vote_id), + extensions: set(future_extensions) }); + +var account_create = new Serializer("account_create", { fee: asset, + registrar: protocol_id_type("account"), + referrer: protocol_id_type("account"), + referrer_percent: uint16, + name: string, + owner: authority, + active: authority, + options: account_options, + extensions: set(future_extensions) }); + +var account_update = new Serializer("account_update", { fee: asset, + account: protocol_id_type("account"), + owner: optional(authority), + active: optional(authority), + new_options: optional(account_options), + extensions: set(future_extensions) }); + +var account_whitelist = new Serializer("account_whitelist", { fee: asset, + authorizing_account: protocol_id_type("account"), + account_to_list: protocol_id_type("account"), + new_listing: uint8, + extensions: set(future_extensions) }); + +var account_upgrade = new Serializer("account_upgrade", { fee: asset, + account_to_upgrade: protocol_id_type("account"), + upgrade_to_lifetime_member: bool, + extensions: set(future_extensions) }); + +var account_transfer = new Serializer("account_transfer", { fee: asset, + account_id: protocol_id_type("account"), + new_owner: protocol_id_type("account"), + extensions: set(future_extensions) }); + +var price = new Serializer("price", { base: asset, + quote: asset }); + +var asset_options = new Serializer("asset_options", { max_supply: int64, + market_fee_percent: uint16, + max_market_fee: int64, + issuer_permissions: uint16, + flags: uint16, + core_exchange_rate: price, + whitelist_authorities: set(protocol_id_type("account")), + blacklist_authorities: set(protocol_id_type("account")), + whitelist_markets: set(protocol_id_type("asset")), + blacklist_markets: set(protocol_id_type("asset")), + description: string, + extensions: set(future_extensions) }); + +var bitasset_options = new Serializer("bitasset_options", { feed_lifetime_sec: uint32, + minimum_feeds: uint8, + force_settlement_delay_sec: uint32, + force_settlement_offset_percent: uint16, + maximum_force_settlement_volume: uint16, + short_backing_asset: protocol_id_type("asset"), + extensions: set(future_extensions) }); + +var asset_create = new Serializer("asset_create", { fee: asset, + issuer: protocol_id_type("account"), + symbol: string, + precision: uint8, + common_options: asset_options, + bitasset_opts: optional(bitasset_options), + is_prediction_market: bool, + extensions: set(future_extensions) }); + +var asset_update = new Serializer("asset_update", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_update: protocol_id_type("asset"), + new_issuer: optional(protocol_id_type("account")), + new_options: asset_options, + extensions: set(future_extensions) }); + +var asset_update_bitasset = new Serializer("asset_update_bitasset", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_update: protocol_id_type("asset"), + new_options: bitasset_options, + extensions: set(future_extensions) }); + +var asset_update_feed_producers = new Serializer("asset_update_feed_producers", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_update: protocol_id_type("asset"), + new_feed_producers: set(protocol_id_type("account")), + extensions: set(future_extensions) }); + +var asset_issue = new Serializer("asset_issue", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_issue: asset, + issue_to_account: protocol_id_type("account"), + memo: optional(memo_data), + extensions: set(future_extensions) }); + +var asset_reserve = new Serializer("asset_reserve", { fee: asset, + payer: protocol_id_type("account"), + amount_to_reserve: asset, + extensions: set(future_extensions) }); + +var asset_fund_fee_pool = new Serializer("asset_fund_fee_pool", { fee: asset, + from_account: protocol_id_type("account"), + asset_id: protocol_id_type("asset"), + amount: int64, + extensions: set(future_extensions) }); + +var asset_settle = new Serializer("asset_settle", { fee: asset, + account: protocol_id_type("account"), + amount: asset, + extensions: set(future_extensions) }); + +var asset_global_settle = new Serializer("asset_global_settle", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_settle: protocol_id_type("asset"), + settle_price: price, + extensions: set(future_extensions) }); + +var price_feed = new Serializer("price_feed", { settlement_price: price, + maintenance_collateral_ratio: uint16, + maximum_short_squeeze_ratio: uint16, + core_exchange_rate: price }); + +var asset_publish_feed = new Serializer("asset_publish_feed", { fee: asset, + publisher: protocol_id_type("account"), + asset_id: protocol_id_type("asset"), + feed: price_feed, + extensions: set(future_extensions) }); + +var witness_create = new Serializer("witness_create", { fee: asset, + witness_account: protocol_id_type("account"), + url: string, + block_signing_key: public_key }); + +var witness_update = new Serializer("witness_update", { fee: asset, + witness: protocol_id_type("witness"), + witness_account: protocol_id_type("account"), + new_url: optional(string), + new_signing_key: optional(public_key) }); + +var op_wrapper = new Serializer("op_wrapper", { op: operation }); + +var proposal_create = new Serializer("proposal_create", { fee: asset, + fee_paying_account: protocol_id_type("account"), + expiration_time: time_point_sec, + proposed_ops: array(op_wrapper), + review_period_seconds: optional(uint32), + extensions: set(future_extensions) }); + +var proposal_update = new Serializer("proposal_update", { fee: asset, + fee_paying_account: protocol_id_type("account"), + proposal: protocol_id_type("proposal"), + active_approvals_to_add: set(protocol_id_type("account")), + active_approvals_to_remove: set(protocol_id_type("account")), + owner_approvals_to_add: set(protocol_id_type("account")), + owner_approvals_to_remove: set(protocol_id_type("account")), + key_approvals_to_add: set(public_key), + key_approvals_to_remove: set(public_key), + extensions: set(future_extensions) }); + +var proposal_delete = new Serializer("proposal_delete", { fee: asset, + fee_paying_account: protocol_id_type("account"), + using_owner_authority: bool, + proposal: protocol_id_type("proposal"), + extensions: set(future_extensions) }); + +var withdraw_permission_create = new Serializer("withdraw_permission_create", { fee: asset, + withdraw_from_account: protocol_id_type("account"), + authorized_account: protocol_id_type("account"), + withdrawal_limit: asset, + withdrawal_period_sec: uint32, + periods_until_expiration: uint32, + period_start_time: time_point_sec }); + +var withdraw_permission_update = new Serializer("withdraw_permission_update", { fee: asset, + withdraw_from_account: protocol_id_type("account"), + authorized_account: protocol_id_type("account"), + permission_to_update: protocol_id_type("withdraw_permission"), + withdrawal_limit: asset, + withdrawal_period_sec: uint32, + period_start_time: time_point_sec, + periods_until_expiration: uint32 }); + +var withdraw_permission_claim = new Serializer("withdraw_permission_claim", { fee: asset, + withdraw_permission: protocol_id_type("withdraw_permission"), + withdraw_from_account: protocol_id_type("account"), + withdraw_to_account: protocol_id_type("account"), + amount_to_withdraw: asset, + memo: optional(memo_data) }); + +var withdraw_permission_delete = new Serializer("withdraw_permission_delete", { fee: asset, + withdraw_from_account: protocol_id_type("account"), + authorized_account: protocol_id_type("account"), + withdrawal_permission: protocol_id_type("withdraw_permission") }); + +var committee_member_create = new Serializer("committee_member_create", { fee: asset, + committee_member_account: protocol_id_type("account"), + url: string }); + +var committee_member_update = new Serializer("committee_member_update", { fee: asset, + committee_member: protocol_id_type("committee_member"), + committee_member_account: protocol_id_type("account"), + new_url: optional(string) }); + +var chain_parameters = new Serializer("chain_parameters", { current_fees: fee_schedule, + block_interval: uint8, + maintenance_interval: uint32, + maintenance_skip_slots: uint8, + committee_proposal_review_period: uint32, + maximum_transaction_size: uint32, + maximum_block_size: uint32, + maximum_time_until_expiration: uint32, + maximum_proposal_lifetime: uint32, + maximum_asset_whitelist_authorities: uint8, + maximum_asset_feed_publishers: uint8, + maximum_witness_count: uint16, + maximum_committee_count: uint16, + maximum_authority_membership: uint16, + reserve_percent_of_fee: uint16, + network_percent_of_fee: uint16, + lifetime_referrer_percent_of_fee: uint16, + cashback_vesting_period_seconds: uint32, + cashback_vesting_threshold: int64, + count_non_member_votes: bool, + allow_non_member_whitelists: bool, + witness_pay_per_block: int64, + worker_budget_per_day: int64, + max_predicate_opcode: uint16, + fee_liquidation_threshold: int64, + accounts_per_fee_scale: uint16, + account_fee_scale_bitshifts: uint8, + max_authority_depth: uint8, + extensions: set(future_extensions) }); + +var committee_member_update_global_parameters = new Serializer("committee_member_update_global_parameters", { fee: asset, + new_parameters: chain_parameters }); + +var linear_vesting_policy_initializer = new Serializer("linear_vesting_policy_initializer", { begin_timestamp: time_point_sec, + vesting_cliff_seconds: uint32, + vesting_duration_seconds: uint32 }); + +var cdd_vesting_policy_initializer = new Serializer("cdd_vesting_policy_initializer", { start_claim: time_point_sec, + vesting_seconds: uint32 }); - return new _ecsignature2.default(r, s); -} +var vesting_policy_initializer = static_variant([linear_vesting_policy_initializer, cdd_vesting_policy_initializer]); -function verifyRaw(curve, e, signature, Q) { - var n = curve.n; - var G = curve.G; +var vesting_balance_create = new Serializer("vesting_balance_create", { fee: asset, + creator: protocol_id_type("account"), + owner: protocol_id_type("account"), + amount: asset, + policy: vesting_policy_initializer }); - var r = signature.r; - var s = signature.s; +var vesting_balance_withdraw = new Serializer("vesting_balance_withdraw", { fee: asset, + vesting_balance: protocol_id_type("vesting_balance"), + owner: protocol_id_type("account"), + amount: asset }); - // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] - if (r.signum() <= 0 || r.compareTo(n) >= 0) { - return false; - } +var refund_worker_initializer = new Serializer("refund_worker_initializer"); - if (s.signum() <= 0 || s.compareTo(n) >= 0) { - return false; - } +var vesting_balance_worker_initializer = new Serializer("vesting_balance_worker_initializer", { pay_vesting_period_days: uint16 }); - // c = s^-1 mod n - var c = s.modInverse(n); +var burn_worker_initializer = new Serializer("burn_worker_initializer"); - // 1.4.4 Compute u1 = es^−1 mod n - // u2 = rs^−1 mod n - var u1 = e.multiply(c).mod(n); - var u2 = r.multiply(c).mod(n); +var worker_initializer = static_variant([refund_worker_initializer, vesting_balance_worker_initializer, burn_worker_initializer]); - // 1.4.5 Compute R = (xR, yR) = u1G + u2Q - var R = G.multiplyTwo(u1, Q, u2); +var worker_create = new Serializer("worker_create", { fee: asset, + owner: protocol_id_type("account"), + work_begin_date: time_point_sec, + work_end_date: time_point_sec, + daily_pay: int64, + name: string, + url: string, + initializer: worker_initializer }); - // 1.4.5 (cont.) Enforce R is not at infinity - if (curve.isInfinity(R)) { - return false; - } +var custom = new Serializer("custom", { fee: asset, + payer: protocol_id_type("account"), + required_auths: set(protocol_id_type("account")), + id: uint16, + data: bytes() }); - // 1.4.6 Convert the field element R.x to an integer - var xR = R.affineX; +var account_name_eq_lit_predicate = new Serializer("account_name_eq_lit_predicate", { account_id: protocol_id_type("account"), + name: string }); - // 1.4.7 Set v = xR mod n - var v = xR.mod(n); +var asset_symbol_eq_lit_predicate = new Serializer("asset_symbol_eq_lit_predicate", { asset_id: protocol_id_type("asset"), + symbol: string }); - // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" - return v.equals(r); -} +var block_id_predicate = new Serializer("block_id_predicate", { id: bytes(20) }); -function verify(curve, hash, signature, Q) { - // 1.4.2 H = Hash(M), already done by the user - // 1.4.3 e = H - var e = _bigi2.default.fromBuffer(hash); - return verifyRaw(curve, e, signature, Q); -} +var predicate = static_variant([account_name_eq_lit_predicate, asset_symbol_eq_lit_predicate, block_id_predicate]); -/** - * Recover a public key from a signature. - * - * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public - * Key Recovery Operation". - * - * http://www.secg.org/download/aid-780/sec1-v2.pdf - */ -function recoverPubKey(curve, e, signature, i) { - _assert2.default.strictEqual(i & 3, i, 'Recovery param is more than two bits'); // eslint-disable-line +var assert = new Serializer("assert", { fee: asset, + fee_paying_account: protocol_id_type("account"), + predicates: array(predicate), + required_auths: set(protocol_id_type("account")), + extensions: set(future_extensions) }); + +var balance_claim = new Serializer("balance_claim", { fee: asset, + deposit_to_account: protocol_id_type("account"), + balance_to_claim: protocol_id_type("balance"), + balance_owner_key: public_key, + total_claimed: asset }); + +var override_transfer = new Serializer("override_transfer", { fee: asset, + issuer: protocol_id_type("account"), + from: protocol_id_type("account"), + to: protocol_id_type("account"), + amount: asset, + memo: optional(memo_data), + extensions: set(future_extensions) }); + +var stealth_confirmation = new Serializer("stealth_confirmation", { one_time_key: public_key, + to: optional(public_key), + encrypted_memo: bytes() }); + +var blind_output = new Serializer("blind_output", { commitment: bytes(33), + range_proof: bytes(), + owner: authority, + stealth_memo: optional(stealth_confirmation) }); + +var transfer_to_blind = new Serializer("transfer_to_blind", { fee: asset, + amount: asset, + from: protocol_id_type("account"), + blinding_factor: bytes(32), + outputs: array(blind_output) }); + +var blind_input = new Serializer("blind_input", { commitment: bytes(33), + owner: authority }); + +var blind_transfer = new Serializer("blind_transfer", { fee: asset, + inputs: array(blind_input), + outputs: array(blind_output) }); + +var transfer_from_blind = new Serializer("transfer_from_blind", { fee: asset, + amount: asset, + to: protocol_id_type("account"), + blinding_factor: bytes(32), + inputs: array(blind_input) }); + +var asset_settle_cancel = new Serializer("asset_settle_cancel", { fee: asset, + settlement: protocol_id_type("force_settlement"), + account: protocol_id_type("account"), + amount: asset, + extensions: set(future_extensions) }); + +var asset_claim_fees = new Serializer("asset_claim_fees", { fee: asset, + issuer: protocol_id_type("account"), + amount_to_claim: asset, + extensions: set(future_extensions) }); + +var fba_distribute = new Serializer("fba_distribute", { fee: asset, + account_id: protocol_id_type("account"), + fba_id: protocol_id_type("fba_accumulator"), + amount: int64 }); + +var dividend_asset_options = new Serializer("dividend_asset_options", { next_payout_time: optional(time_point_sec), + payout_interval: optional(uint32), + minimum_fee_percentage: uint64, + minimum_distribution_interval: optional(uint32), + extensions: set(future_extensions) }); + +var asset_update_dividend = new Serializer("asset_update_dividend", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_update: protocol_id_type("asset"), + new_options: dividend_asset_options, + extensions: set(future_extensions) }); + +var rock_paper_scissors_game_options = new Serializer("rock_paper_scissors_game_options", { insurance_enabled: bool, + time_per_commit_move: uint32, + time_per_reveal_move: uint32, + number_of_gestures: uint8 }); - var n = curve.n; - var G = curve.G; +var game_specific_details = static_variant([rock_paper_scissors_game_options]); - var r = signature.r; - var s = signature.s; +var tournament_options = new Serializer("tournament_options", { + type_of_game: uint16, + registration_deadline: time_point_sec, + number_of_players: uint32, + buy_in: asset, + whitelist: set(protocol_id_type("account")), + start_time: optional(time_point_sec), + start_delay: optional(uint32), + round_delay: uint32, + number_of_wins: uint32, + meta: variant_object, + game_options: game_specific_details +}); - (0, _assert2.default)(r.signum() > 0 && r.compareTo(n) < 0, 'Invalid r value'); - (0, _assert2.default)(s.signum() > 0 && s.compareTo(n) < 0, 'Invalid s value'); +var tournament_create = new Serializer("tournament_create", { fee: asset, + creator: protocol_id_type("account"), + options: tournament_options, + extensions: set(future_extensions) }); - // A set LSB signifies that the y-coordinate is odd - var isYOdd = i & 1; // eslint-disable-line +var tournament_join = new Serializer("tournament_join", { fee: asset, + payer_account_id: protocol_id_type("account"), + player_account_id: protocol_id_type("account"), + tournament_id: protocol_id_type("tournament"), + buy_in: asset, + extensions: set(future_extensions) }); - // The more significant bit specifies whether we should use the - // first or second candidate key. - var isSecondKey = i >> 1; // eslint-disable-line +var rock_paper_scissors_gesture = enumeration(["rock", "paper", "scissors", "spock", "lizard"]); - // 1.1 Let x = r + jn - var x = isSecondKey ? r.add(n) : r; - var R = curve.pointFromX(isYOdd, x); +var rock_paper_scissors_throw_commit = new Serializer("rock_paper_scissors_throw_commit", { nonce1: uint64, + throw_hash: sha256 }); - // 1.4 Check that nR is at infinity - var nR = R.multiply(n); - (0, _assert2.default)(curve.isInfinity(nR), 'nR is not a valid curve point'); +var rock_paper_scissors_throw_reveal = new Serializer("rock_paper_scissors_throw_reveal", { nonce2: uint64, + gesture: rock_paper_scissors_gesture }); - // Compute -e from e - var eNeg = e.negate().mod(n); +var game_specific_moves = static_variant([rock_paper_scissors_throw_commit, rock_paper_scissors_throw_reveal]); - // 1.6.1 Compute Q = r^-1 (sR - eG) - // Q = r^-1 (sR + -eG) - var rInv = r.modInverse(n); +var game_move = new Serializer("game_move", { fee: asset, + game_id: protocol_id_type("game"), + player_account_id: protocol_id_type("account"), + move: game_specific_moves, + extensions: set(future_extensions) }); + +operation.st_operations = [transfer, limit_order_create, limit_order_cancel, call_order_update, fill_order, account_create, account_update, account_whitelist, account_upgrade, account_transfer, asset_create, asset_update, asset_update_bitasset, asset_update_feed_producers, asset_issue, asset_reserve, asset_fund_fee_pool, asset_settle, asset_global_settle, asset_publish_feed, witness_create, witness_update, proposal_create, proposal_update, proposal_delete, withdraw_permission_create, withdraw_permission_update, withdraw_permission_claim, withdraw_permission_delete, committee_member_create, committee_member_update, committee_member_update_global_parameters, vesting_balance_create, vesting_balance_withdraw, worker_create, custom, assert, balance_claim, override_transfer, transfer_to_blind, blind_transfer, transfer_from_blind, asset_settle_cancel, asset_claim_fees, fba_distribute, tournament_create, tournament_join, game_move, asset_update_dividend]; + +var transaction = new Serializer("transaction", { ref_block_num: uint16, + ref_block_prefix: uint32, + expiration: time_point_sec, + operations: array(operation), + extensions: set(future_extensions) }); + +var signed_transaction = new Serializer("signed_transaction", { ref_block_num: uint16, + ref_block_prefix: uint32, + expiration: time_point_sec, + operations: array(operation), + extensions: set(future_extensions), + signatures: array(bytes(65)) }); +//# ------------------------------- +//# Generated code end +//# ------------------------------- - var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv); - curve.validate(Q); +// Custom Types - return Q; -} +var stealth_memo_data = new Serializer("stealth_memo_data", { + from: optional(public_key), + amount: asset, + blinding_factor: bytes(32), + commitment: bytes(33), + check: uint32 +}); +// var stealth_confirmation = new Serializer( +// "stealth_confirmation", { +// one_time_key: public_key, +// to: optional( public_key ), +// encrypted_memo: stealth_memo_data +// }) +},{"./serializer":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/serializer.js","./types":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/types.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/serializer.js":[function(require,module,exports){ +(function (process,Buffer){ +'use strict'; -/** - * Calculate pubkey extraction parameter. - * - * When extracting a pubkey from a signature, we have to - * distinguish four different cases. Rather than putting this - * burden on the verifier, Bitcoin includes a 2-bit value with the - * signature. - * - * This function simply tries all four cases and returns the value - * that resulted in a successful pubkey recovery. - */ -function calcPubKeyRecoveryParam(curve, e, signature, Q) { - for (var i = 0; i < 4; i++) { - var Qprime = recoverPubKey(curve, e, signature, i); +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - // 1.6.2 Verify Q - if (Qprime.equals(Q)) { - return i; - } - } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - throw new Error('Unable to find valid recovery factor'); -} +var ByteBuffer = require('bytebuffer'); +var EC = require('./error_with_cause'); -exports.calcPubKeyRecoveryParam = calcPubKeyRecoveryParam; -exports.deterministicGenerateK = deterministicGenerateK; -exports.recoverPubKey = recoverPubKey; -exports.sign = sign; -exports.verify = verify; -exports.verifyRaw = verifyRaw; -}).call(this,require(35).Buffer) +var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; -},{"15":15,"16":16,"17":17,"27":27,"32":32,"35":35}],15:[function(require,module,exports){ -(function (Buffer){ -'use strict'; +var Serializer = function () { + function Serializer(operation_name, types) { + _classCallCheck(this, Serializer); + + this.operation_name = operation_name; + this.types = types; + if (this.types) this.keys = Object.keys(this.types); + + Serializer.printDebug = true; + } + + _createClass(Serializer, [{ + key: 'fromByteBuffer', + value: function fromByteBuffer(b) { + var object = {}; + var field = null; + try { + var iterable = this.keys; + for (var i = 0, field; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + try { + if (HEX_DUMP) { + if (type.operation_name) { + console.error(type.operation_name); + } else { + var o1 = b.offset; + type.fromByteBuffer(b); + var o2 = b.offset; + b.offset = o1; + //b.reset() + var _b = b.copy(o1, o2); + console.error(this.operation_name + '.' + field + '\t', _b.toHex()); + } + } + object[field] = type.fromByteBuffer(b); + } catch (e) { + if (Serializer.printDebug) { + console.error('Error reading ' + this.operation_name + '.' + field + ' in data:'); + b.printDebug(); + } + throw e; + } + } + } catch (error) { + EC.throw(this.operation_name + '.' + field, error); + } -exports.__esModule = true; + return object; + } + }, { + key: 'appendByteBuffer', + value: function appendByteBuffer(b, object) { + var field = null; + try { + var iterable = this.keys; + for (var i = 0, field; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + type.appendByteBuffer(b, object[field]); + } + } catch (error) { + try { + EC.throw(this.operation_name + '.' + field + " = " + JSON.stringify(object[field]), error); + } catch (e) { + // circular ref + EC.throw(this.operation_name + '.' + field + " = " + object[field], error); + } + } + return; + } + }, { + key: 'fromObject', + value: function fromObject(serialized_object) { + var result = {}; + var field = null; + try { + var iterable = this.keys; + for (var i = 0, field; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + var value = serialized_object[field]; + //DEBUG value = value.resolve if value.resolve + //DEBUG console.log('... value',field,value) + var object = type.fromObject(value); + result[field] = object; + } + } catch (error) { + EC.throw(this.operation_name + '.' + field, error); + } -var _assert = require(27); + return result; + } -var _assert2 = _interopRequireDefault(_assert); + /** + @arg {boolean} [debug.use_default = false] - more template friendly + @arg {boolean} [debug.annotate = false] - add user-friendly information + */ -var _bigi = require(32); + }, { + key: 'toObject', + value: function toObject() { + var serialized_object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { use_default: false, annotate: false }; + + var result = {}; + var field = null; + try { + if (!this.types) return result; + + var iterable = this.keys; + for (var i = 0, field; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + var object = type.toObject(typeof serialized_object !== "undefined" && serialized_object !== null ? serialized_object[field] : undefined, debug); + result[field] = object; + if (HEX_DUMP) { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + type.appendByteBuffer(b, typeof serialized_object !== "undefined" && serialized_object !== null ? serialized_object[field] : undefined); + b = b.copy(0, b.offset); + console.error(this.operation_name + '.' + field, b.toHex()); + } + } + } catch (error) { + EC.throw(this.operation_name + '.' + field, error); + } -var _bigi2 = _interopRequireDefault(_bigi); + return result; + } -var _enforce_types = require(16); + /** Sort by the first element in a operation */ -var _enforce_types2 = _interopRequireDefault(_enforce_types); + }, { + key: 'compare', + value: function compare(a, b) { -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + var first_key = this.keys[0]; + var first_type = this.types[first_key]; -// from https://github.com/bitcoinjs/bitcoinjs-lib -function ECSignature(r, s) { - (0, _enforce_types2.default)(_bigi2.default, r); - (0, _enforce_types2.default)(_bigi2.default, s); + var valA = a[first_key]; + var valB = b[first_key]; - this.r = r; - this.s = s; -} + if (first_type.compare) return first_type.compare(valA, valB); -// Import operations -/* eslint no-bitwise: "off" */ -ECSignature.parseCompact = function (buffer) { - _assert2.default.equal(buffer.length, 65, 'Invalid signature length'); - var i = buffer.readUInt8(0) - 27; + if (typeof valA === "number" && typeof valB === "number") return valA - valB; - // At most 3 bits - _assert2.default.equal(i, i & 7, 'Invalid signature parameter'); - var compressed = !!(i & 4); + var encoding = void 0; + if (Buffer.isBuffer(valA) && Buffer.isBuffer(valB)) { + // A binary string compare does not work. If localeCompare is well supported that could replace HEX. Performanance is very good so comparing HEX works. + encoding = "hex"; + } - // Recovery param only - i &= 3; + var strA = valA.toString(encoding); + var strB = valB.toString(encoding); + return strA > strB ? 1 : strA < strB ? -1 : 0; + } - var r = _bigi2.default.fromBuffer(buffer.slice(1, 33)); - var s = _bigi2.default.fromBuffer(buffer.slice(33)); + // - return { - compressed: compressed, - i: i, - signature: new ECSignature(r, s) - }; -}; + }, { + key: 'fromHex', + value: function fromHex(hex) { + var b = ByteBuffer.fromHex(hex, ByteBuffer.LITTLE_ENDIAN); + return this.fromByteBuffer(b); + } + }, { + key: 'fromBuffer', + value: function fromBuffer(buffer) { + var b = ByteBuffer.fromBinary(buffer.toString("binary"), ByteBuffer.LITTLE_ENDIAN); + return this.fromByteBuffer(b); + } + }, { + key: 'toHex', + value: function toHex(object) { + // return this.toBuffer(object).toString("hex") + var b = this.toByteBuffer(object); + return b.toHex(); + } + }, { + key: 'toByteBuffer', + value: function toByteBuffer(object) { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b, object); + return b.copy(0, b.offset); + } + }, { + key: 'toBuffer', + value: function toBuffer(object) { + return new Buffer(this.toByteBuffer(object).toBinary(), 'binary'); + } + }]); -ECSignature.fromDER = function (buffer) { - _assert2.default.equal(buffer.readUInt8(0), 0x30, 'Not a DER sequence'); - _assert2.default.equal(buffer.readUInt8(1), buffer.length - 2, 'Invalid sequence length'); - _assert2.default.equal(buffer.readUInt8(2), 0x02, 'Expected a DER integer'); + return Serializer; +}(); - var rLen = buffer.readUInt8(3); - (0, _assert2.default)(rLen > 0, 'R length is zero'); +module.exports = Serializer; +}).call(this,require('_process'),require("buffer").Buffer) - var offset = 4 + rLen; - _assert2.default.equal(buffer.readUInt8(offset), 0x02, 'Expected a DER integer (2)'); +},{"./error_with_cause":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/error_with_cause.js","_process":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process/browser.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","bytebuffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bytebuffer/dist/bytebuffer.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/template.js":[function(require,module,exports){ +"use strict"; - var sLen = buffer.readUInt8(offset + 1); - (0, _assert2.default)(sLen > 0, 'S length is zero'); - - var rB = buffer.slice(4, offset); - var sB = buffer.slice(offset + 2); - offset += 2 + sLen; - - if (rLen > 1 && rB.readUInt8(0) === 0x00) { - (0, _assert2.default)(rB.readUInt8(1) & 0x80, 'R value excessively padded'); - } - - if (sLen > 1 && sB.readUInt8(0) === 0x00) { - (0, _assert2.default)(sB.readUInt8(1) & 0x80, 'S value excessively padded'); - } - - _assert2.default.equal(offset, buffer.length, 'Invalid DER encoding'); - var r = _bigi2.default.fromDERInteger(rB); - var s = _bigi2.default.fromDERInteger(sB); - - (0, _assert2.default)(r.signum() >= 0, 'R value is negative'); - (0, _assert2.default)(s.signum() >= 0, 'S value is negative'); - - return new ECSignature(r, s); -}; - -// FIXME: 0x00, 0x04, 0x80 are SIGHASH_* boundary constants, -// importing Transaction causes a circular dependency -ECSignature.parseScriptSignature = function (buffer) { - var hashType = buffer.readUInt8(buffer.length - 1); - var hashTypeMod = hashType & ~0x80; - - (0, _assert2.default)(hashTypeMod > 0x00 && hashTypeMod < 0x04, 'Invalid hashType'); - - return { - signature: ECSignature.fromDER(buffer.slice(0, -1)), - hashType: hashType - }; -}; - -// Export operations -ECSignature.prototype.toCompact = function toCompact(i, compressed) { - if (compressed) { - i += 4; - } - - i += 27; - - var buffer = Buffer.alloc(65); - buffer.writeUInt8(i, 0); - - this.r.toBuffer(32).copy(buffer, 1); - this.s.toBuffer(32).copy(buffer, 33); - - return buffer; -}; - -ECSignature.prototype.toDER = function toDER() { - var rBa = this.r.toDERInteger(); - var sBa = this.s.toDERInteger(); - - var sequence = []; - - // INTEGER - sequence.push(0x02, rBa.length); - sequence = sequence.concat(rBa); - - // INTEGER - sequence.push(0x02, sBa.length); - sequence = sequence.concat(sBa); - - // SEQUENCE - sequence.unshift(0x30, sequence.length); - - return Buffer.from(sequence); -}; - -ECSignature.prototype.toScriptSignature = function toScriptSignature(hashType) { - var hashTypeBuffer = Buffer.alloc(1); - hashTypeBuffer.writeUInt8(hashType, 0); - - return Buffer.concat([this.toDER(), hashTypeBuffer]); -}; - -exports.default = ECSignature; -module.exports = exports['default']; -}).call(this,require(35).Buffer) - -},{"16":16,"27":27,"32":32,"35":35}],16:[function(require,module,exports){ -(function (Buffer){ -'use strict'; - -exports.__esModule = true; -exports.default = enforce; - -function getName(fn) { - // Why not fn.name: https://kangax.github.io/compat-table/es6/#function_name_property - var match = fn.toString().match(/function (.*?)\(/); - return match ? match[1] : null; -} - -function enforce(type, value) { - // Copied from https://github.com/bitcoinjs/bitcoinjs-lib - switch (type) { - case 'Array': - { - if (Array.isArray(value)) { - return; - } - - break; - } - - case 'Boolean': - { - if (typeof value === 'boolean') { - return; - } - - break; - } - - case 'Buffer': - { - if (Buffer.isBuffer(value)) { - return; - } - - break; - } - - case 'Number': - { - if (typeof value === 'number') { - return; - } - - break; - } - - case 'String': - { - if (typeof value === 'string') { - return; - } - - break; - } - - default: - { - if (getName(value.constructor) === getName(type)) { - return; - } - } - } - - throw new TypeError('Expected ' + (getName(type) || type) + ', got ' + value); -} -module.exports = exports['default']; -}).call(this,{"isBuffer":require(66)}) - -},{"66":66}],17:[function(require,module,exports){ -'use strict'; - -exports.__esModule = true; -exports.ripemd160 = exports.HmacSHA256 = exports.sha512 = exports.sha256 = exports.sha1 = undefined; - -var _createHash = require(41); - -var _createHash2 = _interopRequireDefault(_createHash); - -var _createHmac = require(43); - -var _createHmac2 = _interopRequireDefault(_createHmac); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** @arg {string|Buffer} data - @arg {string} [digest = null] - 'hex', 'binary' or 'base64' - @return {string|Buffer} - Buffer when digest is null, or string -*/ -function sha1(data, encoding) { - return (0, _createHash2.default)('sha1').update(data).digest(encoding); -} - -/** @arg {string|Buffer} data - @arg {string} [digest = null] - 'hex', 'binary' or 'base64' - @return {string|Buffer} - Buffer when digest is null, or string -*/ -function sha256(data, encoding) { - return (0, _createHash2.default)('sha256').update(data).digest(encoding); -} - -/** @arg {string|Buffer} data - @arg {string} [digest = null] - 'hex', 'binary' or 'base64' - @return {string|Buffer} - Buffer when digest is null, or string -*/ -function sha512(data, encoding) { - return (0, _createHash2.default)('sha512').update(data).digest(encoding); -} - -function HmacSHA256(buffer, secret) { - return (0, _createHmac2.default)('sha256', secret).update(buffer).digest(); -} - -function ripemd160(data) { - return (0, _createHash2.default)('rmd160').update(data).digest(); -} - -// function hash160(buffer) { -// return ripemd160(sha256(buffer)) -// } -// -// function hash256(buffer) { -// return sha256(sha256(buffer)) -// } - -// -// function HmacSHA512(buffer, secret) { -// return crypto.createHmac('sha512', secret).update(buffer).digest() -// } - -exports.sha1 = sha1; -exports.sha256 = sha256; -exports.sha512 = sha512; -exports.HmacSHA256 = HmacSHA256; -exports.ripemd160 = ripemd160; -},{"41":41,"43":43}],18:[function(require,module,exports){ -(function (Buffer){ -'use strict'; - -exports.__esModule = true; - -var _ecurve = require(59); - -var _assert = require(27); - -var _assert2 = _interopRequireDefault(_assert); - -var _bigi = require(32); - -var _bigi2 = _interopRequireDefault(_bigi); - -var _hash2 = require(17); - -var _ecdsa = require(14); - -var _PublicKey = require(11); - -var _PublicKey2 = _interopRequireDefault(_PublicKey); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* global ByteBuffer */ - - -var secp256k1 = (0, _ecurve.getCurveByName)('secp256k1'); - -var Signature = function () { - function Signature(r1, s1, i1) { - _classCallCheck(this, Signature); - - this.r = r1; - this.s = s1; - this.i = i1; - _assert2.default.equal(this.r != null, true, 'Missing parameter'); - _assert2.default.equal(this.s != null, true, 'Missing parameter'); - _assert2.default.equal(this.i != null, true, 'Missing parameter'); - } - - Signature.fromBuffer = function fromBuffer(buf) { - var i = void 0; - var r = void 0; - var s = void 0; - _assert2.default.equal(buf.length, 65, 'Invalid signature length'); - i = buf.readUInt8(0); - _assert2.default.equal(i - 27, i - 27 & 7, 'Invalid signature parameter'); // eslint-disable-line - r = _bigi2.default.fromBuffer(buf.slice(1, 33)); - s = _bigi2.default.fromBuffer(buf.slice(33)); - return new Signature(r, s, i); - }; - - Signature.prototype.toBuffer = function toBuffer() { - var buf = void 0; - buf = Buffer.alloc(65); - buf.writeUInt8(this.i, 0); - this.r.toBuffer(32).copy(buf, 1); - this.s.toBuffer(32).copy(buf, 33); - return buf; - }; - - Signature.prototype.recoverPublicKeyFromBuffer = function recoverPublicKeyFromBuffer(buffer) { - return this.recoverPublicKey((0, _hash2.sha256)(buffer)); - }; - - /** - @return {PublicKey} - */ - - - Signature.prototype.recoverPublicKey = function recoverPublicKey(sha256_buffer) { - var Q = void 0; - var e = void 0; - var i = void 0; - e = _bigi2.default.fromBuffer(sha256_buffer); - i = this.i; - i -= 27; - i &= 3; // eslint-disable-line - Q = (0, _ecdsa.recoverPubKey)(secp256k1, e, this, i); - return _PublicKey2.default.fromPoint(Q); - }; - - /** - @param {Buffer} buf - @param {PrivateKey} private_key - @return {Signature} - */ - - - Signature.signBuffer = function signBuffer(buf, private_key) { - var _hash = (0, _hash2.sha256)(buf); - return Signature.signBufferSha256(_hash, private_key); - }; - - /** Sign a buffer of exactally 32 bytes in size (sha256(text)) - @param {Buffer} buf - 32 bytes binary - @param {PrivateKey} private_key - @return {Signature} - */ - - - Signature.signBufferSha256 = function signBufferSha256(buf_sha256, private_key) { - if (buf_sha256.length !== 32 || !Buffer.isBuffer(buf_sha256)) { - throw new Error('buf_sha256: 32 byte buffer requred'); - } - - var der = void 0; - var e = void 0; - var ecsignature = void 0; - var i = void 0; - var lenR = void 0; - var lenS = void 0; - var nonce = void 0; - i = null; - nonce = 0; - e = _bigi2.default.fromBuffer(buf_sha256); - - var loop = true; - - while (loop) { - ecsignature = (0, _ecdsa.sign)(secp256k1, buf_sha256, private_key.d, nonce++); - der = ecsignature.toDER(); - lenR = der[3]; - lenS = der[5 + lenR]; - - if (lenR === 32 && lenS === 32) { - i = (0, _ecdsa.calcPubKeyRecoveryParam)(secp256k1, e, ecsignature, private_key.toPublicKey().Q); - i += 4; // compressed - i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) - loop = false; - break; - } - - if (nonce % 10 === 0) { - console.log('WARN: ' + nonce + ' attempts to find canonical signature'); - } - } - - return new Signature(ecsignature.r, ecsignature.s, i); - }; - - Signature.sign = function sign(string, private_key) { - return Signature.signBuffer(Buffer.from(string), private_key); - }; - - /** - @param {Buffer} un-hashed - @param {./PublicKey} - @return {boolean} - */ - - - Signature.prototype.verifyBuffer = function verifyBuffer(buf, public_key) { - var _hash = (0, _hash2.sha256)(buf); - return this.verifyHash(_hash, public_key); - }; - - Signature.prototype.verifyHash = function verifyHash(hash, public_key) { - _assert2.default.equal(hash.length, 32, 'A SHA 256 should be 32 bytes long, instead got ' + hash.length); - return (0, _ecdsa.verify)(secp256k1, hash, { - r: this.r, - s: this.s - }, public_key.Q); - }; - - /* */ - - Signature.prototype.toByteBuffer = function toByteBuffer() { - var b = void 0; - b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); - this.appendByteBuffer(b); - return b.copy(0, b.offset); - }; - - Signature.fromHex = function fromHex(hex) { - return Signature.fromBuffer(Buffer.from(hex, 'hex')); - }; - - Signature.prototype.toHex = function toHex() { - return this.toBuffer().toString('hex'); - }; - - Signature.signHex = function signHex(hex, private_key) { - var buf = void 0; - buf = Buffer.from(hex, 'hex'); - return Signature.signBuffer(buf, private_key); - }; - - Signature.prototype.verifyHex = function verifyHex(hex, public_key) { - var buf = void 0; - buf = Buffer.from(hex, 'hex'); - return this.verifyBuffer(buf, public_key); - }; - - return Signature; -}(); - -exports.default = Signature; -module.exports = exports['default']; -}).call(this,require(35).Buffer) - -},{"11":11,"14":14,"17":17,"27":27,"32":32,"35":35,"59":59}],19:[function(require,module,exports){ -'use strict'; - -exports.__esModule = true; -exports.SerializerValidation = exports.template = exports.ops = exports.types = exports.fp = exports.Serializer = undefined; - -var _serializer = require(24); - -var _serializer2 = _interopRequireDefault(_serializer); - -var _FastParser = require(20); - -var _FastParser2 = _interopRequireDefault(_FastParser); - -var _types = require(26); - -var _types2 = _interopRequireDefault(_types); - -var _operations = require(23); - -var ops = _interopRequireWildcard(_operations); - -var _template = require(25); - -var _template2 = _interopRequireDefault(_template); - -var _SerializerValidation = require(21); - -var _SerializerValidation2 = _interopRequireDefault(_SerializerValidation); - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.Serializer = _serializer2.default; -exports.fp = _FastParser2.default; -exports.types = _types2.default; -exports.ops = ops; -exports.template = _template2.default; -exports.SerializerValidation = _SerializerValidation2.default; -},{"20":20,"21":21,"23":23,"24":24,"25":25,"26":26}],20:[function(require,module,exports){ -(function (Buffer){ -'use strict'; - -exports.__esModule = true; - -var _PublicKey = require(11); - -var _PublicKey2 = _interopRequireDefault(_PublicKey); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var FastParser = function () { - function FastParser() { - _classCallCheck(this, FastParser); - } - - FastParser.fixed_data = function fixed_data(b, len, buffer) { - if (!b) { - return; - } - if (buffer) { - var data = buffer.slice(0, len).toString('binary'); - b.append(data, 'binary'); - while (len-- > data.length) { - b.writeUint8(0); - } - } else { - var b_copy = b.copy(b.offset, b.offset + len); - b.skip(len); - return Buffer.from(b_copy.toBinary(), 'binary'); - } - }; - - FastParser.public_key = function public_key(b, _public_key) { - var buffer = void 0; - if (!b) { - return; - } - if (_public_key) { - buffer = _public_key.toBuffer(); - b.append(buffer.toString('binary'), 'binary'); - } else { - buffer = FastParser.fixed_data(b, 33); - return _PublicKey2.default.fromBuffer(buffer); - } - }; - - FastParser.ripemd160 = function ripemd160(b, _ripemd) { - if (!b) { - return; - } - if (_ripemd) { - FastParser.fixed_data(b, 20, _ripemd); - } else { - return FastParser.fixed_data(b, 20); - } - }; - - FastParser.sha256 = function sha256(b, _sha) { - if (!b) { - return; - } - if (_sha) { - FastParser.fixed_data(b, 32, _sha); - } else { - return FastParser.fixed_data(b, 32); - } - }; - - FastParser.time_point_sec = function time_point_sec(b, epoch) { - if (epoch) { - epoch = Math.ceil(epoch / 1000); - b.writeInt32(epoch); - } else { - epoch = b.readInt32(); // fc::time_point_sec - return new Date(epoch * 1000); - } - }; - - return FastParser; -}(); - -exports.default = FastParser; -module.exports = exports['default']; -}).call(this,require(35).Buffer) - -},{"11":11,"35":35}],21:[function(require,module,exports){ -'use strict'; - -exports.__esModule = true; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _bytebuffer = require(38); - -var _ChainTypes = require(3); - -var _ChainTypes2 = _interopRequireDefault(_ChainTypes); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var MAX_SAFE_INT = 9007199254740991; -var MIN_SAFE_INT = -9007199254740991; - -/** - Most validations are skipped and the value returned unchanged when an empty string, - null, or undefined is encountered (except "required"). - Validations support a string format for dealing with large numbers. -*/ -var _my = { - is_empty: function is_empty(value) { - return value === null || value === undefined; - }, - required: function required(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (this.is_empty(value)) { - throw new Error('value required ' + field_name + ' | ' + value); - } - - return value; - }, - require_long: function require_long(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (!_bytebuffer.Long.isLong(value)) { - throw new Error('Long value required ' + field_name + ' | ' + value); - } - - return value; - }, - string: function string(value) { - if (this.is_empty(value)) { - return value; - } - - if (typeof value !== 'string') { - throw new Error('string required: ' + value); - } - - return value; - }, - number: function number(value) { - if (this.is_empty(value)) { - return value; - } - - if (typeof value !== 'number') { - throw new Error('number required: ' + value); - } - - return value; - }, - whole_number: function whole_number(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (this.is_empty(value)) { - return value; - } - - if (/\./.test(value)) { - throw new Error('whole number required ' + field_name + ' ' + value); - } - - return value; - }, - unsigned: function unsigned(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (this.is_empty(value)) { - return value; - } - - if (/-/.test(value)) { - throw new Error('unsigned required ' + field_name + ' ' + value); - } - - return value; - }, - is_digits: function is_digits(value) { - if (typeof value === 'number') { - return true; - } - - return (/^[0-9]+$/.test(value) - ); - }, - to_number: function to_number(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (this.is_empty(value)) { - return value; - } - - this.no_overflow53(value, field_name); - var int_value = function () { - if (typeof value === 'number') { - return value; - } - - return parseInt(value, 10); - }(); - return int_value; - }, - to_long: function to_long(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (this.is_empty(value)) { - return value; - } - - if (_bytebuffer.Long.isLong(value)) { - return value; - } - - this.no_overflow64(value, field_name); - - if (typeof value === 'number') { - value = '' + value; - } - - return _bytebuffer.Long.fromString(value); - }, - to_ulong: function to_ulong(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (this.is_empty(value)) { - return value; - } - - if (_bytebuffer.Long.isLong(value)) { - return value; - } - - this.no_overflow64(value, field_name, true); - - if (typeof value === 'number') { - value = '' + value; - } - - return _bytebuffer.Long.fromString(value, true); - }, - to_string: function to_string(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (this.is_empty(value)) { - return value; - } - - if (typeof value === 'string') { - return value; - } - - if (typeof value === 'number') { - this.no_overflow53(value, field_name); - return '' + value; - } - - if (_bytebuffer.Long.isLong(value)) { - return value.toString(); - } - - throw new Error('unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value); - }, - require_test: function require_test(regex, value) { - var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; - - if (this.is_empty(value)) { - return value; - } - - if (!regex.test(value)) { - throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value); - } - - return value; - }, - require_match: function require_match(regex, value) { - var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; - - if (this.is_empty(value)) { - return value; - } - - var match = value.match(regex); - - if (match === null) { - throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value); - } - - return match; - }, - require_object_id: function require_object_id(value, field_name) { - return this.require_match(/^([0-9]+)\.([0-9]+)\.([0-9]+)$/, value, field_name); - }, - - - // Does not support over 53 bits - require_range: function require_range(min, max, value) { - var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; - - if (this.is_empty(value)) { - return value; - } - - var num = this.to_number(value); - - if (num < min || num > max) { - throw new Error('out of range ' + value + ' ' + field_name + ' ' + value); - } - - return value; - }, - require_object_type: function require_object_type() { - var reserved_spaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - var type = arguments[1]; - var value = arguments[2]; - var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ''; - - if (this.is_empty(value)) { - return value; - } - - var object_type = _ChainTypes2.default.object_type[type]; - - if (!object_type) { - throw new Error('Unknown object type ' + type + ' ' + field_name + ' ' + value); - } - - var re = new RegExp(reserved_spaces + '.' + object_type + '.[0-9]+$'); - - if (!re.test(value)) { - throw new Error('Expecting ' + type + ' in format ' + (reserved_spaces + '.' + object_type + '.[0-9]+ ') + ('instead of ' + value + ' ' + field_name + ' ' + value)); - } - - return value; - }, - get_instance: function get_instance(reserve_spaces, type, value, field_name) { - if (this.is_empty(value)) { - return value; - } - - this.require_object_type(reserve_spaces, type, value, field_name); - return this.to_number(value.split('.')[2]); - }, - require_relative_type: function require_relative_type(type, value, field_name) { - this.require_object_type(0, type, value, field_name); - return value; - }, - get_relative_instance: function get_relative_instance(type, value, field_name) { - if (this.is_empty(value)) { - return value; - } - - this.require_object_type(0, type, value, field_name); - return this.to_number(value.split('.')[2]); - }, - require_protocol_type: function require_protocol_type(type, value, field_name) { - this.require_object_type(1, type, value, field_name); - return value; - }, - get_protocol_instance: function get_protocol_instance(type, value, field_name) { - if (this.is_empty(value)) { - return value; - } - - this.require_object_type(1, type, value, field_name); - return this.to_number(value.split('.')[2]); - }, - get_protocol_type: function get_protocol_type(value, field_name) { - if (this.is_empty(value)) { - return value; - } - - this.require_object_id(value, field_name); - var values = value.split('.'); - return this.to_number(values[1]); - }, - get_protocol_type_name: function get_protocol_type_name(value, field_name) { - if (this.is_empty(value)) { - return value; - } - - var type_id = this.get_protocol_type(value, field_name); - return Object.keys(_ChainTypes2.default.object_type)[type_id]; - }, - require_implementation_type: function require_implementation_type(type, value, field_name) { - this.require_object_type(2, type, value, field_name); - return value; - }, - get_implementation_instance: function get_implementation_instance(type, value, field_name) { - if (this.is_empty(value)) { - return value; - } - - this.require_object_type(2, type, value, field_name); - return this.to_number(value.split('.')[2]); - }, - - - // signed / unsigned decimal - no_overflow53: function no_overflow53(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (typeof value === 'number') { - if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { - throw new Error('overflow ' + field_name + ' ' + value); - } - - return; - } - - if (typeof value === 'string') { - var int = parseInt(value, 10); - - if (int > MAX_SAFE_INT || int < MIN_SAFE_INT) { - throw new Error('overflow ' + field_name + ' ' + int); - } - - return; - } - - if (_bytebuffer.Long.isLong(value)) { - // typeof value.toInt() is 'number' - this.no_overflow53(value.toInt(), field_name); - return; - } - - throw new Error('unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value); - }, - - - // signed / unsigned whole numbers only - no_overflow64: function no_overflow64(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - var unsigned = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - // https://github.com/dcodeIO/Long.js/issues/20 - if (_bytebuffer.Long.isLong(value)) { - return; - } - - // BigInteger#isBigInteger https://github.com/cryptocoinjs/bigi/issues/20 - if (value.t !== undefined && value.s !== undefined) { - this.no_overflow64(value.toString(), field_name, unsigned); - - return; - } - - if (typeof value === 'string') { - // remove leading zeros, will cause a false positive - value = value.replace(/^0+/, ''); - - // remove trailing zeros - while (/0$/.test(value)) { - value = value.substring(0, value.length - 1); - } - - if (/\.$/.test(value)) { - // remove trailing dot - value = value.substring(0, value.length - 1); - } - - if (value === '') { - value = '0'; - } - - var long_string = _bytebuffer.Long.fromString(value, unsigned).toString(); - - if (long_string !== value.trim()) { - throw new Error('overflow ' + field_name + ' ' + value); - } - - return; - } - - if (typeof value === 'number') { - if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { - throw new Error('overflow ' + field_name + ' ' + value); - } - - return; - } - - throw new Error('unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value); - } -}; - -exports.default = _my; -module.exports = exports['default']; -},{"3":3,"38":38}],22:[function(require,module,exports){ -'use strict'; - -exports.__esModule = true; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** Exception nesting. */ -var ErrorWithCause = function () { - function ErrorWithCause(message, cause) { - _classCallCheck(this, ErrorWithCause); - - this.message = message; - - if (typeof cause !== 'undefined' && cause !== null ? cause.message : undefined) { - this.message = 'cause\t' + cause.message + '\t' + this.message; - } - - var stack = ''; // (new Error).stack - - if (typeof cause !== 'undefined' && cause !== null ? cause.stack : undefined) { - stack = 'caused by\n\t' + cause.stack + '\t' + stack; - } - - this.stack = this.message + '\n' + stack; - } - - ErrorWithCause.throw = function _throw(message, cause) { - var msg = message; - - if (typeof cause !== 'undefined' && cause !== null ? cause.message : undefined) { - msg += '\t cause: ' + cause.message + ' '; - } - - if (typeof cause !== 'undefined' && cause !== null ? cause.stack : undefined) { - msg += '\n stack: ' + cause.stack + ' '; - } - - throw new Error(msg); - }; - - return ErrorWithCause; -}(); - -exports.default = ErrorWithCause; -module.exports = exports['default']; -},{}],23:[function(require,module,exports){ -'use strict'; - -exports.__esModule = true; -exports.stealth_memo_data = exports.global_betting_statistics = exports.betting_market_position = exports.bet = exports.betting_market = exports.betting_market_group = exports.betting_market_rules = exports.event = exports.event_group = exports.sport = exports.signed_transaction = exports.transaction = exports.bet_adjusted = exports.betting_market_update = exports.betting_market_group_update = exports.tournament_leave = exports.tournament_payout = exports.payout_type = exports.bet_canceled = exports.bet_cancel = exports.bet_matched = exports.betting_market_group_cancel_unmatched_bets = exports.betting_market_group_resolved = exports.betting_market_group_resolve = exports.betting_market_resolution_type = exports.bet_place = exports.bet_type = exports.betting_market_create = exports.betting_market_group_create = exports.betting_market_rules_update = exports.betting_market_rules_create = exports.event_update = exports.event_create = exports.event_group_update = exports.event_group_create = exports.sport_update = exports.sport_create = exports.asset_dividend_distribution = exports.asset_update_dividend = exports.dividend_asset_options = exports.game_move = exports.rock_paper_scissors_throw_reveal = exports.rock_paper_scissors_throw_commit = exports.rock_paper_scissors_gesture = exports.tournament_join = exports.tournament_create = exports.tournament_options = exports.rock_paper_scissors_game_options = exports.fba_distribute = exports.asset_claim_fees = exports.asset_settle_cancel = exports.transfer_from_blind = exports.blind_transfer = exports.blind_input = exports.transfer_to_blind = exports.blind_output = exports.stealth_confirmation = exports.override_transfer = exports.balance_claim = exports.assert = exports.block_id_predicate = exports.asset_symbol_eq_lit_predicate = exports.account_name_eq_lit_predicate = exports.custom = exports.worker_create = exports.burn_worker_initializer = exports.vesting_balance_worker_initializer = exports.refund_worker_initializer = exports.vesting_balance_withdraw = exports.vesting_balance_create = exports.cdd_vesting_policy_initializer = exports.linear_vesting_policy_initializer = exports.committee_member_update_global_parameters = exports.chain_parameters = exports.committee_member_update = exports.committee_member_create = exports.withdraw_permission_delete = exports.withdraw_permission_claim = exports.withdraw_permission_update = exports.withdraw_permission_create = exports.proposal_delete = exports.proposal_update = exports.proposal_create = exports.op_wrapper = exports.witness_update = exports.witness_create = exports.asset_publish_feed = exports.price_feed = exports.asset_global_settle = exports.asset_settle = exports.asset_fund_fee_pool = exports.asset_reserve = exports.asset_issue = undefined; -exports.asset_update_feed_producers = exports.asset_update_bitasset = exports.asset_update = exports.asset_create = exports.bitasset_options = exports.asset_options = exports.price = exports.account_transfer = exports.account_upgrade = exports.account_whitelist = exports.account_update = exports.account_create = exports.account_options = exports.authority = exports.fill_order = exports.call_order_update = exports.limit_order_cancel = exports.limit_order_create = exports.transfer = exports.memo_data = exports.signed_block_header = exports.block_header = exports.signed_block = exports.processed_transaction = exports.asset = exports.void_result = exports.fee_schedule = exports.bet_adjusted_operation_fee_parameters = exports.betting_market_update_operation_fee_parameters = exports.betting_market_group_update_operation_fee_parameters = exports.tournament_leave_operation_fee_parameters = exports.tournament_payout_operation_fee_parameters = exports.game_move_operation_fee_parameters = exports.tournament_join_operation_fee_parameters = exports.tournament_create_operation_fee_parameters = exports.bet_canceled_operation_fee_parameters = exports.bet_cancel_operation_fee_parameters = exports.bet_matched_operation_fee_parameters = exports.betting_market_group_cancel_unmatched_bets_operation_fee_parameters = exports.betting_market_group_resolved_operation_fee_parameters = exports.betting_market_group_resolve_operation_fee_parameters = exports.bet_place_operation_fee_parameters = exports.betting_market_create_operation_fee_parameters = exports.betting_market_group_create_operation_fee_parameters = exports.betting_market_rules_update_operation_fee_parameters = exports.betting_market_rules_create_operation_fee_parameters = exports.event_update_operation_fee_parameters = exports.event_create_operation_fee_parameters = exports.event_group_update_operation_fee_parameters = exports.event_group_create_operation_fee_parameters = exports.sport_update_operation_fee_parameters = exports.sport_create_operation_fee_parameters = exports.asset_dividend_distribution_operation_fee_parameters = exports.asset_update_dividend_operation_fee_parameters = exports.fba_distribute_operation_fee_parameters = exports.asset_claim_fees_operation_fee_parameters = exports.asset_settle_cancel_operation_fee_parameters = exports.transfer_from_blind_operation_fee_parameters = exports.blind_transfer_operation_fee_parameters = exports.transfer_to_blind_operation_fee_parameters = exports.override_transfer_operation_fee_parameters = exports.balance_claim_operation_fee_parameters = exports.assert_operation_fee_parameters = exports.custom_operation_fee_parameters = exports.worker_create_operation_fee_parameters = exports.vesting_balance_withdraw_operation_fee_parameters = exports.vesting_balance_create_operation_fee_parameters = exports.committee_member_update_global_parameters_operation_fee_parameters = exports.committee_member_update_operation_fee_parameters = exports.committee_member_create_operation_fee_parameters = exports.withdraw_permission_delete_operation_fee_parameters = exports.withdraw_permission_claim_operation_fee_parameters = exports.withdraw_permission_update_operation_fee_parameters = exports.withdraw_permission_create_operation_fee_parameters = exports.proposal_delete_operation_fee_parameters = exports.proposal_update_operation_fee_parameters = exports.proposal_create_operation_fee_parameters = exports.witness_update_operation_fee_parameters = exports.witness_create_operation_fee_parameters = exports.asset_publish_feed_operation_fee_parameters = exports.asset_global_settle_operation_fee_parameters = exports.asset_settle_operation_fee_parameters = exports.asset_fund_fee_pool_operation_fee_parameters = exports.asset_reserve_operation_fee_parameters = exports.asset_issue_operation_fee_parameters = exports.asset_update_feed_producers_operation_fee_parameters = exports.asset_update_bitasset_operation_fee_parameters = exports.asset_update_operation_fee_parameters = exports.asset_create_operation_fee_parameters = exports.account_transfer_operation_fee_parameters = exports.account_upgrade_operation_fee_parameters = exports.account_whitelist_operation_fee_parameters = exports.account_update_operation_fee_parameters = exports.account_create_operation_fee_parameters = exports.fill_order_operation_fee_parameters = exports.call_order_update_operation_fee_parameters = exports.limit_order_cancel_operation_fee_parameters = exports.limit_order_create_operation_fee_parameters = exports.transfer_operation_fee_parameters = exports.operation = undefined; - -var _types = require(26); - -var _types2 = _interopRequireDefault(_types); - -var _serializer = require(24); - -var _serializer2 = _interopRequireDefault(_serializer); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var uint8 = _types2.default.uint8, - uint16 = _types2.default.uint16, - uint32 = _types2.default.uint32, - int64 = _types2.default.int64, - uint64 = _types2.default.uint64, - string = _types2.default.string, - bytes = _types2.default.bytes, - bool = _types2.default.bool, - array = _types2.default.array, - protocol_id_type = _types2.default.protocol_id_type, - object_id_type = _types2.default.object_id_type, - vote_id = _types2.default.vote_id, - implementation_id_type = _types2.default.implementation_id_type, - static_variant = _types2.default.static_variant, - map = _types2.default.map, - set = _types2.default.set, - public_key = _types2.default.public_key, - address = _types2.default.address, - time_point_sec = _types2.default.time_point_sec, - optional = _types2.default.optional, - variant_object = _types2.default.variant_object, - enumeration = _types2.default.enumeration, - sha256 = _types2.default.sha256; - - -var future_extensions = _types2.default.void; - -/* -When updating generated code -Replace: operation = static_variant [ -with: operation.st_operations = [ - -Delete: -public_key = new Serializer( - "public_key" - key_data: bytes 33 -); -*/ - -function Serializer(operation_name, serilization_types_object) { - return new _serializer2.default(operation_name, serilization_types_object); -} -// Place-holder, their are dependencies on "operation" .. The final list of -// operations is not avialble until the very end of the generated code. -// See: operation.st_operations = ... -// module.exports["operation"] = operation; - -var operation = static_variant(); - -// Custom-types follow Generated code: - -// ## Generated code follows -// # programs/js_operation_serializer > npm i -g decaffeinate -// ## ------------------------------- -var transfer_operation_fee_parameters = new Serializer('transfer_operation_fee_parameters', { - fee: uint64, - price_per_kbyte: uint32 -}); - -var limit_order_create_operation_fee_parameters = new Serializer('limit_order_create_operation_fee_parameters', { - fee: uint64 -}); - -var limit_order_cancel_operation_fee_parameters = new Serializer('limit_order_cancel_operation_fee_parameters', { - fee: uint64 -}); - -var call_order_update_operation_fee_parameters = new Serializer('call_order_update_operation_fee_parameters', { - fee: uint64 -}); - -var fill_order_operation_fee_parameters = new Serializer('fill_order_operation_fee_parameters'); - -var account_create_operation_fee_parameters = new Serializer('account_create_operation_fee_parameters', { - basic_fee: uint64, - premium_fee: uint64, - price_per_kbyte: uint32 -}); - -var account_update_operation_fee_parameters = new Serializer('account_update_operation_fee_parameters', { - fee: int64, - price_per_kbyte: uint32 -}); - -var account_whitelist_operation_fee_parameters = new Serializer('account_whitelist_operation_fee_parameters', { - fee: int64 -}); - -var account_upgrade_operation_fee_parameters = new Serializer('account_upgrade_operation_fee_parameters', { - membership_annual_fee: uint64, - membership_lifetime_fee: uint64 -}); - -var account_transfer_operation_fee_parameters = new Serializer('account_transfer_operation_fee_parameters', { - fee: uint64 -}); - -var asset_create_operation_fee_parameters = new Serializer('asset_create_operation_fee_parameters', { - symbol3: uint64, - symbol4: uint64, - long_symbol: uint64, - price_per_kbyte: uint32 -}); - -var asset_update_operation_fee_parameters = new Serializer('asset_update_operation_fee_parameters', { - fee: uint64, - price_per_kbyte: uint32 -}); - -var asset_update_bitasset_operation_fee_parameters = new Serializer('asset_update_bitasset_operation_fee_parameters', { - fee: uint64 -}); - -var asset_update_feed_producers_operation_fee_parameters = new Serializer('asset_update_feed_producers_operation_fee_parameters', { - fee: uint64 -}); - -var asset_issue_operation_fee_parameters = new Serializer('asset_issue_operation_fee_parameters', { - fee: uint64, - price_per_kbyte: uint32 -}); - -var asset_reserve_operation_fee_parameters = new Serializer('asset_reserve_operation_fee_parameters', { - fee: uint64 -}); - -var asset_fund_fee_pool_operation_fee_parameters = new Serializer('asset_fund_fee_pool_operation_fee_parameters', { - fee: uint64 -}); - -var asset_settle_operation_fee_parameters = new Serializer('asset_settle_operation_fee_parameters', { - fee: uint64 -}); - -var asset_global_settle_operation_fee_parameters = new Serializer('asset_global_settle_operation_fee_parameters', { - fee: uint64 -}); - -var asset_publish_feed_operation_fee_parameters = new Serializer('asset_publish_feed_operation_fee_parameters', { - fee: uint64 -}); - -var witness_create_operation_fee_parameters = new Serializer('witness_create_operation_fee_parameters', { - fee: uint64 -}); - -var witness_update_operation_fee_parameters = new Serializer('witness_update_operation_fee_parameters', { - fee: int64 -}); - -var proposal_create_operation_fee_parameters = new Serializer('proposal_create_operation_fee_parameters', { - fee: uint64, - price_per_kbyte: uint32 -}); - -var proposal_update_operation_fee_parameters = new Serializer('proposal_update_operation_fee_parameters', { - fee: uint64, - price_per_kbyte: uint32 -}); - -var proposal_delete_operation_fee_parameters = new Serializer('proposal_delete_operation_fee_parameters', { - fee: uint64 -}); - -var withdraw_permission_create_operation_fee_parameters = new Serializer('withdraw_permission_create_operation_fee_parameters', { - fee: uint64 -}); - -var withdraw_permission_update_operation_fee_parameters = new Serializer('withdraw_permission_update_operation_fee_parameters', { - fee: uint64 -}); - -var withdraw_permission_claim_operation_fee_parameters = new Serializer('withdraw_permission_claim_operation_fee_parameters', { - fee: uint64, - price_per_kbyte: uint32 -}); - -var withdraw_permission_delete_operation_fee_parameters = new Serializer('withdraw_permission_delete_operation_fee_parameters', { - fee: uint64 -}); - -var committee_member_create_operation_fee_parameters = new Serializer('committee_member_create_operation_fee_parameters', { - fee: uint64 -}); - -var committee_member_update_operation_fee_parameters = new Serializer('committee_member_update_operation_fee_parameters', { - fee: uint64 -}); - -var committee_member_update_global_parameters_operation_fee_parameters = new Serializer('committee_member_update_global_parameters_operation_fee_parameters', { - fee: uint64 -}); - -var vesting_balance_create_operation_fee_parameters = new Serializer('vesting_balance_create_operation_fee_parameters', { - fee: uint64 -}); - -var vesting_balance_withdraw_operation_fee_parameters = new Serializer('vesting_balance_withdraw_operation_fee_parameters', { - fee: uint64 -}); - -var worker_create_operation_fee_parameters = new Serializer('worker_create_operation_fee_parameters', { - fee: uint64 -}); - -var custom_operation_fee_parameters = new Serializer('custom_operation_fee_parameters', { - fee: uint64, - price_per_kbyte: uint32 -}); - -var assert_operation_fee_parameters = new Serializer('assert_operation_fee_parameters', { - fee: uint64 -}); - -var balance_claim_operation_fee_parameters = new Serializer('balance_claim_operation_fee_parameters'); - -var override_transfer_operation_fee_parameters = new Serializer('override_transfer_operation_fee_parameters', { - fee: uint64, - price_per_kbyte: uint32 -}); - -var transfer_to_blind_operation_fee_parameters = new Serializer('transfer_to_blind_operation_fee_parameters', { - fee: uint64, - price_per_output: uint32 -}); - -var blind_transfer_operation_fee_parameters = new Serializer('blind_transfer_operation_fee_parameters', { - fee: uint64, - price_per_output: uint32 -}); - -var transfer_from_blind_operation_fee_parameters = new Serializer('transfer_from_blind_operation_fee_parameters', { - fee: uint64 -}); - -var asset_settle_cancel_operation_fee_parameters = new Serializer('asset_settle_cancel_operation_fee_parameters'); - -var asset_claim_fees_operation_fee_parameters = new Serializer('asset_claim_fees_operation_fee_parameters', { - fee: uint64 -}); - -var fba_distribute_operation_fee_parameters = new Serializer('fba_distribute_operation_fee_parameters', {}); - -var asset_update_dividend_operation_fee_parameters = new Serializer('asset_update_dividend_operation_fee_parameters', { - fee: uint64 -}); - -var asset_dividend_distribution_operation_fee_parameters = new Serializer('asset_dividend_distribution_operation_fee_parameters', { - distribution_base_fee: uint64, - distribution_fee_per_holder: uint32 -}); - -var sport_create_operation_fee_parameters = new Serializer('sport_create_operation_fee_parameters', { - fee: uint64 -}); - -var sport_update_operation_fee_parameters = new Serializer('sport_update_operation_fee_parameters', { - fee: uint64 -}); - -var event_group_create_operation_fee_parameters = new Serializer('event_group_create_operation_fee_parameters', { - fee: uint64 -}); - -var event_group_update_operation_fee_parameters = new Serializer('event_group_update_operation_fee_parameters', { - fee: uint64 -}); - -var event_create_operation_fee_parameters = new Serializer('event_create_operation_fee_parameters', { - fee: uint64 -}); - -var event_update_operation_fee_parameters = new Serializer('event_update_operation_fee_parameters', { - fee: uint64 -}); - -var betting_market_rules_create_operation_fee_parameters = new Serializer('betting_market_rules_create_operation_fee_parameters', { - fee: uint64 -}); - -var betting_market_rules_update_operation_fee_parameters = new Serializer('betting_market_rules_update_operation_fee_parameters', { - fee: uint64 -}); - -var betting_market_group_create_operation_fee_parameters = new Serializer('betting_market_group_create_operation_fee_parameters', { - fee: uint64 -}); - -var betting_market_create_operation_fee_parameters = new Serializer('betting_market_create_operation_fee_parameters', { - fee: uint64 -}); - -var bet_place_operation_fee_parameters = new Serializer('bet_place_operation_fee_parameters', { - fee: uint64 -}); - -var betting_market_group_resolve_operation_fee_parameters = new Serializer('betting_market_group_resolve_operation_fee_parameters', { - fee: uint64 -}); - -var betting_market_group_resolved_operation_fee_parameters = new Serializer('betting_market_group_resolved_operation_fee_parameters'); - -var betting_market_group_cancel_unmatched_bets_operation_fee_parameters = new Serializer('betting_market_group_cancel_unmatched_bets_operation_fee_parameters', { - fee: uint64 -}); - -var bet_matched_operation_fee_parameters = new Serializer('bet_matched_operation_fee_parameters'); - -var bet_cancel_operation_fee_parameters = new Serializer('bet_cancel_operation_fee_parameters', { - fee: uint64 -}); - -var bet_canceled_operation_fee_parameters = new Serializer('bet_canceled_operation_fee_parameters'); - -var tournament_create_operation_fee_parameters = new Serializer('tournament_create_operation_fee_parameters', { - fee: int64 -}); - -var tournament_join_operation_fee_parameters = new Serializer('tournament_join_operation_fee_parameters', { - fee: int64 -}); - -var game_move_operation_fee_parameters = new Serializer('game_move_operation_fee_parameters', { - fee: int64 -}); - -var tournament_payout_operation_fee_parameters = new Serializer('tournament_payout_operation_fee_parameters'); - -var tournament_leave_operation_fee_parameters = new Serializer('tournament_leave_operation_fee_parameters', { - fee: int64 -}); - -var betting_market_group_update_operation_fee_parameters = new Serializer('betting_market_group_update_operation_fee_parameters', { - fee: uint64 -}); - -var betting_market_update_operation_fee_parameters = new Serializer('betting_market_update_operation_fee_parameters', { - fee: uint64 -}); - -var bet_adjusted_operation_fee_parameters = new Serializer('bet_adjusted_operation_fee_parameters'); - -var fee_parameters = static_variant([transfer_operation_fee_parameters, limit_order_create_operation_fee_parameters, limit_order_cancel_operation_fee_parameters, call_order_update_operation_fee_parameters, fill_order_operation_fee_parameters, account_create_operation_fee_parameters, account_update_operation_fee_parameters, account_whitelist_operation_fee_parameters, account_upgrade_operation_fee_parameters, account_transfer_operation_fee_parameters, asset_create_operation_fee_parameters, asset_update_operation_fee_parameters, asset_update_bitasset_operation_fee_parameters, asset_update_feed_producers_operation_fee_parameters, asset_issue_operation_fee_parameters, asset_reserve_operation_fee_parameters, asset_fund_fee_pool_operation_fee_parameters, asset_settle_operation_fee_parameters, asset_global_settle_operation_fee_parameters, asset_publish_feed_operation_fee_parameters, witness_create_operation_fee_parameters, witness_update_operation_fee_parameters, proposal_create_operation_fee_parameters, proposal_update_operation_fee_parameters, proposal_delete_operation_fee_parameters, withdraw_permission_create_operation_fee_parameters, withdraw_permission_update_operation_fee_parameters, withdraw_permission_claim_operation_fee_parameters, withdraw_permission_delete_operation_fee_parameters, committee_member_create_operation_fee_parameters, committee_member_update_operation_fee_parameters, committee_member_update_global_parameters_operation_fee_parameters, vesting_balance_create_operation_fee_parameters, vesting_balance_withdraw_operation_fee_parameters, worker_create_operation_fee_parameters, custom_operation_fee_parameters, assert_operation_fee_parameters, balance_claim_operation_fee_parameters, override_transfer_operation_fee_parameters, transfer_to_blind_operation_fee_parameters, blind_transfer_operation_fee_parameters, transfer_from_blind_operation_fee_parameters, asset_settle_cancel_operation_fee_parameters, asset_claim_fees_operation_fee_parameters, fba_distribute_operation_fee_parameters, tournament_create_operation_fee_parameters, tournament_join_operation_fee_parameters, game_move_operation_fee_parameters, asset_update_dividend_operation_fee_parameters, asset_dividend_distribution_operation_fee_parameters, tournament_payout_operation_fee_parameters, tournament_leave_operation_fee_parameters, sport_create_operation_fee_parameters, sport_update_operation_fee_parameters, event_group_create_operation_fee_parameters, event_group_update_operation_fee_parameters, event_create_operation_fee_parameters, event_update_operation_fee_parameters, betting_market_rules_create_operation_fee_parameters, betting_market_rules_update_operation_fee_parameters, betting_market_group_create_operation_fee_parameters, betting_market_create_operation_fee_parameters, bet_place_operation_fee_parameters, betting_market_group_resolve_operation_fee_parameters, betting_market_group_resolved_operation_fee_parameters, bet_adjusted_operation_fee_parameters, betting_market_group_cancel_unmatched_bets_operation_fee_parameters, bet_matched_operation_fee_parameters, bet_cancel_operation_fee_parameters, bet_canceled_operation_fee_parameters, betting_market_group_update_operation_fee_parameters, betting_market_update_operation_fee_parameters -// Missing event_update_status -]); - -var fee_schedule = new Serializer('fee_schedule', { - parameters: set(fee_parameters), - scale: uint32 -}); - -var void_result = new Serializer('void_result'); - -var asset = new Serializer('asset', { - amount: int64, - asset_id: protocol_id_type('asset') -}); - -var operation_result = static_variant([void_result, object_id_type, asset]); - -var processed_transaction = new Serializer('processed_transaction', { - ref_block_num: uint16, - ref_block_prefix: uint32, - expiration: time_point_sec, - operations: array(operation), - extensions: set(future_extensions), - signatures: array(bytes(65)), - operation_results: array(operation_result) -}); - -var signed_block = new Serializer('signed_block', { - previous: bytes(20), - timestamp: time_point_sec, - witness: protocol_id_type('witness'), - next_secret_hash: bytes(20), - previous_secret: bytes(20), - transaction_merkle_root: bytes(20), - extensions: set(future_extensions), - witness_signature: bytes(65), - transactions: array(processed_transaction) -}); - -var block_header = new Serializer('block_header', { - previous: bytes(20), - timestamp: time_point_sec, - witness: protocol_id_type('witness'), - next_secret_hash: bytes(20), - previous_secret: bytes(20), - transaction_merkle_root: bytes(20), - extensions: set(future_extensions) -}); - -var signed_block_header = new Serializer('signed_block_header', { - previous: bytes(20), - timestamp: time_point_sec, - witness: protocol_id_type('witness'), - next_secret_hash: bytes(20), - previous_secret: bytes(20), - transaction_merkle_root: bytes(20), - extensions: set(future_extensions), - witness_signature: bytes(65) -}); - -var memo_data = new Serializer('memo_data', { - from: public_key, - to: public_key, - nonce: uint64, - message: bytes() -}); - -var transfer = new Serializer('transfer', { - fee: asset, - from: protocol_id_type('account'), - to: protocol_id_type('account'), - amount: asset, - memo: optional(memo_data), - extensions: set(future_extensions) -}); - -var limit_order_create = new Serializer('limit_order_create', { - fee: asset, - seller: protocol_id_type('account'), - amount_to_sell: asset, - min_to_receive: asset, - expiration: time_point_sec, - fill_or_kill: bool, - extensions: set(future_extensions) -}); - -var limit_order_cancel = new Serializer('limit_order_cancel', { - fee: asset, - fee_paying_account: protocol_id_type('account'), - order: protocol_id_type('limit_order'), - extensions: set(future_extensions) -}); - -var call_order_update = new Serializer('call_order_update', { - fee: asset, - funding_account: protocol_id_type('account'), - delta_collateral: asset, - delta_debt: asset, - extensions: set(future_extensions) -}); - -var fill_order = new Serializer('fill_order', { - fee: asset, - order_id: object_id_type, - account_id: protocol_id_type('account'), - pays: asset, - receives: asset -}); - -var authority = new Serializer('authority', { - weight_threshold: uint32, - account_auths: map(protocol_id_type('account'), uint16), - key_auths: map(public_key, uint16), - address_auths: map(address, uint16) -}); - -var account_options = new Serializer('account_options', { - memo_key: public_key, - voting_account: protocol_id_type('account'), - num_witness: uint16, - num_committee: uint16, - votes: set(vote_id), - extensions: set(future_extensions) -}); - -var account_create = new Serializer('account_create', { - fee: asset, - registrar: protocol_id_type('account'), - referrer: protocol_id_type('account'), - referrer_percent: uint16, - name: string, - owner: authority, - active: authority, - options: account_options, - extensions: set(future_extensions) -}); - -var account_update = new Serializer('account_update', { - fee: asset, - account: protocol_id_type('account'), - owner: optional(authority), - active: optional(authority), - new_options: optional(account_options), - extensions: set(future_extensions) -}); - -var account_whitelist = new Serializer('account_whitelist', { - fee: asset, - authorizing_account: protocol_id_type('account'), - account_to_list: protocol_id_type('account'), - new_listing: uint8, - extensions: set(future_extensions) -}); - -var account_upgrade = new Serializer('account_upgrade', { - fee: asset, - account_to_upgrade: protocol_id_type('account'), - upgrade_to_lifetime_member: bool, - extensions: set(future_extensions) -}); - -var account_transfer = new Serializer('account_transfer', { - fee: asset, - account_id: protocol_id_type('account'), - new_owner: protocol_id_type('account'), - extensions: set(future_extensions) -}); - -var price = new Serializer('price', { - base: asset, - quote: asset -}); - -var asset_options = new Serializer('asset_options', { - max_supply: int64, - market_fee_percent: uint16, - max_market_fee: int64, - issuer_permissions: uint16, - flags: uint16, - core_exchange_rate: price, - whitelist_authorities: set(protocol_id_type('account')), - blacklist_authorities: set(protocol_id_type('account')), - whitelist_markets: set(protocol_id_type('asset')), - blacklist_markets: set(protocol_id_type('asset')), - description: string, - extensions: set(future_extensions) -}); - -var bitasset_options = new Serializer('bitasset_options', { - feed_lifetime_sec: uint32, - minimum_feeds: uint8, - force_settlement_delay_sec: uint32, - force_settlement_offset_percent: uint16, - maximum_force_settlement_volume: uint16, - short_backing_asset: protocol_id_type('asset'), - extensions: set(future_extensions) -}); - -var asset_create = new Serializer('asset_create', { - fee: asset, - issuer: protocol_id_type('account'), - symbol: string, - precision: uint8, - common_options: asset_options, - bitasset_opts: optional(bitasset_options), - is_prediction_market: bool, - extensions: set(future_extensions) -}); - -var asset_update = new Serializer('asset_update', { - fee: asset, - issuer: protocol_id_type('account'), - asset_to_update: protocol_id_type('asset'), - new_issuer: optional(protocol_id_type('account')), - new_options: asset_options, - extensions: set(future_extensions) -}); - -var asset_update_bitasset = new Serializer('asset_update_bitasset', { - fee: asset, - issuer: protocol_id_type('account'), - asset_to_update: protocol_id_type('asset'), - new_options: bitasset_options, - extensions: set(future_extensions) -}); - -var asset_update_feed_producers = new Serializer('asset_update_feed_producers', { - fee: asset, - issuer: protocol_id_type('account'), - asset_to_update: protocol_id_type('asset'), - new_feed_producers: set(protocol_id_type('account')), - extensions: set(future_extensions) -}); - -var asset_issue = new Serializer('asset_issue', { - fee: asset, - issuer: protocol_id_type('account'), - asset_to_issue: asset, - issue_to_account: protocol_id_type('account'), - memo: optional(memo_data), - extensions: set(future_extensions) -}); - -var asset_reserve = new Serializer('asset_reserve', { - fee: asset, - payer: protocol_id_type('account'), - amount_to_reserve: asset, - extensions: set(future_extensions) -}); - -var asset_fund_fee_pool = new Serializer('asset_fund_fee_pool', { - fee: asset, - from_account: protocol_id_type('account'), - asset_id: protocol_id_type('asset'), - amount: int64, - extensions: set(future_extensions) -}); - -var asset_settle = new Serializer('asset_settle', { - fee: asset, - account: protocol_id_type('account'), - amount: asset, - extensions: set(future_extensions) -}); - -var asset_global_settle = new Serializer('asset_global_settle', { - fee: asset, - issuer: protocol_id_type('account'), - asset_to_settle: protocol_id_type('asset'), - settle_price: price, - extensions: set(future_extensions) -}); - -var price_feed = new Serializer('price_feed', { - settlement_price: price, - maintenance_collateral_ratio: uint16, - maximum_short_squeeze_ratio: uint16, - core_exchange_rate: price -}); - -var asset_publish_feed = new Serializer('asset_publish_feed', { - fee: asset, - publisher: protocol_id_type('account'), - asset_id: protocol_id_type('asset'), - feed: price_feed, - extensions: set(future_extensions) -}); - -var witness_create = new Serializer('witness_create', { - fee: asset, - witness_account: protocol_id_type('account'), - url: string, - block_signing_key: public_key, - initial_secret: bytes(20) -}); - -var witness_update = new Serializer('witness_update', { - fee: asset, - witness: protocol_id_type('witness'), - witness_account: protocol_id_type('account'), - new_url: optional(string), - new_signing_key: optional(public_key), - new_initial_secret: optional(bytes(20)) -}); - -var op_wrapper = new Serializer('op_wrapper', { - op: operation -}); - -var proposal_create = new Serializer('proposal_create', { - fee: asset, - fee_paying_account: protocol_id_type('account'), - expiration_time: time_point_sec, - proposed_ops: array(op_wrapper), - review_period_seconds: optional(uint32), - extensions: set(future_extensions) -}); - -var proposal_update = new Serializer('proposal_update', { - fee: asset, - fee_paying_account: protocol_id_type('account'), - proposal: protocol_id_type('proposal'), - active_approvals_to_add: set(protocol_id_type('account')), - active_approvals_to_remove: set(protocol_id_type('account')), - owner_approvals_to_add: set(protocol_id_type('account')), - owner_approvals_to_remove: set(protocol_id_type('account')), - key_approvals_to_add: set(public_key), - key_approvals_to_remove: set(public_key), - extensions: set(future_extensions) -}); - -var proposal_delete = new Serializer('proposal_delete', { - fee: asset, - fee_paying_account: protocol_id_type('account'), - using_owner_authority: bool, - proposal: protocol_id_type('proposal'), - extensions: set(future_extensions) -}); - -var withdraw_permission_create = new Serializer('withdraw_permission_create', { - fee: asset, - withdraw_from_account: protocol_id_type('account'), - authorized_account: protocol_id_type('account'), - withdrawal_limit: asset, - withdrawal_period_sec: uint32, - periods_until_expiration: uint32, - period_start_time: time_point_sec -}); - -var withdraw_permission_update = new Serializer('withdraw_permission_update', { - fee: asset, - withdraw_from_account: protocol_id_type('account'), - authorized_account: protocol_id_type('account'), - permission_to_update: protocol_id_type('withdraw_permission'), - withdrawal_limit: asset, - withdrawal_period_sec: uint32, - period_start_time: time_point_sec, - periods_until_expiration: uint32 -}); - -var withdraw_permission_claim = new Serializer('withdraw_permission_claim', { - fee: asset, - withdraw_permission: protocol_id_type('withdraw_permission'), - withdraw_from_account: protocol_id_type('account'), - withdraw_to_account: protocol_id_type('account'), - amount_to_withdraw: asset, - memo: optional(memo_data) -}); - -var withdraw_permission_delete = new Serializer('withdraw_permission_delete', { - fee: asset, - withdraw_from_account: protocol_id_type('account'), - authorized_account: protocol_id_type('account'), - withdrawal_permission: protocol_id_type('withdraw_permission') -}); - -var committee_member_create = new Serializer('committee_member_create', { - fee: asset, - committee_member_account: protocol_id_type('account'), - url: string -}); - -var committee_member_update = new Serializer('committee_member_update', { - fee: asset, - committee_member: protocol_id_type('committee_member'), - committee_member_account: protocol_id_type('account'), - new_url: optional(string) -}); - -var chain_parameters = new Serializer('chain_parameters', { - current_fees: fee_schedule, - block_interval: uint8, - maintenance_interval: uint32, - maintenance_skip_slots: uint8, - committee_proposal_review_period: uint32, - maximum_transaction_size: uint32, - maximum_block_size: uint32, - maximum_time_until_expiration: uint32, - maximum_proposal_lifetime: uint32, - maximum_asset_whitelist_authorities: uint8, - maximum_asset_feed_publishers: uint8, - maximum_witness_count: uint16, - maximum_committee_count: uint16, - maximum_authority_membership: uint16, - reserve_percent_of_fee: uint16, - network_percent_of_fee: uint16, - lifetime_referrer_percent_of_fee: uint16, - cashback_vesting_period_seconds: uint32, - cashback_vesting_threshold: int64, - count_non_member_votes: bool, - allow_non_member_whitelists: bool, - witness_pay_per_block: int64, - worker_budget_per_day: int64, - max_predicate_opcode: uint16, - fee_liquidation_threshold: int64, - accounts_per_fee_scale: uint16, - account_fee_scale_bitshifts: uint8, - max_authority_depth: uint8, - min_bet_multiplier: uint32, - max_bet_multiplier: uint32, - betting_rake_fee_percentage: uint16, - permitted_betting_odds_increments: map(uint32, uint32), - witness_schedule_algorithm: uint8, - live_betting_delay_time: uint16, - min_round_delay: uint32, - max_round_delay: uint32, - min_time_per_commit_move: uint32, - max_time_per_commit_move: uint32, - min_time_per_reveal_move: uint32, - max_time_per_reveal_move: uint32, - rake_fee_percentage: uint16, - maximum_registration_deadline: uint32, - maximum_players_in_tournament: uint16, - maximum_tournament_whitelist_length: uint16, - maximum_tournament_start_time_in_future: uint32, - maximum_tournament_start_delay: uint32, - maximum_tournament_number_of_wins: uint16, - extensions: set(future_extensions) -}); - -var committee_member_update_global_parameters = new Serializer('committee_member_update_global_parameters', { - fee: asset, - new_parameters: chain_parameters -}); - -var linear_vesting_policy_initializer = new Serializer('linear_vesting_policy_initializer', { - begin_timestamp: time_point_sec, - vesting_cliff_seconds: uint32, - vesting_duration_seconds: uint32 -}); - -var cdd_vesting_policy_initializer = new Serializer('cdd_vesting_policy_initializer', { - start_claim: time_point_sec, - vesting_seconds: uint32 -}); - -var vesting_policy_initializer = static_variant([linear_vesting_policy_initializer, cdd_vesting_policy_initializer]); - -var vesting_balance_create = new Serializer('vesting_balance_create', { - fee: asset, - creator: protocol_id_type('account'), - owner: protocol_id_type('account'), - amount: asset, - policy: vesting_policy_initializer -}); - -var vesting_balance_withdraw = new Serializer('vesting_balance_withdraw', { - fee: asset, - vesting_balance: protocol_id_type('vesting_balance'), - owner: protocol_id_type('account'), - amount: asset -}); - -var refund_worker_initializer = new Serializer('refund_worker_initializer'); - -var vesting_balance_worker_initializer = new Serializer('vesting_balance_worker_initializer', { - pay_vesting_period_days: uint16 -}); - -var burn_worker_initializer = new Serializer('burn_worker_initializer'); - -var worker_initializer = static_variant([refund_worker_initializer, vesting_balance_worker_initializer, burn_worker_initializer]); - -var worker_create = new Serializer('worker_create', { - fee: asset, - owner: protocol_id_type('account'), - work_begin_date: time_point_sec, - work_end_date: time_point_sec, - daily_pay: int64, - name: string, - url: string, - initializer: worker_initializer -}); - -var custom = new Serializer('custom', { - fee: asset, - payer: protocol_id_type('account'), - required_auths: set(protocol_id_type('account')), - id: uint16, - data: bytes() -}); - -var account_name_eq_lit_predicate = new Serializer('account_name_eq_lit_predicate', { - account_id: protocol_id_type('account'), - name: string -}); - -var asset_symbol_eq_lit_predicate = new Serializer('asset_symbol_eq_lit_predicate', { - asset_id: protocol_id_type('asset'), - symbol: string -}); - -var block_id_predicate = new Serializer('block_id_predicate', { - id: bytes(20) -}); - -var predicate = static_variant([account_name_eq_lit_predicate, asset_symbol_eq_lit_predicate, block_id_predicate]); - -var assert = new Serializer('assert', { - fee: asset, - fee_paying_account: protocol_id_type('account'), - predicates: array(predicate), - required_auths: set(protocol_id_type('account')), - extensions: set(future_extensions) -}); - -var balance_claim = new Serializer('balance_claim', { - fee: asset, - deposit_to_account: protocol_id_type('account'), - balance_to_claim: protocol_id_type('balance'), - balance_owner_key: public_key, - total_claimed: asset -}); - -var override_transfer = new Serializer('override_transfer', { - fee: asset, - issuer: protocol_id_type('account'), - from: protocol_id_type('account'), - to: protocol_id_type('account'), - amount: asset, - memo: optional(memo_data), - extensions: set(future_extensions) -}); - -var stealth_confirmation = new Serializer('stealth_confirmation', { - one_time_key: public_key, - to: optional(public_key), - encrypted_memo: bytes() -}); - -var blind_output = new Serializer('blind_output', { - commitment: bytes(33), - range_proof: bytes(), - owner: authority, - stealth_memo: optional(stealth_confirmation) -}); - -var transfer_to_blind = new Serializer('transfer_to_blind', { - fee: asset, - amount: asset, - from: protocol_id_type('account'), - blinding_factor: bytes(32), - outputs: array(blind_output) -}); - -var blind_input = new Serializer('blind_input', { - commitment: bytes(33), - owner: authority -}); - -var blind_transfer = new Serializer('blind_transfer', { - fee: asset, - inputs: array(blind_input), - outputs: array(blind_output) -}); - -var transfer_from_blind = new Serializer('transfer_from_blind', { - fee: asset, - amount: asset, - to: protocol_id_type('account'), - blinding_factor: bytes(32), - inputs: array(blind_input) -}); - -var asset_settle_cancel = new Serializer('asset_settle_cancel', { - fee: asset, - settlement: protocol_id_type('force_settlement'), - account: protocol_id_type('account'), - amount: asset, - extensions: set(future_extensions) -}); - -var asset_claim_fees = new Serializer('asset_claim_fees', { - fee: asset, - issuer: protocol_id_type('account'), - amount_to_claim: asset, - extensions: set(future_extensions) -}); - -var fba_distribute = new Serializer('fba_distribute', { - fee: asset, - account_id: protocol_id_type('account'), - fba_id: protocol_id_type('fba_accumulator'), - amount: int64 -}); - -var rock_paper_scissors_game_options = new Serializer('rock_paper_scissors_game_options', { - insurance_enabled: bool, - time_per_commit_move: uint32, - time_per_reveal_move: uint32, - number_of_gestures: uint8 -}); - -var game_specific_details = static_variant([rock_paper_scissors_game_options]); - -var tournament_options = new Serializer('tournament_options', { - type_of_game: uint16, - registration_deadline: time_point_sec, - number_of_players: uint32, - buy_in: asset, - whitelist: set(protocol_id_type('account')), - start_time: optional(time_point_sec), - start_delay: optional(uint32), - round_delay: uint32, - number_of_wins: uint32, - meta: variant_object, - game_options: game_specific_details -}); - -var tournament_create = new Serializer('tournament_create', { - fee: asset, - creator: protocol_id_type('account'), - options: tournament_options, - extensions: set(future_extensions) -}); - -var tournament_join = new Serializer('tournament_join', { - fee: asset, - payer_account_id: protocol_id_type('account'), - player_account_id: protocol_id_type('account'), - tournament_id: protocol_id_type('tournament'), - buy_in: asset, - extensions: set(future_extensions) -}); - -var rock_paper_scissors_gesture = enumeration(['rock', 'paper', 'scissors', 'spock', 'lizard']); - -var rock_paper_scissors_throw_commit = new Serializer('rock_paper_scissors_throw_commit', { - nonce1: uint64, - throw_hash: sha256 -}); - -var rock_paper_scissors_throw_reveal = new Serializer('rock_paper_scissors_throw_reveal', { - nonce2: uint64, - gesture: rock_paper_scissors_gesture -}); - -var game_specific_moves = static_variant([rock_paper_scissors_throw_commit, rock_paper_scissors_throw_reveal]); - -var game_move = new Serializer('game_move', { - fee: asset, - game_id: protocol_id_type('game'), - player_account_id: protocol_id_type('account'), - move: game_specific_moves, - extensions: set(future_extensions) -}); - -var dividend_asset_options = new Serializer('dividend_asset_options', { - next_payout_time: optional(time_point_sec), - payout_interval: optional(uint32), - minimum_fee_percentage: uint64, - minimum_distribution_interval: optional(uint32), - extensions: set(future_extensions) -}); - -var asset_update_dividend = new Serializer('asset_update_dividend', { - fee: asset, - issuer: protocol_id_type('account'), - asset_to_update: protocol_id_type('asset'), - new_options: dividend_asset_options, - extensions: set(future_extensions) -}); - -var asset_dividend_distribution = new Serializer('asset_dividend_distribution', { - fee: asset, - dividend_asset_id: protocol_id_type('asset'), - account_id: protocol_id_type('account'), - amounts: set(asset), - extensions: set(future_extensions) -}); - -var sport_create = new Serializer('sport_create', { - fee: asset, - name: map(string, string), - extensions: set(future_extensions) -}); - -var sport_update = new Serializer('sport_update', { - fee: asset, - sport_id: protocol_id_type('sport'), - new_name: optional(map(string, string)), - extensions: set(future_extensions) -}); - -var event_group_create = new Serializer('event_group_create', { - fee: asset, - name: map(string, string), - sport_id: object_id_type, - extensions: set(future_extensions) -}); - -var event_group_update = new Serializer('event_group_update', { - fee: asset, - new_sport_id: optional(protocol_id_type('sport')), - new_name: optional(map(string, string)), - event_group_id: protocol_id_type('event_group'), - extensions: set(future_extensions) -}); - -var event_create = new Serializer('event_create', { - fee: asset, - name: map(string, string), - season: map(string, string), - start_time: optional(time_point_sec), - event_group_id: object_id_type, - extensions: set(future_extensions) -}); - -var event_update = new Serializer('event_update', { - fee: asset, - event_id: protocol_id_type('event'), - new_event_group_id: optional(protocol_id_type('event_group')), - new_name: optional(map(string, string)), - new_season: optional(map(string, string)), - new_start_time: optional(time_point_sec), - is_live_market: optional(bool), - extensions: set(future_extensions) -}); - -var betting_market_rules_create = new Serializer('betting_market_rules_create', { - fee: asset, - name: map(string, string), - description: map(string, string), - extensions: set(future_extensions) -}); - -var betting_market_rules_update = new Serializer('betting_market_rules_update', { - fee: asset, - new_name: optional(map(string, string)), - new_description: optional(map(string, string)), - extensions: set(future_extensions), - betting_market_rules_id: protocol_id_type('betting_market_rules') -}); - -var betting_market_group_create = new Serializer('betting_market_group_create', { - fee: asset, - description: map(string, string), - event_id: object_id_type, - rules_id: object_id_type, - asset_id: protocol_id_type('asset'), - extensions: set(future_extensions) -}); - -var betting_market_create = new Serializer('betting_market_create', { - fee: asset, - group_id: object_id_type, - description: map(string, string), - payout_condition: map(string, string), - extensions: set(future_extensions) -}); - -var bet_type = enumeration(['back', 'lay']); - -var bet_place = new Serializer('bet_place', { - fee: asset, - bettor_id: protocol_id_type('account'), - betting_market_id: protocol_id_type('betting_market'), - amount_to_bet: asset, - backer_multiplier: uint32, - back_or_lay: bet_type, - extensions: set(future_extensions) -}); - -var betting_market_resolution_type = enumeration(['win', 'not_win', 'cancel', 'BETTING_MARKET_RESOLUTION_COUNT']); - -var betting_market_group_resolve = new Serializer('betting_market_group_resolve', { - fee: asset, - betting_market_group_id: protocol_id_type('betting_market_group'), - resolutions: map(protocol_id_type('betting_market'), betting_market_resolution_type), - extensions: set(future_extensions) -}); - -var betting_market_group_resolved = new Serializer('betting_market_group_resolved', { - bettor_id: protocol_id_type('account'), - betting_market_group_id: protocol_id_type('betting_market_group'), - resolutions: map(protocol_id_type('betting_market'), betting_market_resolution_type), - winnings: int64, - fees_paid: int64, - fee: asset -}); - -var betting_market_group_cancel_unmatched_bets = new Serializer('betting_market_group_cancel_unmatched_bets', { - fee: asset, - betting_market_group_id: protocol_id_type('betting_market_group'), - extensions: set(future_extensions) -}); - -var bet_matched = new Serializer('bet_matched', { - bettor_id: protocol_id_type('account'), - bet_id: protocol_id_type('bet'), - betting_market_id: protocol_id_type('betting_market'), - amount_bet: asset, - fees_paid: int64, - backer_multiplier: uint32, - guaranteed_winnings_returned: int64 -}); - -var bet_cancel = new Serializer('bet_cancel', { - fee: asset, - bettor_id: protocol_id_type('account'), - bet_to_cancel: protocol_id_type('bet'), - extensions: set(future_extensions) -}); - -var bet_canceled = new Serializer('bet_canceled', { - bettor_id: protocol_id_type('account'), - bet_id: protocol_id_type('bet'), - stake_returned: asset, - unused_fees_returned: asset -}); - -var payout_type = enumeration(['prize_award', 'buyin_refund', 'rake_fee']); - -var tournament_payout = new Serializer('tournament_payout', { - fee: asset, - payout_account_id: protocol_id_type('account'), - tournament_id: protocol_id_type('tournament'), - payout_amount: asset, - type: payout_type, - extensions: set(future_extensions) -}); - -var tournament_leave = new Serializer('tournament_leave', { - fee: asset, - canceling_account_id: protocol_id_type('account'), - player_account_id: protocol_id_type('account'), - tournament_id: protocol_id_type('tournament'), - extensions: set(future_extensions) -}); - -var betting_market_group_update = new Serializer('betting_market_group_update', { - fee: asset, - betting_market_group_id: protocol_id_type('betting_market_group'), - new_description: optional(map(string, string)), - new_rules_id: optional(protocol_id_type('betting_market_rules')), - freeze: optional(bool), - delay_bets: optional(bool), - extensions: set(future_extensions) -}); - -var betting_market_update = new Serializer('betting_market_update', { - fee: asset, - betting_market_id: protocol_id_type('betting_market'), - new_group_id: optional(protocol_id_type('betting_market_group')), - new_description: optional(map(string, string)), - new_payout_condition: optional(map(string, string)), - extensions: set(future_extensions) -}); - -var bet_adjusted = new Serializer('bet_adjusted', { - bettor_id: protocol_id_type('account'), - bet_id: protocol_id_type('bet'), - stake_returned: asset -}); - -operation.st_operations = [transfer, limit_order_create, limit_order_cancel, call_order_update, fill_order, account_create, account_update, account_whitelist, account_upgrade, account_transfer, asset_create, asset_update, asset_update_bitasset, asset_update_feed_producers, asset_issue, asset_reserve, asset_fund_fee_pool, asset_settle, asset_global_settle, asset_publish_feed, witness_create, witness_update, proposal_create, proposal_update, proposal_delete, withdraw_permission_create, withdraw_permission_update, withdraw_permission_claim, withdraw_permission_delete, committee_member_create, committee_member_update, committee_member_update_global_parameters, vesting_balance_create, vesting_balance_withdraw, worker_create, custom, assert, balance_claim, override_transfer, transfer_to_blind, blind_transfer, transfer_from_blind, asset_settle_cancel, asset_claim_fees, fba_distribute, tournament_create, tournament_join, game_move, asset_update_dividend, asset_dividend_distribution, tournament_payout, tournament_leave, sport_create, sport_update, event_group_create, event_group_update, event_create, event_update, betting_market_rules_create, betting_market_rules_update, betting_market_group_create, betting_market_create, bet_place, betting_market_group_resolve, betting_market_group_resolved, bet_adjusted, betting_market_group_cancel_unmatched_bets, bet_matched, bet_cancel, bet_canceled, betting_market_group_update, betting_market_update]; - -var transaction = new Serializer('transaction', { - ref_block_num: uint16, - ref_block_prefix: uint32, - expiration: time_point_sec, - operations: array(operation), - extensions: set(future_extensions) -}); - -var signed_transaction = new Serializer('signed_transaction', { - ref_block_num: uint16, - ref_block_prefix: uint32, - expiration: time_point_sec, - operations: array(operation), - extensions: set(future_extensions), - signatures: array(bytes(65)) -}); -// # ------------------------------- -// # Generated code end -// # ------------------------------- - -// Betting Objects - -var sport = new Serializer('sport', { - id: protocol_id_type('sport'), - name: map(string, string) -}); - -var event_group = new Serializer('event_group', { - id: protocol_id_type('event_group'), - name: map(string, string), - sport_id: protocol_id_type('sport') -}); - -var event_status = enumeration(['upcoming', 'in_progress', 'frozen', 'finished', 'completed', 'canceled', 'STATUS_COUNT']); - -var betting_market_status = enumeration(['unresolved', 'frozen', 'graded', 'canceled', 'settled']); - -var betting_market_group_status = enumeration(['upcoming', 'in_play', 'closed', 'graded', 're-grading', 'settled', 'frozen', 'canceled']); - -var event = new Serializer('event', { - id: protocol_id_type('event'), - name: map(string, string), - season: map(string, string), - start_time: optional(time_point_sec), - event_group_id: protocol_id_type('event_group'), - is_live_market: bool, - status: event_status, - scores: array(string) -}); - -var betting_market_rules = new Serializer('betting_market_rules', { - id: protocol_id_type('betting_market_rules'), - name: map(string, string), - description: map(string, string) -}); - -var betting_market_group = new Serializer('betting_market_group', { - id: protocol_id_type('betting_market_group'), - description: map(string, string), - event_id: protocol_id_type('event'), - rules_id: protocol_id_type('betting_market_rules'), - asset_id: protocol_id_type('asset'), - total_matched_bets_amount: uint64, - frozen: bool, - delay_bets: bool, - status: betting_market_group_status -}); - -var betting_market = new Serializer('betting_market', { - id: protocol_id_type('betting_market'), - group_id: protocol_id_type('betting_market_group'), - description: map(string, string), - payout_condition: map(string, string), - status: betting_market_status -}); - -var bet = new Serializer('bet', { - id: protocol_id_type('bet'), - bettor_id: protocol_id_type('account'), - betting_market_id: protocol_id_type('betting_market'), - amount_to_bet: asset, - backer_multiplier: uint32, - back_or_lay: bet_type -}); - -var betting_market_position = new Serializer('betting_market_position', { - id: implementation_id_type('betting_market_position'), - bettor_id: protocol_id_type('account'), - betting_market_id: protocol_id_type('betting_market'), - pay_if_payout_condition: int64, - pay_if_not_payout_condition: int64, - pay_if_canceled: int64, - pay_if_not_canceled: int64, - fees_collected: int64 -}); - -var global_betting_statistics = new Serializer('global_betting_statistics', { - id: implementation_id_type('global_betting_statistics'), - number_of_active_events: uint32, - total_amount_staked: map(protocol_id_type('asset'), int64) -}); - -// eof Betting Objects - -// Custom Types - -var stealth_memo_data = new Serializer('stealth_memo_data', { - from: optional(public_key), - amount: asset, - blinding_factor: bytes(32), - commitment: bytes(33), - check: uint32 -}); -// var stealth_confirmation = new Serializer( -// "stealth_confirmation", { -// one_time_key: public_key, -// to: optional( public_key ), -// encrypted_memo: stealth_memo_data -// }) - -exports.operation = operation; -exports.transfer_operation_fee_parameters = transfer_operation_fee_parameters; -exports.limit_order_create_operation_fee_parameters = limit_order_create_operation_fee_parameters; -exports.limit_order_cancel_operation_fee_parameters = limit_order_cancel_operation_fee_parameters; -exports.call_order_update_operation_fee_parameters = call_order_update_operation_fee_parameters; -exports.fill_order_operation_fee_parameters = fill_order_operation_fee_parameters; -exports.account_create_operation_fee_parameters = account_create_operation_fee_parameters; -exports.account_update_operation_fee_parameters = account_update_operation_fee_parameters; -exports.account_whitelist_operation_fee_parameters = account_whitelist_operation_fee_parameters; -exports.account_upgrade_operation_fee_parameters = account_upgrade_operation_fee_parameters; -exports.account_transfer_operation_fee_parameters = account_transfer_operation_fee_parameters; -exports.asset_create_operation_fee_parameters = asset_create_operation_fee_parameters; -exports.asset_update_operation_fee_parameters = asset_update_operation_fee_parameters; -exports.asset_update_bitasset_operation_fee_parameters = asset_update_bitasset_operation_fee_parameters; -exports.asset_update_feed_producers_operation_fee_parameters = asset_update_feed_producers_operation_fee_parameters; -exports.asset_issue_operation_fee_parameters = asset_issue_operation_fee_parameters; -exports.asset_reserve_operation_fee_parameters = asset_reserve_operation_fee_parameters; -exports.asset_fund_fee_pool_operation_fee_parameters = asset_fund_fee_pool_operation_fee_parameters; -exports.asset_settle_operation_fee_parameters = asset_settle_operation_fee_parameters; -exports.asset_global_settle_operation_fee_parameters = asset_global_settle_operation_fee_parameters; -exports.asset_publish_feed_operation_fee_parameters = asset_publish_feed_operation_fee_parameters; -exports.witness_create_operation_fee_parameters = witness_create_operation_fee_parameters; -exports.witness_update_operation_fee_parameters = witness_update_operation_fee_parameters; -exports.proposal_create_operation_fee_parameters = proposal_create_operation_fee_parameters; -exports.proposal_update_operation_fee_parameters = proposal_update_operation_fee_parameters; -exports.proposal_delete_operation_fee_parameters = proposal_delete_operation_fee_parameters; -exports.withdraw_permission_create_operation_fee_parameters = withdraw_permission_create_operation_fee_parameters; -exports.withdraw_permission_update_operation_fee_parameters = withdraw_permission_update_operation_fee_parameters; -exports.withdraw_permission_claim_operation_fee_parameters = withdraw_permission_claim_operation_fee_parameters; -exports.withdraw_permission_delete_operation_fee_parameters = withdraw_permission_delete_operation_fee_parameters; -exports.committee_member_create_operation_fee_parameters = committee_member_create_operation_fee_parameters; -exports.committee_member_update_operation_fee_parameters = committee_member_update_operation_fee_parameters; -exports.committee_member_update_global_parameters_operation_fee_parameters = committee_member_update_global_parameters_operation_fee_parameters; -exports.vesting_balance_create_operation_fee_parameters = vesting_balance_create_operation_fee_parameters; -exports.vesting_balance_withdraw_operation_fee_parameters = vesting_balance_withdraw_operation_fee_parameters; -exports.worker_create_operation_fee_parameters = worker_create_operation_fee_parameters; -exports.custom_operation_fee_parameters = custom_operation_fee_parameters; -exports.assert_operation_fee_parameters = assert_operation_fee_parameters; -exports.balance_claim_operation_fee_parameters = balance_claim_operation_fee_parameters; -exports.override_transfer_operation_fee_parameters = override_transfer_operation_fee_parameters; -exports.transfer_to_blind_operation_fee_parameters = transfer_to_blind_operation_fee_parameters; -exports.blind_transfer_operation_fee_parameters = blind_transfer_operation_fee_parameters; -exports.transfer_from_blind_operation_fee_parameters = transfer_from_blind_operation_fee_parameters; -exports.asset_settle_cancel_operation_fee_parameters = asset_settle_cancel_operation_fee_parameters; -exports.asset_claim_fees_operation_fee_parameters = asset_claim_fees_operation_fee_parameters; -exports.fba_distribute_operation_fee_parameters = fba_distribute_operation_fee_parameters; -exports.asset_update_dividend_operation_fee_parameters = asset_update_dividend_operation_fee_parameters; -exports.asset_dividend_distribution_operation_fee_parameters = asset_dividend_distribution_operation_fee_parameters; -exports.sport_create_operation_fee_parameters = sport_create_operation_fee_parameters; -exports.sport_update_operation_fee_parameters = sport_update_operation_fee_parameters; -exports.event_group_create_operation_fee_parameters = event_group_create_operation_fee_parameters; -exports.event_group_update_operation_fee_parameters = event_group_update_operation_fee_parameters; -exports.event_create_operation_fee_parameters = event_create_operation_fee_parameters; -exports.event_update_operation_fee_parameters = event_update_operation_fee_parameters; -exports.betting_market_rules_create_operation_fee_parameters = betting_market_rules_create_operation_fee_parameters; -exports.betting_market_rules_update_operation_fee_parameters = betting_market_rules_update_operation_fee_parameters; -exports.betting_market_group_create_operation_fee_parameters = betting_market_group_create_operation_fee_parameters; -exports.betting_market_create_operation_fee_parameters = betting_market_create_operation_fee_parameters; -exports.bet_place_operation_fee_parameters = bet_place_operation_fee_parameters; -exports.betting_market_group_resolve_operation_fee_parameters = betting_market_group_resolve_operation_fee_parameters; -exports.betting_market_group_resolved_operation_fee_parameters = betting_market_group_resolved_operation_fee_parameters; -exports.betting_market_group_cancel_unmatched_bets_operation_fee_parameters = betting_market_group_cancel_unmatched_bets_operation_fee_parameters; -exports.bet_matched_operation_fee_parameters = bet_matched_operation_fee_parameters; -exports.bet_cancel_operation_fee_parameters = bet_cancel_operation_fee_parameters; -exports.bet_canceled_operation_fee_parameters = bet_canceled_operation_fee_parameters; -exports.tournament_create_operation_fee_parameters = tournament_create_operation_fee_parameters; -exports.tournament_join_operation_fee_parameters = tournament_join_operation_fee_parameters; -exports.game_move_operation_fee_parameters = game_move_operation_fee_parameters; -exports.tournament_payout_operation_fee_parameters = tournament_payout_operation_fee_parameters; -exports.tournament_leave_operation_fee_parameters = tournament_leave_operation_fee_parameters; -exports.betting_market_group_update_operation_fee_parameters = betting_market_group_update_operation_fee_parameters; -exports.betting_market_update_operation_fee_parameters = betting_market_update_operation_fee_parameters; -exports.bet_adjusted_operation_fee_parameters = bet_adjusted_operation_fee_parameters; -exports.fee_schedule = fee_schedule; -exports.void_result = void_result; -exports.asset = asset; -exports.processed_transaction = processed_transaction; -exports.signed_block = signed_block; -exports.block_header = block_header; -exports.signed_block_header = signed_block_header; -exports.memo_data = memo_data; -exports.transfer = transfer; -exports.limit_order_create = limit_order_create; -exports.limit_order_cancel = limit_order_cancel; -exports.call_order_update = call_order_update; -exports.fill_order = fill_order; -exports.authority = authority; -exports.account_options = account_options; -exports.account_create = account_create; -exports.account_update = account_update; -exports.account_whitelist = account_whitelist; -exports.account_upgrade = account_upgrade; -exports.account_transfer = account_transfer; -exports.price = price; -exports.asset_options = asset_options; -exports.bitasset_options = bitasset_options; -exports.asset_create = asset_create; -exports.asset_update = asset_update; -exports.asset_update_bitasset = asset_update_bitasset; -exports.asset_update_feed_producers = asset_update_feed_producers; -exports.asset_issue = asset_issue; -exports.asset_reserve = asset_reserve; -exports.asset_fund_fee_pool = asset_fund_fee_pool; -exports.asset_settle = asset_settle; -exports.asset_global_settle = asset_global_settle; -exports.price_feed = price_feed; -exports.asset_publish_feed = asset_publish_feed; -exports.witness_create = witness_create; -exports.witness_update = witness_update; -exports.op_wrapper = op_wrapper; -exports.proposal_create = proposal_create; -exports.proposal_update = proposal_update; -exports.proposal_delete = proposal_delete; -exports.withdraw_permission_create = withdraw_permission_create; -exports.withdraw_permission_update = withdraw_permission_update; -exports.withdraw_permission_claim = withdraw_permission_claim; -exports.withdraw_permission_delete = withdraw_permission_delete; -exports.committee_member_create = committee_member_create; -exports.committee_member_update = committee_member_update; -exports.chain_parameters = chain_parameters; -exports.committee_member_update_global_parameters = committee_member_update_global_parameters; -exports.linear_vesting_policy_initializer = linear_vesting_policy_initializer; -exports.cdd_vesting_policy_initializer = cdd_vesting_policy_initializer; -exports.vesting_balance_create = vesting_balance_create; -exports.vesting_balance_withdraw = vesting_balance_withdraw; -exports.refund_worker_initializer = refund_worker_initializer; -exports.vesting_balance_worker_initializer = vesting_balance_worker_initializer; -exports.burn_worker_initializer = burn_worker_initializer; -exports.worker_create = worker_create; -exports.custom = custom; -exports.account_name_eq_lit_predicate = account_name_eq_lit_predicate; -exports.asset_symbol_eq_lit_predicate = asset_symbol_eq_lit_predicate; -exports.block_id_predicate = block_id_predicate; -exports.assert = assert; -exports.balance_claim = balance_claim; -exports.override_transfer = override_transfer; -exports.stealth_confirmation = stealth_confirmation; -exports.blind_output = blind_output; -exports.transfer_to_blind = transfer_to_blind; -exports.blind_input = blind_input; -exports.blind_transfer = blind_transfer; -exports.transfer_from_blind = transfer_from_blind; -exports.asset_settle_cancel = asset_settle_cancel; -exports.asset_claim_fees = asset_claim_fees; -exports.fba_distribute = fba_distribute; -exports.rock_paper_scissors_game_options = rock_paper_scissors_game_options; -exports.tournament_options = tournament_options; -exports.tournament_create = tournament_create; -exports.tournament_join = tournament_join; -exports.rock_paper_scissors_gesture = rock_paper_scissors_gesture; -exports.rock_paper_scissors_throw_commit = rock_paper_scissors_throw_commit; -exports.rock_paper_scissors_throw_reveal = rock_paper_scissors_throw_reveal; -exports.game_move = game_move; -exports.dividend_asset_options = dividend_asset_options; -exports.asset_update_dividend = asset_update_dividend; -exports.asset_dividend_distribution = asset_dividend_distribution; -exports.sport_create = sport_create; -exports.sport_update = sport_update; -exports.event_group_create = event_group_create; -exports.event_group_update = event_group_update; -exports.event_create = event_create; -exports.event_update = event_update; -exports.betting_market_rules_create = betting_market_rules_create; -exports.betting_market_rules_update = betting_market_rules_update; -exports.betting_market_group_create = betting_market_group_create; -exports.betting_market_create = betting_market_create; -exports.bet_type = bet_type; -exports.bet_place = bet_place; -exports.betting_market_resolution_type = betting_market_resolution_type; -exports.betting_market_group_resolve = betting_market_group_resolve; -exports.betting_market_group_resolved = betting_market_group_resolved; -exports.betting_market_group_cancel_unmatched_bets = betting_market_group_cancel_unmatched_bets; -exports.bet_matched = bet_matched; -exports.bet_cancel = bet_cancel; -exports.bet_canceled = bet_canceled; -exports.payout_type = payout_type; -exports.tournament_payout = tournament_payout; -exports.tournament_leave = tournament_leave; -exports.betting_market_group_update = betting_market_group_update; -exports.betting_market_update = betting_market_update; -exports.bet_adjusted = bet_adjusted; -exports.transaction = transaction; -exports.signed_transaction = signed_transaction; -exports.sport = sport; -exports.event_group = event_group; -exports.event = event; -exports.betting_market_rules = betting_market_rules; -exports.betting_market_group = betting_market_group; -exports.betting_market = betting_market; -exports.bet = bet; -exports.betting_market_position = betting_market_position; -exports.global_betting_statistics = global_betting_statistics; -exports.stealth_memo_data = stealth_memo_data; -},{"24":24,"26":26}],24:[function(require,module,exports){ -(function (process,Buffer){ -'use strict'; - -exports.__esModule = true; - -var _bytebuffer = require(38); - -var _bytebuffer2 = _interopRequireDefault(_bytebuffer); - -var _error_with_cause = require(22); - -var _error_with_cause2 = _interopRequireDefault(_error_with_cause); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; - -var Serializer = function () { - function Serializer(operation_name, types) { - _classCallCheck(this, Serializer); - - this.operation_name = operation_name; - this.types = types; - - if (this.types) { - this.keys = Object.keys(this.types); - } - - Serializer.printDebug = true; - } - - Serializer.prototype.fromByteBuffer = function fromByteBuffer(b) { - var object = {}; - var field = null; - - try { - var iterable = this.keys; - - for (var i = 0; i < iterable.length; i++) { - field = iterable[i]; - var type = this.types[field]; - - try { - if (HEX_DUMP) { - if (type.operation_name) { - console.error(type.operation_name); - } else { - var o1 = b.offset; - type.fromByteBuffer(b); - var o2 = b.offset; - b.offset = o1; - // b.reset() - var _b = b.copy(o1, o2); - console.error(this.operation_name + '.' + field + '\t', _b.toHex()); - } - } - - object[field] = type.fromByteBuffer(b); - } catch (e) { - if (Serializer.printDebug) { - console.error('Error reading ' + this.operation_name + '.' + field + ' in data:'); - b.printDebug(); - } - - throw e; - } - } - } catch (error) { - _error_with_cause2.default.throw(this.operation_name + '.' + field, error); - } - - return object; - }; - - Serializer.prototype.appendByteBuffer = function appendByteBuffer(b, object) { - var field = null; - - try { - var iterable = this.keys; - - for (var i = 0; i < iterable.length; i++) { - field = iterable[i]; - var type = this.types[field]; - type.appendByteBuffer(b, object[field]); - } - } catch (error) { - try { - _error_with_cause2.default.throw(this.operation_name + '.' + field + ' = ' + JSON.stringify(object[field]), error); - } catch (e) { - // circular ref - _error_with_cause2.default.throw(this.operation_name + '.' + field + ' = ' + object[field], error); - } - } - }; - - Serializer.prototype.fromObject = function fromObject(serialized_object) { - var result = {}; - var field = null; - - try { - var iterable = this.keys; - - for (var i = 0; i < iterable.length; i++) { - field = iterable[i]; - var type = this.types[field]; - var value = serialized_object[field]; - // DEBUG value = value.resolve if value.resolve - // DEBUG console.log('... value',field,value) - var object = type.fromObject(value); - result[field] = object; - } - } catch (error) { - _error_with_cause2.default.throw(this.operation_name + '.' + field, error); - } - - return result; - }; - - /** - @arg {boolean} [debug.use_default = false] - more template friendly - @arg {boolean} [debug.annotate = false] - add user-friendly information - */ - - - Serializer.prototype.toObject = function toObject() { - var serialized_object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { use_default: false, annotate: false }; - - var result = {}; - var field = null; - - try { - if (!this.types) { - return result; - } - - var iterable = this.keys; - - for (var i = 0; i < iterable.length; i++) { - field = iterable[i]; - var type = this.types[field]; - var object = type.toObject(typeof serialized_object !== 'undefined' && serialized_object !== null ? serialized_object[field] : undefined, debug); - result[field] = object; - - if (HEX_DUMP) { - var b = new _bytebuffer2.default(_bytebuffer2.default.DEFAULT_CAPACITY, _bytebuffer2.default.LITTLE_ENDIAN); - type.appendByteBuffer(b, typeof serialized_object !== 'undefined' && serialized_object !== null ? serialized_object[field] : undefined); - b = b.copy(0, b.offset); - console.error(this.operation_name + '.' + field, b.toHex()); - } - } - } catch (error) { - _error_with_cause2.default.throw(this.operation_name + '.' + field, error); - } - - return result; - }; - - /** Sort by the first element in a operation */ - - - Serializer.prototype.compare = function compare(a, b) { - var first_key = this.keys[0]; - var first_type = this.types[first_key]; - - var valA = a[first_key]; - var valB = b[first_key]; - - if (first_type.compare) { - return first_type.compare(valA, valB); - } - - if (typeof valA === 'number' && typeof valB === 'number') { - return valA - valB; - } - - var encoding = void 0; - - if (Buffer.isBuffer(valA) && Buffer.isBuffer(valB)) { - // A binary string compare does not work. If localeCompare is well supported that could - // replace HEX. Performanance is very good so comparing HEX works. - encoding = 'hex'; - } - - var strA = valA.toString(encoding); - var strB = valB.toString(encoding); - - var result = 0; - - if (strA > strB) { - result = 1; - } - - if (strA < strB) { - result = -1; - } - - return result; - }; - - // - - Serializer.prototype.fromHex = function fromHex(hex) { - var b = _bytebuffer2.default.fromHex(hex, _bytebuffer2.default.LITTLE_ENDIAN); - return this.fromByteBuffer(b); - }; - - Serializer.prototype.fromBuffer = function fromBuffer(buffer) { - var b = _bytebuffer2.default.fromBinary(buffer.toString('binary'), _bytebuffer2.default.LITTLE_ENDIAN); - return this.fromByteBuffer(b); - }; - - Serializer.prototype.toHex = function toHex(object) { - // return this.toBuffer(object).toString("hex") - var b = this.toByteBuffer(object); - return b.toHex(); - }; - - Serializer.prototype.toByteBuffer = function toByteBuffer(object) { - var b = new _bytebuffer2.default(_bytebuffer2.default.DEFAULT_CAPACITY, _bytebuffer2.default.LITTLE_ENDIAN); - this.appendByteBuffer(b, object); - return b.copy(0, b.offset); - }; - - Serializer.prototype.toBuffer = function toBuffer(object) { - return Buffer.from(this.toByteBuffer(object).toBinary(), 'binary'); - }; - - return Serializer; -}(); - -exports.default = Serializer; -module.exports = exports['default']; -}).call(this,require(77),require(35).Buffer) - -},{"22":22,"35":35,"38":38,"77":77}],25:[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -exports.default = template; /** Console print any transaction object with zero default values. */ -function template(op) { - var object = op.toObject(undefined, { use_default: true, annotate: true }); - - // visual (with descriptions) - console.error(JSON.stringify(object, null, 4)); - - // usable in a copy-paste - - object = op.toObject(undefined, { use_default: true, annotate: false }); - - // copy-paste one-lineer - console.error(JSON.stringify(object)); -} -module.exports = exports["default"]; -},{}],26:[function(require,module,exports){ -(function (process,Buffer){ -'use strict'; - -exports.__esModule = true; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // Low-level types that make up operations - -var _peerplaysjsWs = require(70); - -var _SerializerValidation = require(21); - -var _SerializerValidation2 = _interopRequireDefault(_SerializerValidation); - -var _FastParser = require(20); - -var _FastParser2 = _interopRequireDefault(_FastParser); - -var _ChainTypes = require(3); - -var _ChainTypes2 = _interopRequireDefault(_ChainTypes); - -var _ObjectId = require(4); - -var _ObjectId2 = _interopRequireDefault(_ObjectId); - -var _ecc = require(7); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var MIN_SIGNED_32 = -1 * Math.pow(2, 31); -var MAX_SIGNED_32 = Math.pow(2, 31) - 1; - -var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; - -var strCmp = function strCmp(a, b) { - var result = 0; - - if (a > b) { - result = 1; - } +module.exports = function template(op) { - if (a < b) { - result = -1; - } - - return result; -}; - -var firstEl = function firstEl(el) { - return Array.isArray(el) ? el[0] : el; -}; - -var sortOperation = function sortOperation(array, st_operation) { - if (!st_operation.nosort) { - // If the operation has its own compare function. - if (st_operation.compare) { - return array.sort(function (a, b) { - return st_operation.compare(firstEl(a), firstEl(b)); - }); - } - - return array.sort(function (a, b) { - var aFirst = firstEl(a); - var bFirst = firstEl(b); - - // If both of the first elements are numbers. - if (typeof aFirst === 'number' && typeof bFirst === 'number') { - return aFirst - bFirst; - } - - // If they are both buffers. - if (Buffer.isBuffer(aFirst) && Buffer.isBuffer(bFirst)) { - return strCmp(aFirst.toString('hex'), bFirst.toString('hex')); - } - - // Otherwise - return strCmp(aFirst.toString(), bFirst.toString()); - }); - } - - return array; -}; - -var Types = {}; - -Types.uint8 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint8(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.require_range(0, 0xff, object, 'uint8 ' + object); - b.writeUint8(object); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.require_range(0, 0xff, object, 'uint8 ' + object); - return object; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return 0; - } - - _SerializerValidation2.default.require_range(0, 0xff, object, 'uint8 ' + object); - return parseInt(object, 10); - } -}; - -Types.uint16 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint16(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.require_range(0, 0xffff, object, 'uint16 ' + object); - b.writeUint16(object); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.require_range(0, 0xffff, object, 'uint16 ' + object); - return object; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return 0; - } - - _SerializerValidation2.default.require_range(0, 0xffff, object, 'uint16 ' + object); - return parseInt(object, 10); - } -}; - -Types.uint32 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint32(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.require_range(0, 0xffffffff, object, 'uint32 ' + object); - b.writeUint32(object); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.require_range(0, 0xffffffff, object, 'uint32 ' + object); - return object; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return 0; - } - - _SerializerValidation2.default.require_range(0, 0xffffffff, object, 'uint32 ' + object); - return parseInt(object, 10); - } -}; - -Types.varint32 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readVarint32(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); - b.writeVarint32(object); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); - return object; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return 0; - } - - _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); - return parseInt(object, 10); - } -}; - -Types.int64 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readInt64(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - b.writeInt64(_SerializerValidation2.default.to_long(object)); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - return _SerializerValidation2.default.to_long(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return '0'; - } - - _SerializerValidation2.default.required(object); - return _SerializerValidation2.default.to_long(object).toString(); - } -}; - -Types.uint64 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint64(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - b.writeUint64(_SerializerValidation2.default.to_ulong(_SerializerValidation2.default.unsigned(object))); - }, - fromObject: function fromObject(object) { - return _SerializerValidation2.default.to_ulong(_SerializerValidation2.default.unsigned(object)); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return '0'; - } - - return _SerializerValidation2.default.to_ulong(object).toString(); - } -}; - -Types.string = { - fromByteBuffer: function fromByteBuffer(b) { - var b_copy = void 0; - var len = b.readVarint32(); - b_copy = b.copy(b.offset, b.offset + len); - b.skip(len); - return Buffer.from(b_copy.toBinary(), 'binary'); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - b.writeVarint32(object.length); - b.append(object.toString('binary'), 'binary'); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - return Buffer.from(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return ''; - } - - return object.toString(); - } -}; - -Types.bytes = function (size) { - var bytes = { - fromByteBuffer: function fromByteBuffer(b) { - if (size === undefined) { - var _b_copy = void 0; - var len = b.readVarint32(); - _b_copy = b.copy(b.offset, b.offset + len); - b.skip(len); - return Buffer.from(_b_copy.toBinary(), 'binary'); - } - - var b_copy = b.copy(b.offset, b.offset + size); - b.skip(size); - return Buffer.from(b_copy.toBinary(), 'binary'); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - - if (typeof object === 'string') { - object = Buffer.from(object, 'hex'); - } - - if (size === undefined) { - b.writeVarint32(object.length); - } - - b.append(object.toString('binary'), 'binary'); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - - if (Buffer.isBuffer(object)) { - return object; - } - - return Buffer.from(object, 'hex'); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return new Array(size).join('00'); - } - - _SerializerValidation2.default.required(object); - return object.toString('hex'); - } - }; + var object = op.toObject(void 0, { use_default: true, annotate: true }); - return bytes; -}; + // visual (with descriptions) + console.error(JSON.stringify(object, null, 4)); -Types.bool = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint8() === 1; - }, - appendByteBuffer: function appendByteBuffer(b, object) { - // supports boolean or integer - b.writeUint8(JSON.parse(object) ? 1 : 0); - }, - fromObject: function fromObject(object) { - return !!JSON.parse(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + // usable in a copy-paste - if (debug.use_default && object === undefined) { - return false; - } + object = op.toObject(void 0, { use_default: true, annotate: false }); - return !!JSON.parse(object); - } + // copy-paste one-lineer + console.error(JSON.stringify(object)); }; +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/types.js":[function(require,module,exports){ +(function (process,Buffer){ +'use strict'; -Types.void = { - fromByteBuffer: function fromByteBuffer() { - throw new Error('(void) undefined type'); - }, - appendByteBuffer: function appendByteBuffer() { - throw new Error('(void) undefined type'); - }, - fromObject: function fromObject() { - throw new Error('(void) undefined type'); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; 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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - if (debug.use_default && object === undefined) { - return undefined; - } +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - throw new Error('(void) undefined type'); - } -}; +// Low-level types that make up operations -Types.array = function (st_operation) { - var array = { - fromByteBuffer: function fromByteBuffer(b) { - var size = b.readVarint32(); +var v = require('./SerializerValidation'); +var fp = require('./FastParser'); - if (HEX_DUMP) { - console.log('varint32 size = ' + size.toString(16)); - } +var ChainTypes = require("../../chain/src/ChainTypes"); +var ObjectId = require("../../chain/src/ObjectId"); - var result = []; +var _require = require("../../ecc"), + PublicKey = _require.PublicKey, + Address = _require.Address; - for (var i = 0; size > 0 ? i < size : i > size; size > 0 ? i++ : i++) { - result.push(st_operation.fromByteBuffer(b)); - } +var _require2 = require("peerplaysjs-ws"), + ChainConfig = _require2.ChainConfig; + +var Types = {}; +module.exports = Types; + +var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; - return sortOperation(result, st_operation); +Types.uint8 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint8(); }, appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - object = sortOperation(object, st_operation); - b.writeVarint32(object.length); - - for (var i = 0, len = object.length; i < len; i++) { - var o = object[i]; - st_operation.appendByteBuffer(b, o); - } + v.require_range(0, 0xFF, object, 'uint8 ' + object); + b.writeUint8(object); + return; }, fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - object = sortOperation(object, st_operation); - var result = []; - - for (var i = 0, len = object.length; i < len; i++) { - var o = object[i]; - result.push(st_operation.fromObject(o)); - } - - return result; + v.require_range(0, 0xFF, object, 'uint8 ' + object); + return object; }, toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return [st_operation.toObject(object, debug)]; - } - - _SerializerValidation2.default.required(object); - object = sortOperation(object, st_operation); - - var result = []; + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - for (var i = 0, len = object.length; i < len; i++) { - var o = object[i]; - result.push(st_operation.toObject(o, debug)); - } - - return result; + if (debug.use_default && object === undefined) { + return 0; + } + v.require_range(0, 0xFF, object, 'uint8 ' + object); + return parseInt(object); } - }; - - return array; }; -Types.time_point_sec = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint32(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - if (typeof object !== 'number') { - object = Types.time_point_sec.fromObject(object); - } - - b.writeUint32(object); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); +Types.uint16 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint16(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.require_range(0, 0xFFFF, object, 'uint16 ' + object); + b.writeUint16(object); + return; + }, + fromObject: function fromObject(object) { + v.require_range(0, 0xFFFF, object, 'uint16 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (typeof object === 'number') { - return object; + if (debug.use_default && object === undefined) { + return 0; + } + v.require_range(0, 0xFFFF, object, 'uint16 ' + object); + return parseInt(object); } +}; - if (object.getTime) { - return Math.floor(object.getTime() / 1000); - } +Types.uint32 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.require_range(0, 0xFFFFFFFF, object, 'uint32 ' + object); + b.writeUint32(object); + return; + }, + fromObject: function fromObject(object) { + v.require_range(0, 0xFFFFFFFF, object, 'uint32 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (typeof object !== 'string') { - throw new Error('Unknown date type: ' + object); + if (debug.use_default && object === undefined) { + return 0; + } + v.require_range(0, 0xFFFFFFFF, object, 'uint32 ' + object); + return parseInt(object); } +}; - // if(typeof object === "string" && !/Z$/.test(object)) - // object = object + "Z" +var MIN_SIGNED_32 = -1 * Math.pow(2, 31); +var MAX_SIGNED_32 = Math.pow(2, 31) - 1; - return Math.floor(new Date(object).getTime() / 1000); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; +Types.varint32 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readVarint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); + b.writeVarint32(object); + return; + }, + fromObject: function fromObject(object) { + v.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (debug.use_default && object === undefined) { - return new Date(0).toISOString().split('.')[0]; + if (debug.use_default && object === undefined) { + return 0; + } + v.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); + return parseInt(object); } +}; - _SerializerValidation2.default.required(object); - - if (typeof object === 'string') { - return object; - } +Types.int64 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readInt64(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + b.writeInt64(v.to_long(object)); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + return v.to_long(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (object.getTime) { - return object.toISOString().split('.')[0]; + if (debug.use_default && object === undefined) { + return "0"; + } + v.required(object); + return v.to_long(object).toString(); } - - var int = parseInt(object, 10); - _SerializerValidation2.default.require_range(0, 0xffffffff, int, 'uint32 ' + object); - return new Date(int * 1000).toISOString().split('.')[0]; - } }; -Types.set = function (st_operation) { - var set_object = { - validate: function validate(array) { - var dup_map = {}; - - for (var i = 0, len = array.length; i < len; i++) { - var o = array[i]; - var ref = typeof o === 'undefined' ? 'undefined' : _typeof(o); - - if (['string', 'number'].indexOf(ref) >= 0) { - if (dup_map[o] !== undefined) { - throw new Error('duplicate (set)'); - } +Types.uint64 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint64(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + b.writeUint64(v.to_ulong(v.unsigned(object))); + return; + }, + fromObject: function fromObject(object) { + return v.to_ulong(v.unsigned(object)); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - dup_map[o] = true; + if (debug.use_default && object === undefined) { + return "0"; } - } + return v.to_ulong(object).toString(); + } +}; - return sortOperation(array, st_operation); - }, +Types.string = { fromByteBuffer: function fromByteBuffer(b) { - var size = b.readVarint32(); + var b_copy; + var len = b.readVarint32(); + b_copy = b.copy(b.offset, b.offset + len), b.skip(len); + return new Buffer(b_copy.toBinary(), 'binary'); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + b.writeVarint32(object.length); + b.append(object.toString('binary'), 'binary'); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + return new Buffer(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (HEX_DUMP) { - console.log('varint32 size = ' + size.toString(16)); - } + if (debug.use_default && object === undefined) { + return ""; + } + return object.toString(); + } +}; - return this.validate(function () { - var result = []; +Types.bytes = function (size) { + return { + fromByteBuffer: function fromByteBuffer(b) { + if (size === undefined) { + var b_copy; + var len = b.readVarint32(); + b_copy = b.copy(b.offset, b.offset + len), b.skip(len); + return new Buffer(b_copy.toBinary(), 'binary'); + } else { + b_copy = b.copy(b.offset, b.offset + size), b.skip(size); + return new Buffer(b_copy.toBinary(), 'binary'); + } + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + if (typeof object === "string") object = new Buffer(object, "hex"); - for (var i = 0; size > 0 ? i < size : i > size; size > 0 ? i++ : i++) { - result.push(st_operation.fromByteBuffer(b)); + if (size === undefined) { + b.writeVarint32(object.length); + } + b.append(object.toString('binary'), 'binary'); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + if (Buffer.isBuffer(object)) return object; + + return new Buffer(object, 'hex'); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + var zeros = function zeros(num) { + return new Array(num).join("00"); + }; + return zeros(size); + } + v.required(object); + return object.toString('hex'); } + }; +}; - return result; - }()); +Types.bool = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint8() === 1; }, appendByteBuffer: function appendByteBuffer(b, object) { - if (!object) { - object = []; - } - - b.writeVarint32(object.length); - var iterable = this.validate(object); - - for (var i = 0, len = iterable.length; i < len; i++) { - var o = iterable[i]; - st_operation.appendByteBuffer(b, o); - } + // supports boolean or integer + b.writeUint8(JSON.parse(object) ? 1 : 0); + return; }, fromObject: function fromObject(object) { - if (!object) { - object = []; - } - - return this.validate(function () { - var result = []; - - for (var i = 0, len = object.length; i < len; i++) { - var o = object[i]; - result.push(st_operation.fromObject(o)); - } - - return result; - }()); + return JSON.parse(object) ? true : false; }, toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return [st_operation.toObject(object, debug)]; - } - - if (!object) { - object = []; - } - - var result = []; - - for (var i = 0, len = object.length; i < len; i++) { - var o = object[i]; - result.push(st_operation.toObject(o, debug)); - } + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - return this.validate(result); + if (debug.use_default && object === undefined) { + return false; + } + return JSON.parse(object) ? true : false; } - }; - - return set_object; }; -Types.fixed_array = function (count, st_operation) { - var fixed_array = { +Types.void = { fromByteBuffer: function fromByteBuffer(b) { - var results = []; - - for (var i = 0, ref = count; i < ref; i++) { - results.push(st_operation.fromByteBuffer(b)); - } - - return sortOperation(results, st_operation); + throw new Error("(void) undefined type"); }, appendByteBuffer: function appendByteBuffer(b, object) { - if (count !== 0) { - _SerializerValidation2.default.required(object); - object = sortOperation(object, st_operation); - } - - for (var i = 0, ref = count; i < ref; i++) { - st_operation.appendByteBuffer(b, object[i]); - } + throw new Error("(void) undefined type"); }, fromObject: function fromObject(object) { - if (count !== 0) { - _SerializerValidation2.default.required(object); - } - - var results = []; - - for (var i = 0, ref = count; i < ref; i++) { - results.push(st_operation.fromObject(object[i])); - } - - return results; + throw new Error("(void) undefined type"); }, - toObject: function toObject(object, debug) { - if (debug == null) { - debug = {}; - } - - var results = void 0; - - if (debug.use_default && object === undefined) { - results = []; + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - for (var i = 0, ref = count; i < ref; i++) { - results.push(st_operation.toObject(undefined, debug)); + if (debug.use_default && object === undefined) { + return undefined; } + throw new Error("(void) undefined type"); + } +}; - return results; - } - - if (count !== 0) { - _SerializerValidation2.default.required(object); - } - - results = []; - - for (var _i = 0, _ref = count; _i < _ref; _i++) { - results.push(st_operation.toObject(object[_i], debug)); - } +Types.array = function (st_operation) { + return { + fromByteBuffer: function fromByteBuffer(b) { + var size = b.readVarint32(); + if (HEX_DUMP) { + console.log("varint32 size = " + size.toString(16)); + } + var result = []; + for (var i = 0; 0 < size ? i < size : i > size; 0 < size ? i++ : i++) { + result.push(st_operation.fromByteBuffer(b)); + } + return sortOperation(result, st_operation); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + object = sortOperation(object, st_operation); + b.writeVarint32(object.length); + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + st_operation.appendByteBuffer(b, o); + } + }, + fromObject: function fromObject(object) { + v.required(object); + object = sortOperation(object, st_operation); + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push(st_operation.fromObject(o)); + } + return result; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - return results; - } - }; + if (debug.use_default && object === undefined) { + return [st_operation.toObject(object, debug)]; + } + v.required(object); + object = sortOperation(object, st_operation); - return fixed_array; + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push(st_operation.toObject(o, debug)); + } + return result; + } + }; }; -/* Supports instance numbers (11) or object types (1.2.11). Object type -Validation is enforced when an object type is used. */ -Types.id_type = function (reserved_spaces, object_type) { - _SerializerValidation2.default.required(reserved_spaces, 'reserved_spaces'); - _SerializerValidation2.default.required(object_type, 'object_type'); - - var id_type_object = { +Types.time_point_sec = { fromByteBuffer: function fromByteBuffer(b) { - return b.readVarint32(); + return b.readUint32(); }, appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - - if (object.resolve !== undefined) { - object = object.resolve; - } - - // convert 1.2.n into just n - if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { - object = _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object); - } + if (typeof object !== "number") object = Types.time_point_sec.fromObject(object); - b.writeVarint32(_SerializerValidation2.default.to_number(object)); + b.writeUint32(object); + return; }, fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); + v.required(object); - if (object.resolve !== undefined) { - object = object.resolve; - } + if (typeof object === "number") return object; - if (_SerializerValidation2.default.is_digits(object)) { - return _SerializerValidation2.default.to_number(object); - } + if (object.getTime) return Math.floor(object.getTime() / 1000); - return _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object); + if (typeof object !== "string") throw new Error("Unknown date type: " + object); + + // if(typeof object === "string" && !/Z$/.test(object)) + // object = object + "Z" + + return Math.floor(new Date(object).getTime() / 1000); }, toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var object_type_id = _ChainTypes2.default.object_type[object_type]; - - if (debug.use_default && object === undefined) { - return reserved_spaces + '.' + object_type_id + '.0'; - } + if (debug.use_default && object === undefined) return new Date(0).toISOString().split('.')[0]; - _SerializerValidation2.default.required(object); + v.required(object); - if (object.resolve !== undefined) { - object = object.resolve; - } + if (typeof object === "string") return object; - if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { - object = _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object); - } + if (object.getTime) return object.toISOString().split('.')[0]; - return reserved_spaces + '.' + object_type_id + '.' + object; + var int = parseInt(object); + v.require_range(0, 0xFFFFFFFF, int, 'uint32 ' + object); + return new Date(int * 1000).toISOString().split('.')[0]; } - }; - - return id_type_object; }; -Types.protocol_id_type = function (name) { - _SerializerValidation2.default.required(name, 'name'); - return Types.id_type(_ChainTypes2.default.reserved_spaces.protocol_ids, name); -}; - -Types.implementation_id_type = function (name) { - var result = Types.id_type(_ChainTypes2.default.reserved_spaces.implementation_ids, name); - return result; +Types.set = function (st_operation) { + return { + validate: function validate(array) { + var dup_map = {}; + for (var i = 0, o; i < array.length; i++) { + o = array[i]; + var ref; + if (ref = typeof o === 'undefined' ? 'undefined' : _typeof(o), ['string', 'number'].indexOf(ref) >= 0) { + if (dup_map[o] !== undefined) { + throw new Error("duplicate (set)"); + } + dup_map[o] = true; + } + } + return sortOperation(array, st_operation); + }, + fromByteBuffer: function fromByteBuffer(b) { + var size = b.readVarint32(); + if (HEX_DUMP) { + console.log("varint32 size = " + size.toString(16)); + } + return this.validate(function () { + var result = []; + for (var i = 0; 0 < size ? i < size : i > size; 0 < size ? i++ : i++) { + result.push(st_operation.fromByteBuffer(b)); + } + return result; + }()); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (!object) { + object = []; + } + b.writeVarint32(object.length); + var iterable = this.validate(object); + for (var i = 0, o; i < iterable.length; i++) { + o = iterable[i]; + st_operation.appendByteBuffer(b, o); + } + return; + }, + fromObject: function fromObject(object) { + if (!object) { + object = []; + } + return this.validate(function () { + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push(st_operation.fromObject(o)); + } + return result; + }()); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [st_operation.toObject(object, debug)]; + } + if (!object) { + object = []; + } + return this.validate(function () { + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push(st_operation.toObject(o, debug)); + } + return result; + }()); + } + }; }; -Types.object_id_type = { - fromByteBuffer: function fromByteBuffer(b) { - return _ObjectId2.default.fromByteBuffer(b); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - - if (object.resolve !== undefined) { - object = object.resolve; - } - - object = _ObjectId2.default.fromString(object); - object.appendByteBuffer(b); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - - if (object.resolve !== undefined) { - object = object.resolve; - } - - return _ObjectId2.default.fromString(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return '0.0.0'; - } - - _SerializerValidation2.default.required(object); - - if (object.resolve !== undefined) { - object = object.resolve; - } - - object = _ObjectId2.default.fromString(object); - return object.toString(); - } +// global_parameters_update_operation current_fees +Types.fixed_array = function (count, st_operation) { + return { + fromByteBuffer: function fromByteBuffer(b) { + var i, j, ref, results; + results = []; + for (i = j = 0, ref = count; j < ref; i = j += 1) { + results.push(st_operation.fromByteBuffer(b)); + } + return sortOperation(results, st_operation); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + var i, j, ref; + if (count !== 0) { + v.required(object); + object = sortOperation(object, st_operation); + } + for (i = j = 0, ref = count; j < ref; i = j += 1) { + st_operation.appendByteBuffer(b, object[i]); + } + }, + fromObject: function fromObject(object) { + var i, j, ref, results; + if (count !== 0) { + v.required(object); + } + results = []; + for (i = j = 0, ref = count; j < ref; i = j += 1) { + results.push(st_operation.fromObject(object[i])); + } + return results; + }, + toObject: function toObject(object, debug) { + var i, j, k, ref, ref1, results, results1; + if (debug == null) { + debug = {}; + } + if (debug.use_default && object === void 0) { + results = []; + for (i = j = 0, ref = count; j < ref; i = j += 1) { + results.push(st_operation.toObject(void 0, debug)); + } + return results; + } + if (count !== 0) { + v.required(object); + } + results1 = []; + for (i = k = 0, ref1 = count; k < ref1; i = k += 1) { + results1.push(st_operation.toObject(object[i], debug)); + } + return results1; + } + }; }; -Types.vote_id = { - TYPE: 0x000000ff, - ID: 0xffffff00, - fromByteBuffer: function fromByteBuffer(b) { - var value = b.readUint32(); +/* Supports instance numbers (11) or object types (1.2.11). Object type +Validation is enforced when an object type is used. */ +var id_type = function id_type(reserved_spaces, object_type) { + v.required(reserved_spaces, "reserved_spaces"); + v.required(object_type, "object_type"); return { - type: value & this.TYPE, // eslint-disable-line - id: value & this.ID // eslint-disable-line - }; - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - - if (object === 'string') { - object = Types.vote_id.fromObject(object); - } - - var value = object.id << 8 | object.type; // eslint-disable-line - b.writeUint32(value); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object, '(type vote_id)'); - - if ((typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object') { - _SerializerValidation2.default.required(object.type, 'type'); - _SerializerValidation2.default.required(object.id, 'id'); - return object; - } - - _SerializerValidation2.default.require_test(/^[0-9]+:[0-9]+$/, object, 'vote_id format ' + object); - - var _object$split = object.split(':'), - type = _object$split[0], - id = _object$split[1]; - - _SerializerValidation2.default.require_range(0, 0xff, type, 'vote type ' + object); - _SerializerValidation2.default.require_range(0, 0xffffff, id, 'vote id ' + object); - return { type: type, id: id }; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return '0:0'; - } - - _SerializerValidation2.default.required(object); - - if (typeof object === 'string') { - object = Types.vote_id.fromObject(object); - } - - return object.type + ':' + object.id; - }, - compare: function compare(a, b) { - if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) !== 'object') { - a = Types.vote_id.fromObject(a); - } + fromByteBuffer: function fromByteBuffer(b) { + return b.readVarint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + // convert 1.2.n into just n + if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { + object = v.get_instance(reserved_spaces, object_type, object); + } + b.writeVarint32(v.to_number(object)); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + if (v.is_digits(object)) { + return v.to_number(object); + } + return v.get_instance(reserved_spaces, object_type, object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var object_type_id = ChainTypes.object_type[object_type]; + if (debug.use_default && object === undefined) { + return reserved_spaces + '.' + object_type_id + '.0'; + } + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { + object = v.get_instance(reserved_spaces, object_type, object); + } - if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) !== 'object') { - b = Types.vote_id.fromObject(b); - } + return reserved_spaces + '.' + object_type_id + '.' + object; + } + }; +}; - return parseInt(a.id, 10) - parseInt(b.id, 10); - } +Types.protocol_id_type = function (name) { + v.required(name, "name"); + return id_type(ChainTypes.reserved_spaces.protocol_ids, name); }; -Types.optional = function (st_operation) { - _SerializerValidation2.default.required(st_operation, 'st_operation'); - return { +Types.object_id_type = { fromByteBuffer: function fromByteBuffer(b) { - if (!(b.readUint8() === 1)) { - return undefined; - } - - return st_operation.fromByteBuffer(b); + return ObjectId.fromByteBuffer(b); }, appendByteBuffer: function appendByteBuffer(b, object) { - if (object !== null && object !== undefined) { - b.writeUint8(1); - st_operation.appendByteBuffer(b, object); - } else { - b.writeUint8(0); - } + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + object = ObjectId.fromString(object); + object.appendByteBuffer(b); + return; }, fromObject: function fromObject(object) { - if (object === undefined) { - return undefined; - } - - return st_operation.fromObject(object); + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + return ObjectId.fromString(object); }, toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - // toObject is only null save if use_default is true - var result_object = function () { - if (!debug.use_default && object === undefined) { - return undefined; + if (debug.use_default && object === undefined) { + return "0.0.0"; } - - return st_operation.toObject(object, debug); - }(); - - if (debug.annotate) { - if ((typeof result_object === 'undefined' ? 'undefined' : _typeof(result_object)) === 'object') { - result_object.__optional = 'parent is optional'; - } else { - result_object = { __optional: result_object }; + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; } - } - - return result_object; + object = ObjectId.fromString(object); + return object.toString(); } - }; }; -Types.static_variant = function (_st_operations) { - var static_variant = { - nosort: true, - st_operations: _st_operations, +Types.vote_id = { TYPE: 0x000000FF, + ID: 0xFFFFFF00, fromByteBuffer: function fromByteBuffer(b) { - var type_id = b.readVarint32(); - var st_operation = this.st_operations[type_id]; - - if (HEX_DUMP) { - console.error('static_variant id 0x' + type_id.toString(16) + ' (' + type_id + ')'); - } - - _SerializerValidation2.default.required(st_operation, 'operation ' + type_id); - return [type_id, st_operation.fromByteBuffer(b)]; + var value = b.readUint32(); + return { + type: value & this.TYPE, + id: value & this.ID + }; }, appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - var type_id = object[0]; - var st_operation = this.st_operations[type_id]; - _SerializerValidation2.default.required(st_operation, 'operation ' + type_id); - b.writeVarint32(type_id); - st_operation.appendByteBuffer(b, object[1]); + v.required(object); + if (object === "string") object = Types.vote_id.fromObject(object); + + var value = object.id << 8 | object.type; + b.writeUint32(value); + return; }, fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - var type_id = object[0]; - var st_operation = this.st_operations[type_id]; + v.required(object, "(type vote_id)"); + if ((typeof object === 'undefined' ? 'undefined' : _typeof(object)) === "object") { + v.required(object.type, "type"); + v.required(object.id, "id"); + return object; + } + v.require_test(/^[0-9]+:[0-9]+$/, object, 'vote_id format ' + object); - _SerializerValidation2.default.required(st_operation, 'operation ' + type_id); - return [type_id, st_operation.fromObject(object[1])]; + var _object$split = object.split(':'), + _object$split2 = _slicedToArray(_object$split, 2), + type = _object$split2[0], + id = _object$split2[1]; + + v.require_range(0, 0xff, type, 'vote type ' + object); + v.require_range(0, 0xffffff, id, 'vote id ' + object); + return { type: type, id: id }; }, toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (debug.use_default && object === undefined) { - return [0, this.st_operations[0].toObject(undefined, debug)]; - } + if (debug.use_default && object === undefined) { + return "0:0"; + } + v.required(object); + if (typeof object === "string") object = Types.vote_id.fromObject(object); - _SerializerValidation2.default.required(object); - var type_id = object[0]; - var st_operation = this.st_operations[type_id]; - _SerializerValidation2.default.required(st_operation, 'operation ' + type_id); - return [type_id, st_operation.toObject(object[1], debug)]; + return object.type + ":" + object.id; + }, + compare: function compare(a, b) { + if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) !== "object") a = Types.vote_id.fromObject(a); + if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) !== "object") b = Types.vote_id.fromObject(b); + return parseInt(a.id) - parseInt(b.id); } - }; - - return static_variant; }; -Types.map = function (key_st_operation, value_st_operation) { - var map_object = { - validate: function validate(array) { - if (!Array.isArray(array)) { - throw new Error('expecting array'); - } +Types.optional = function (st_operation) { + v.required(st_operation, "st_operation"); + return { + fromByteBuffer: function fromByteBuffer(b) { + if (!(b.readUint8() === 1)) { + return undefined; + } + return st_operation.fromByteBuffer(b); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (object !== null && object !== undefined) { + b.writeUint8(1); + st_operation.appendByteBuffer(b, object); + } else { + b.writeUint8(0); + } + return; + }, + fromObject: function fromObject(object) { + if (object === undefined) { + return undefined; + } + return st_operation.fromObject(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + // toObject is only null save if use_default is true + var result_object = function () { + if (!debug.use_default && object === undefined) { + return undefined; + } else { + return st_operation.toObject(object, debug); + } + }(); + + if (debug.annotate) { + if ((typeof result_object === 'undefined' ? 'undefined' : _typeof(result_object)) === "object") { + result_object.__optional = "parent is optional"; + } else { + result_object = { __optional: result_object }; + } + } + return result_object; + } + }; +}; - var dup_map = {}; +Types.static_variant = function (_st_operations) { + return { + nosort: true, + st_operations: _st_operations, + fromByteBuffer: function fromByteBuffer(b) { + var type_id = b.readVarint32(); + var st_operation = this.st_operations[type_id]; + if (HEX_DUMP) { + console.error('static_variant id 0x' + type_id.toString(16) + ' (' + type_id + ')'); + } + v.required(st_operation, 'operation ' + type_id); + return [type_id, st_operation.fromByteBuffer(b)]; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + var type_id = object[0]; + var st_operation = this.st_operations[type_id]; + v.required(st_operation, 'operation ' + type_id); + b.writeVarint32(type_id); + st_operation.appendByteBuffer(b, object[1]); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + var type_id = object[0]; + var st_operation = this.st_operations[type_id]; + v.required(st_operation, 'operation ' + type_id); + return [type_id, st_operation.fromObject(object[1])]; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [0, this.st_operations[0].toObject(undefined, debug)]; + } + v.required(object); + var type_id = object[0]; + var st_operation = this.st_operations[type_id]; + v.required(st_operation, 'operation ' + type_id); + return [type_id, st_operation.toObject(object[1], debug)]; + } + }; +}; - for (var i = 0, len = array.length; i < len; i++) { - var o = array[i]; - var ref = void 0; +Types.map = function (key_st_operation, value_st_operation) { + return { + validate: function validate(array) { + if (!Array.isArray(array)) { + throw new Error("expecting array"); + } + var dup_map = {}; + for (var i = 0, o; i < array.length; i++) { + o = array[i]; + var ref; + if (!(o.length === 2)) { + throw new Error("expecting two elements"); + } + if (ref = _typeof(o[0]), ['number', 'string'].indexOf(ref) >= 0) { + if (dup_map[o[0]] !== undefined) { + throw new Error("duplicate (map)"); + } + dup_map[o[0]] = true; + } + } + return sortOperation(array, key_st_operation); + }, + fromByteBuffer: function fromByteBuffer(b) { + var result = []; + var end = b.readVarint32(); + for (var i = 0; 0 < end ? i < end : i > end; 0 < end ? i++ : i++) { + result.push([key_st_operation.fromByteBuffer(b), value_st_operation.fromByteBuffer(b)]); + } + return this.validate(result); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + this.validate(object); + b.writeVarint32(object.length); + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + key_st_operation.appendByteBuffer(b, o[0]); + value_st_operation.appendByteBuffer(b, o[1]); + } + return; + }, + fromObject: function fromObject(object) { + v.required(object); + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push([key_st_operation.fromObject(o[0]), value_st_operation.fromObject(o[1])]); + } + return this.validate(result); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (!(o.length === 2)) { - throw new Error('expecting two elements'); + if (debug.use_default && object === undefined) { + return [[key_st_operation.toObject(undefined, debug), value_st_operation.toObject(undefined, debug)]]; + } + v.required(object); + object = this.validate(object); + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push([key_st_operation.toObject(o[0], debug), value_st_operation.toObject(o[1], debug)]); + } + return result; } + }; +}; - ref = _typeof(o[0]); - - if (ref && ['number', 'string'].indexOf(ref) >= 0) { - if (dup_map[o[0]] !== undefined) { - throw new Error('duplicate (map)'); - } +Types.public_key = { + toPublic: function toPublic(object) { + if (object.resolve !== undefined) { + object = object.resolve; + } - dup_map[o[0]] = true; + if (object instanceof PublicKey) { + return object; } - } - return sortOperation(array, key_st_operation); + return object == null ? object : object.Q ? object : PublicKey.fromStringOrThrow(object); }, fromByteBuffer: function fromByteBuffer(b) { - var result = []; - var end = b.readVarint32(); - - for (var i = 0; end > 0 ? i < end : i > end; end > 0 ? i++ : i++) { - result.push([key_st_operation.fromByteBuffer(b), value_st_operation.fromByteBuffer(b)]); - } - - return this.validate(result); + return fp.public_key(b); }, appendByteBuffer: function appendByteBuffer(b, object) { - this.validate(object); - b.writeVarint32(object.length); - - for (var i = 0, len = object.length; i < len; i++) { - var o = object[i]; - key_st_operation.appendByteBuffer(b, o[0]); - value_st_operation.appendByteBuffer(b, o[1]); - } + v.required(object); + fp.public_key(b, Types.public_key.toPublic(object)); + return; }, fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - var result = []; - - for (var i = 0, len = object.length; i < len; i++) { - var o = object[i]; - result.push([key_st_operation.fromObject(o[0]), value_st_operation.fromObject(o[1])]); - } - - return this.validate(result); + v.required(object); + if (object.Q) { + return object; + } + return Types.public_key.toPublic(object); }, toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return [[key_st_operation.toObject(undefined, debug), value_st_operation.toObject(undefined, debug)]]; - } - - _SerializerValidation2.default.required(object); - object = this.validate(object); - var result = []; + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - for (var i = 0, len = object.length; i < len; i++) { - var o = object[i]; - result.push([key_st_operation.toObject(o[0], debug), value_st_operation.toObject(o[1], debug)]); - } - - return result; - } - }; - - return map_object; -}; - -Types.public_key = { - toPublic: function toPublic(object) { - if (object.resolve !== undefined) { - object = object.resolve; - } - - if (object instanceof _ecc.PublicKey) { - return object; - } - - var result = object; - - if (!object) { - return null; - } - - if (!object.Q) { - result = _ecc.PublicKey.fromStringOrThrow(object); - } - - return result; - }, - fromByteBuffer: function fromByteBuffer(b) { - return _FastParser2.default.public_key(b); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - _FastParser2.default.public_key(b, Types.public_key.toPublic(object)); - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - - if (object.Q) { - return object; - } - - return Types.public_key.toPublic(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return _peerplaysjsWs.ChainConfig.address_prefix + '859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2HqhToVM'; + if (debug.use_default && object === undefined) { + return ChainConfig.address_prefix + "859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2HqhToVM"; + } + v.required(object); + return object.toString(); + }, + compare: function compare(a, b) { + return strCmp(a.toAddressString(), b.toAddressString()); } - - _SerializerValidation2.default.required(object); - return object.toString(); - }, - compare: function compare(a, b) { - return strCmp(a.toAddressString(), b.toAddressString()); - } }; Types.address = { - _to_address: function _to_address(object) { - _SerializerValidation2.default.required(object); - - if (object.addy) { - return object; - } - - return _ecc.Address.fromString(object); - }, - fromByteBuffer: function fromByteBuffer(b) { - return new _ecc.Address(_FastParser2.default.ripemd160(b)); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _FastParser2.default.ripemd160(b, Types.address._to_address(object).toBuffer()); - }, - fromObject: function fromObject(object) { - return Types.address._to_address(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + _to_address: function _to_address(object) { + v.required(object); + if (object.addy) { + return object; + } + return Address.fromString(object); + }, + fromByteBuffer: function fromByteBuffer(b) { + return new Address(fp.ripemd160(b)); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + fp.ripemd160(b, Types.address._to_address(object).toBuffer()); + return; + }, + fromObject: function fromObject(object) { + return Types.address._to_address(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (debug.use_default && object === undefined) { - return _peerplaysjsWs.ChainConfig.address_prefix + '664KmHxSuQyDsfwo4WEJvWpzg1QKdg67S'; + if (debug.use_default && object === undefined) { + return ChainConfig.address_prefix + "664KmHxSuQyDsfwo4WEJvWpzg1QKdg67S"; + } + return Types.address._to_address(object).toString(); + }, + compare: function compare(a, b) { + return strCmp(a.toString(), b.toString()); } - - return Types.address._to_address(object).toString(); - }, - compare: function compare(a, b) { - return strCmp(a.toString(), b.toString()); - } }; Types.variant = { - fromByteBuffer: function fromByteBuffer(b) { - var type = b.readUint8(); - - switch (type) { - case 0: - return null; - case 1: - return Types.int64.fromByteBuffer(b); - case 2: - return Types.uint64.fromByteBuffer(b); - case 3: - return b.readDouble(); - case 4: - return Types.bool.fromByteBuffer(b); - case 5: - return Types.string.fromByteBuffer(b); - case 6: - return Types.array(Types.variant).fromByteBuffer(b); - case 7: - default: - return Types.variant_object.fromByteBuffer(b); - } - }, - appendByteBuffer: function appendByteBuffer(b, object) { - if (typeof object === 'number') { - if (Number.isInteger(object)) { - if (object >= 0) { - b.writeUint8(2); - Types.uint64.appendByteBuffer(b, object); + fromByteBuffer: function fromByteBuffer(b) { + var type = b.readUint8(); + switch (type) { + case 0: + return null; + case 1: + return Types.int64.fromByteBuffer(b); + case 2: + return Types.uint64.fromByteBuffer(b); + case 3: + return b.readDouble(); + case 4: + return Types.bool.fromByteBuffer(b); + case 5: + return Types.string.fromByteBuffer(b); + case 6: + return Types.array(Types.variant).fromByteBuffer(b); + case 7: + default: + return Types.variant_object.fromByteBuffer(b); + }; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (typeof object == 'number') { + if (Number.isInteger(object)) { + if (object >= 0) { + b.writeUint8(2); + Types.uint64.appendByteBuffer(b, object); + } else { + b.writeUint8(1); + Types.int64.appendByteBuffer(b, object); + } + } else { + b.writeUint8(3); + b.writeDouble(Number.parseFloat(object)); + } + } else if (typeof object == 'boolean') { + b.writeUint8(4); + Types.bool.appendByteBuffer(b, object); + } else if (typeof object == 'string') { + b.writeUint8(5); + Types.string.appendByteBuffer(b, object); + } else if (typeof object == 'array') { + b.writeUint8(6); + Types.array(Types.variant).appendByteBuffer(b, object); } else { - b.writeUint8(1); - Types.int64.appendByteBuffer(b, object); + b.writeUint8(7); + Types.variant_object.appendByteBuffer(b, object); } - } else { - b.writeUint8(3); - b.writeDouble(Number.parseFloat(object)); - } - } else if (typeof object === 'boolean') { - b.writeUint8(4); - Types.bool.appendByteBuffer(b, object); - } else if (typeof object === 'string') { - b.writeUint8(5); - Types.string.appendByteBuffer(b, object); - } else if (Array.isArray(object)) { - b.writeUint8(6); - Types.array(Types.variant).appendByteBuffer(b, object); - } else { - b.writeUint8(7); - Types.variant_object.appendByteBuffer(b, object); - } - }, - fromObject: function fromObject(object) { - return JSON.parse(object); - }, - toObject: function toObject(object) { - return JSON.parse(object); - } -}; - -Types.variant_object = { - fromByteBuffer: function fromByteBuffer(b) { - var count = b.readVarint32(); - var result = {}; - - for (var i = 0; i < count; ++i) { - var key = Types.string.fromByteBuffer(b); - result[key] = Types.variant.fromByteBuffer(b); - } - - return result; - }, - appendByteBuffer: function appendByteBuffer(b, object) { - var keys = Object.keys(object); - - b.writeVarint32(keys.length); // number of key/value pairs - - for (var i = 0, len = keys.length; i < len; i++) { - var key = keys[i]; - Types.string.appendByteBuffer(b, key); - Types.variant.appendByteBuffer(b, object[key]); - } - }, - fromObject: function fromObject(object) { - var newObject = {}; - - var keys = Object.keys(object); - - for (var i = 0, len = keys.length; i < len; i++) { - var key = keys[i]; - newObject[key] = object[key]; - } - - return newObject; - }, - toObject: function toObject(object) { - var newObject = {}; - - var keys = Object.keys(object); + }, + fromObject: function fromObject(object) { + return JSON.parse(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - for (var i = 0, len = keys.length; i < len; i++) { - var key = keys[i]; - newObject[key] = object[key]; + if (debug.use_default && object === undefined) { + return null; + } + return JSON.parse(object); } - - return newObject; - } }; -Types.enumeration = function (values) { - var enumeration = { +Types.variant_object = { fromByteBuffer: function fromByteBuffer(b) { - return values[b.readVarint32ZigZag()]; + var count = b.readVarint32(); + var result = {}; + for (var i = 0; i < count; ++i) { + var key = Types.string.fromByteBuffer(b); + result[key] = Types.variant.fromByteBuffer(b); + } + return result; }, appendByteBuffer: function appendByteBuffer(b, object) { - b.writeVarint32ZigZag(values.indexOf(object)); + var count = 0; + for (var key in object) { + if (object.hasOwnProperty(key)) ++count; + }b.writeVarint32(count); // number of key/value pairs + for (var key in object) { + if (object.hasOwnProperty(key)) { + Types.string.appendByteBuffer(b, key); + Types.variant.appendByteBuffer(b, object[key]); + } + }return; }, fromObject: function fromObject(object) { - return object; + var newObject = {}; + for (var key in object) { + if (object.hasOwnProperty(key)) newObject[key] = object[key]; + }return newObject; }, toObject: function toObject(object) { - return object; + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var newObject = {}; + for (var key in object) { + if (object.hasOwnProperty(key)) newObject[key] = object[key]; + }return newObject; } - }; +}; - return enumeration; +Types.enumeration = function (values) { + return { + fromByteBuffer: function fromByteBuffer(b) { + return values[b.readVarint32ZigZag()]; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + b.writeVarint32ZigZag(values.indexOf(object)); + return; + }, + fromObject: function fromObject(object) { + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + values[0]; + } + return object; + } + }; }; Types.sha256 = Types.bytes(32); -exports.default = Types; -module.exports = exports['default']; -}).call(this,require(77),require(35).Buffer) +var strCmp = function strCmp(a, b) { + return a > b ? 1 : a < b ? -1 : 0; +}; +var firstEl = function firstEl(el) { + return Array.isArray(el) ? el[0] : el; +}; +var sortOperation = function sortOperation(array, st_operation) { + return st_operation.nosort ? array : st_operation.compare ? array.sort(function (a, b) { + return st_operation.compare(firstEl(a), firstEl(b)); + }) : // custom compare operation + array.sort(function (a, b) { + return typeof firstEl(a) === "number" && typeof firstEl(b) === "number" ? firstEl(a) - firstEl(b) : + // A binary string compare does not work. Performanance is very good so HEX is used.. localeCompare is another option. + Buffer.isBuffer(firstEl(a)) && Buffer.isBuffer(firstEl(b)) ? strCmp(firstEl(a).toString("hex"), firstEl(b).toString("hex")) : strCmp(firstEl(a).toString(), firstEl(b).toString()); + }); +}; +}).call(this,require('_process'),require("buffer").Buffer) -},{"20":20,"21":21,"3":3,"35":35,"4":4,"7":7,"70":70,"77":77}],27:[function(require,module,exports){ +},{"../../chain/src/ChainTypes":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/chain/src/ChainTypes.js","../../chain/src/ObjectId":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/chain/src/ObjectId.js","../../ecc":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/index.js","./FastParser":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/FastParser.js","./SerializerValidation":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/SerializerValidation.js","_process":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process/browser.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","peerplaysjs-ws":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js":[function(require,module,exports){ (function (global){ 'use strict'; @@ -6699,7 +5265,7 @@ function isBuffer(b) { // 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. -var util = require(108); +var util = require('util/'); var hasOwn = Object.prototype.hasOwnProperty; var pSlice = Array.prototype.slice; var functionsHaveNames = (function () { @@ -7124,7 +5690,7 @@ var objectKeys = Object.keys || function (obj) { }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"108":108}],28:[function(require,module,exports){ +},{"util/":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/util/util.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/base-x/index.js":[function(require,module,exports){ // base-x encoding // Forked from https://github.com/cryptocoinjs/bs58 // Originally written by Mike Hearn for BitcoinJ @@ -7212,7 +5778,7 @@ module.exports = function base (ALPHABET) { } } -},{}],29:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/base64-js/index.js":[function(require,module,exports){ 'use strict' exports.byteLength = byteLength @@ -7365,7 +5931,7 @@ function fromByteArray (uint8) { return parts.join('') } -},{}],30:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/bigi.js":[function(require,module,exports){ // (public) Constructor function BigInteger(a, b, c) { if (!(this instanceof BigInteger)) @@ -7381,7 +5947,7 @@ function BigInteger(a, b, c) { var proto = BigInteger.prototype // duck-typed isBigInteger -proto.__bigi = require(33).version +proto.__bigi = require('../package.json').version BigInteger.isBigInteger = function (obj, check_ver) { return obj && obj.__bigi && (!check_ver || obj.__bigi === proto.__bigi) } @@ -8876,11 +7442,11 @@ BigInteger.valueOf = nbv module.exports = BigInteger -},{"33":33}],31:[function(require,module,exports){ +},{"../package.json":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/package.json"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/convert.js":[function(require,module,exports){ (function (Buffer){ // FIXME: Kind of a weird way to throw exceptions, consider removing -var assert = require(27) -var BigInteger = require(30) +var assert = require('assert') +var BigInteger = require('./bigi') /** * Turns a byte array into a big integer. @@ -8970,17 +7536,41 @@ BigInteger.prototype.toHex = function(size) { return this.toBuffer(size).toString('hex') } -}).call(this,require(35).Buffer) +}).call(this,require("buffer").Buffer) -},{"27":27,"30":30,"35":35}],32:[function(require,module,exports){ -var BigInteger = require(30) +},{"./bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/bigi.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/index.js":[function(require,module,exports){ +var BigInteger = require('./bigi') //addons -require(31) +require('./convert') module.exports = BigInteger -},{"30":30,"31":31}],33:[function(require,module,exports){ +},{"./bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/bigi.js","./convert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/convert.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/package.json":[function(require,module,exports){ module.exports={ + "_from": "bigi@^1.4.1", + "_id": "bigi@1.4.2", + "_inBundle": false, + "_integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU=", + "_location": "/peerplaysjs-lib/bigi", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "bigi@^1.4.1", + "name": "bigi", + "escapedName": "bigi", + "rawSpec": "^1.4.1", + "saveSpec": null, + "fetchSpec": "^1.4.1" + }, + "_requiredBy": [ + "/peerplaysjs-lib", + "/peerplaysjs-lib/ecurve" + ], + "_resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz", + "_shasum": "9c665a95f88b8b08fc05cfd731f561859d725825", + "_spec": "bigi@^1.4.1", + "_where": "/Users/mseaward/Documents/code/peerplaysjs-lib", "bugs": { "url": "https://github.com/cryptocoinjs/bigi/issues" }, @@ -9041,9 +7631,10 @@ module.exports={ }, "version": "1.4.2" } -},{}],34:[function(require,module,exports){ -},{}],35:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browser-resolve/empty.js":[function(require,module,exports){ + +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js":[function(require,module,exports){ (function (global){ /*! * The buffer module from node.js, for the browser. @@ -9055,9 +7646,9 @@ module.exports={ 'use strict' -var base64 = require(29) -var ieee754 = require(64) -var isArray = require(67) +var base64 = require('base64-js') +var ieee754 = require('ieee754') +var isArray = require('isarray') exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer @@ -10837,7 +9428,7 @@ function isnan (val) { }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"29":29,"64":64,"67":67}],36:[function(require,module,exports){ +},{"base64-js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/base64-js/index.js","ieee754":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ieee754/index.js","isarray":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/isarray/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/string_decoder/index.js":[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -10859,7 +9450,7 @@ function isnan (val) { // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -var Buffer = require(35).Buffer; +var Buffer = require('buffer').Buffer; var isBufferEncoding = Buffer.isEncoding || function(encoding) { @@ -11060,13 +9651,13 @@ function base64DetectIncompleteChar(buffer) { this.charLength = this.charReceived ? 3 : 0; } -},{"35":35}],37:[function(require,module,exports){ -var basex = require(28) +},{"buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bs58/index.js":[function(require,module,exports){ +var basex = require('base-x') var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' module.exports = basex(ALPHABET) -},{"28":28}],38:[function(require,module,exports){ +},{"base-x":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/base-x/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bytebuffer/dist/bytebuffer.js":[function(require,module,exports){ /* Copyright 2013-2014 Daniel Wirtz @@ -11095,7 +9686,7 @@ module.exports = basex(ALPHABET) define(["long"], factory); /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"]) module['exports'] = (function() { - var Long; try { Long = require(68); } catch (e) {} + var Long; try { Long = require("long"); } catch (e) {} return factory(Long); })(); /* Global */ else @@ -14814,11 +13405,11 @@ module.exports = basex(ALPHABET) return ByteBuffer; }); -},{"68":68}],39:[function(require,module,exports){ -var Buffer = require(93).Buffer -var Transform = require(103).Transform -var StringDecoder = require(36).StringDecoder -var inherits = require(65) +},{"long":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/long/dist/long.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/cipher-base/index.js":[function(require,module,exports){ +var Buffer = require('safe-buffer').Buffer +var Transform = require('stream').Transform +var StringDecoder = require('string_decoder').StringDecoder +var inherits = require('inherits') function CipherBase (hashMode) { Transform.call(this) @@ -14915,7 +13506,7 @@ CipherBase.prototype._toString = function (value, enc, fin) { module.exports = CipherBase -},{"103":103,"36":36,"65":65,"93":93}],40:[function(require,module,exports){ +},{"inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js","stream":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/stream-browserify/index.js","string_decoder":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/string_decoder/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/core-util-is/lib/util.js":[function(require,module,exports){ (function (Buffer){ // Copyright Joyent, Inc. and other Node contributors. // @@ -15025,15 +13616,15 @@ function objectToString(o) { return Object.prototype.toString.call(o); } -}).call(this,{"isBuffer":require(66)}) +}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) -},{"66":66}],41:[function(require,module,exports){ +},{"../../is-buffer/index.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/is-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/create-hash/browser.js":[function(require,module,exports){ 'use strict' -var inherits = require(65) -var MD5 = require(69) -var RIPEMD160 = require(92) -var sha = require(96) -var Base = require(39) +var inherits = require('inherits') +var MD5 = require('md5.js') +var RIPEMD160 = require('ripemd160') +var sha = require('sha.js') +var Base = require('cipher-base') function Hash (hash) { Base.call(this, 'digest') @@ -15059,23 +13650,23 @@ module.exports = function createHash (alg) { return new Hash(sha(alg)) } -},{"39":39,"65":65,"69":69,"92":92,"96":96}],42:[function(require,module,exports){ -var MD5 = require(69) +},{"cipher-base":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/cipher-base/index.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","md5.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/md5.js/index.js","ripemd160":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ripemd160/index.js","sha.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/create-hash/md5.js":[function(require,module,exports){ +var MD5 = require('md5.js') module.exports = function (buffer) { return new MD5().update(buffer).digest() } -},{"69":69}],43:[function(require,module,exports){ +},{"md5.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/md5.js/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/create-hmac/browser.js":[function(require,module,exports){ 'use strict' -var inherits = require(65) -var Legacy = require(44) -var Base = require(39) -var Buffer = require(93).Buffer -var md5 = require(42) -var RIPEMD160 = require(92) +var inherits = require('inherits') +var Legacy = require('./legacy') +var Base = require('cipher-base') +var Buffer = require('safe-buffer').Buffer +var md5 = require('create-hash/md5') +var RIPEMD160 = require('ripemd160') -var sha = require(96) +var sha = require('sha.js') var ZEROS = Buffer.alloc(128) @@ -15130,12 +13721,12 @@ module.exports = function createHmac (alg, key) { return new Hmac(alg, key) } -},{"39":39,"42":42,"44":44,"65":65,"92":92,"93":93,"96":96}],44:[function(require,module,exports){ +},{"./legacy":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/create-hmac/legacy.js","cipher-base":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/cipher-base/index.js","create-hash/md5":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/create-hash/md5.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","ripemd160":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ripemd160/index.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js","sha.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/create-hmac/legacy.js":[function(require,module,exports){ 'use strict' -var inherits = require(65) -var Buffer = require(93).Buffer +var inherits = require('inherits') +var Buffer = require('safe-buffer').Buffer -var Base = require(39) +var Base = require('cipher-base') var ZEROS = Buffer.alloc(128) var blocksize = 64 @@ -15178,11 +13769,11 @@ Hmac.prototype._final = function () { } module.exports = Hmac -},{"39":39,"65":65,"93":93}],45:[function(require,module,exports){ +},{"cipher-base":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/cipher-base/index.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/aes.js":[function(require,module,exports){ ;(function (root, factory, undef) { if (typeof exports === "object") { // CommonJS - module.exports = exports = factory(require(47), require(48), require(52), require(50), require(46)); + module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core")); } else if (typeof define === "function" && define.amd) { // AMD @@ -15411,15 +14002,15 @@ module.exports = Hmac return CryptoJS.AES; })); -},{"46":46,"47":47,"48":48,"50":50,"52":52}],46:[function(require,module,exports){ -;(function (root, factory, undef) { +},{"./cipher-core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/cipher-core.js","./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js","./enc-base64":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/enc-base64.js","./evpkdf":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/evpkdf.js","./md5":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/md5.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/cipher-core.js":[function(require,module,exports){ +;(function (root, factory) { if (typeof exports === "object") { // CommonJS - module.exports = exports = factory(require(47), require(50)); + module.exports = exports = factory(require("./core")); } else if (typeof define === "function" && define.amd) { // AMD - define(["./core", "./evpkdf"], factory); + define(["./core"], factory); } else { // Global (browser) @@ -15880,16 +14471,11 @@ module.exports = Hmac var modeCreator = mode.createEncryptor; } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { var modeCreator = mode.createDecryptor; + // Keep at least one block in the buffer for unpadding this._minBufferSize = 1; } - - if (this._mode && this._mode.__creator == modeCreator) { - this._mode.init(this, iv && iv.words); - } else { - this._mode = modeCreator.call(mode, this, iv && iv.words); - this._mode.__creator = modeCreator; - } + this._mode = modeCreator.call(mode, this, iv && iv.words); }, _doProcessBlock: function (words, offset) { @@ -16292,7 +14878,7 @@ module.exports = Hmac })); -},{"47":47,"50":50}],47:[function(require,module,exports){ +},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js":[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS @@ -17053,11 +15639,11 @@ module.exports = Hmac return CryptoJS; })); -},{}],48:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/enc-base64.js":[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS - module.exports = exports = factory(require(47)); + module.exports = exports = factory(require("./core")); } else if (typeof define === "function" && define.amd) { // AMD @@ -17189,11 +15775,11 @@ module.exports = Hmac return CryptoJS.enc.Base64; })); -},{"47":47}],49:[function(require,module,exports){ +},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/enc-hex.js":[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS - module.exports = exports = factory(require(47)); + module.exports = exports = factory(require("./core")); } else if (typeof define === "function" && define.amd) { // AMD @@ -17208,11 +15794,11 @@ module.exports = Hmac return CryptoJS.enc.Hex; })); -},{"47":47}],50:[function(require,module,exports){ +},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/evpkdf.js":[function(require,module,exports){ ;(function (root, factory, undef) { if (typeof exports === "object") { // CommonJS - module.exports = exports = factory(require(47), require(53), require(51)); + module.exports = exports = factory(require("./core"), require("./sha1"), require("./hmac")); } else if (typeof define === "function" && define.amd) { // AMD @@ -17341,11 +15927,11 @@ module.exports = Hmac return CryptoJS.EvpKDF; })); -},{"47":47,"51":51,"53":53}],51:[function(require,module,exports){ +},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js","./hmac":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/hmac.js","./sha1":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/sha1.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/hmac.js":[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS - module.exports = exports = factory(require(47)); + module.exports = exports = factory(require("./core")); } else if (typeof define === "function" && define.amd) { // AMD @@ -17485,11 +16071,11 @@ module.exports = Hmac })); -},{"47":47}],52:[function(require,module,exports){ +},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/md5.js":[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS - module.exports = exports = factory(require(47)); + module.exports = exports = factory(require("./core")); } else if (typeof define === "function" && define.amd) { // AMD @@ -17754,11 +16340,11 @@ module.exports = Hmac return CryptoJS.MD5; })); -},{"47":47}],53:[function(require,module,exports){ +},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/sha1.js":[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS - module.exports = exports = factory(require(47)); + module.exports = exports = factory(require("./core")); } else if (typeof define === "function" && define.amd) { // AMD @@ -17905,10 +16491,10 @@ module.exports = Hmac return CryptoJS.SHA1; })); -},{"47":47}],54:[function(require,module,exports){ +},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/deep-equal/index.js":[function(require,module,exports){ var pSlice = Array.prototype.slice; -var objectKeys = require(56); -var isArguments = require(55); +var objectKeys = require('./lib/keys.js'); +var isArguments = require('./lib/is_arguments.js'); var deepEqual = module.exports = function (actual, expected, opts) { if (!opts) opts = {}; @@ -18001,7 +16587,7 @@ function objEquiv(a, b, opts) { return typeof a === typeof b; } -},{"55":55,"56":56}],55:[function(require,module,exports){ +},{"./lib/is_arguments.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/deep-equal/lib/is_arguments.js","./lib/keys.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/deep-equal/lib/keys.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/deep-equal/lib/is_arguments.js":[function(require,module,exports){ var supportsArgumentsClass = (function(){ return Object.prototype.toString.call(arguments) })() == '[object Arguments]'; @@ -18023,7 +16609,7 @@ function unsupported(object){ false; }; -},{}],56:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/deep-equal/lib/keys.js":[function(require,module,exports){ exports = module.exports = typeof Object.keys === 'function' ? Object.keys : shim; @@ -18034,11 +16620,11 @@ function shim (obj) { return keys; } -},{}],57:[function(require,module,exports){ -var assert = require(27) -var BigInteger = require(32) +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/curve.js":[function(require,module,exports){ +var assert = require('assert') +var BigInteger = require('bigi') -var Point = require(61) +var Point = require('./point') function Curve (p, a, b, Gx, Gy, n, h) { this.p = p @@ -18113,7 +16699,7 @@ Curve.prototype.validate = function (Q) { module.exports = Curve -},{"27":27,"32":32,"61":61}],58:[function(require,module,exports){ +},{"./point":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/point.js","assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/curves.json":[function(require,module,exports){ module.exports={ "secp128r1": { "p": "fffffffdffffffffffffffffffffffff", @@ -18180,11 +16766,11 @@ module.exports={ } } -},{}],59:[function(require,module,exports){ -var Point = require(61) -var Curve = require(57) +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/index.js":[function(require,module,exports){ +var Point = require('./point') +var Curve = require('./curve') -var getCurveByName = require(60) +var getCurveByName = require('./names') module.exports = { Curve: Curve, @@ -18192,11 +16778,11 @@ module.exports = { getCurveByName: getCurveByName } -},{"57":57,"60":60,"61":61}],60:[function(require,module,exports){ -var BigInteger = require(32) +},{"./curve":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/curve.js","./names":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/names.js","./point":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/point.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/names.js":[function(require,module,exports){ +var BigInteger = require('bigi') -var curves = require(58) -var Curve = require(57) +var curves = require('./curves.json') +var Curve = require('./curve') function getCurveByName (name) { var curve = curves[name] @@ -18215,10 +16801,10 @@ function getCurveByName (name) { module.exports = getCurveByName -},{"32":32,"57":57,"58":58}],61:[function(require,module,exports){ -var assert = require(27) -var Buffer = require(93).Buffer -var BigInteger = require(32) +},{"./curve":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/curve.js","./curves.json":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/curves.json","bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ecurve/lib/point.js":[function(require,module,exports){ +var assert = require('assert') +var Buffer = require('safe-buffer').Buffer +var BigInteger = require('bigi') var THREE = BigInteger.valueOf(3) @@ -18461,7 +17047,7 @@ Point.prototype.toString = function () { module.exports = Point -},{"27":27,"32":32,"93":93}],62:[function(require,module,exports){ +},{"assert":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/assert/assert.js","bigi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/index.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/events/events.js":[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -18765,11 +17351,11 @@ function isUndefined(arg) { return arg === void 0; } -},{}],63:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/hash-base/index.js":[function(require,module,exports){ 'use strict' -var Buffer = require(93).Buffer -var Transform = require(103).Transform -var inherits = require(65) +var Buffer = require('safe-buffer').Buffer +var Transform = require('stream').Transform +var inherits = require('inherits') function throwIfNotStringOrBuffer (val, prefix) { if (!Buffer.isBuffer(val) && typeof val !== 'string') { @@ -18862,7 +17448,7 @@ HashBase.prototype._digest = function () { module.exports = HashBase -},{"103":103,"65":65,"93":93}],64:[function(require,module,exports){ +},{"inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js","stream":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/stream-browserify/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ieee754/index.js":[function(require,module,exports){ exports.read = function (buffer, offset, isLE, mLen, nBytes) { var e, m var eLen = (nBytes * 8) - mLen - 1 @@ -18948,7 +17534,7 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { buffer[offset + i - d] |= s * 128 } -},{}],65:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js":[function(require,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { @@ -18973,7 +17559,7 @@ if (typeof Object.create === 'function') { } } -},{}],66:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/is-buffer/index.js":[function(require,module,exports){ /*! * Determine if an object is a Buffer * @@ -18996,14 +17582,14 @@ function isSlowBuffer (obj) { return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) } -},{}],67:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/isarray/index.js":[function(require,module,exports){ var toString = {}.toString; module.exports = Array.isArray || function (arr) { return toString.call(arr) == '[object Array]'; }; -},{}],68:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/long/dist/long.js":[function(require,module,exports){ /* Copyright 2013 Daniel Wirtz Copyright 2009 The Closure Library Authors. All Rights Reserved. @@ -20214,11 +18800,11 @@ module.exports = Array.isArray || function (arr) { return Long; }); -},{}],69:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/md5.js/index.js":[function(require,module,exports){ (function (Buffer){ 'use strict' -var inherits = require(65) -var HashBase = require(63) +var inherits = require('inherits') +var HashBase = require('hash-base') var ARRAY16 = new Array(16) @@ -20362,23 +18948,23 @@ function fnI (a, b, c, d, m, k, s) { module.exports = MD5 -}).call(this,require(35).Buffer) +}).call(this,require("buffer").Buffer) -},{"35":35,"63":63,"65":65}],70:[function(require,module,exports){ +},{"buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","hash-base":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/hash-base/index.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/index.js":[function(require,module,exports){ 'use strict'; exports.__esModule = true; exports.Manager = exports.ChainConfig = exports.Apis = undefined; -var _ApiInstances = require(71); +var _ApiInstances = require('./src/ApiInstances'); var _ApiInstances2 = _interopRequireDefault(_ApiInstances); -var _ConnectionManager = require(74); +var _ConnectionManager = require('./src/ConnectionManager'); var _ConnectionManager2 = _interopRequireDefault(_ConnectionManager); -var _ChainConfig = require(72); +var _ChainConfig = require('./src/ChainConfig'); var _ChainConfig2 = _interopRequireDefault(_ChainConfig); @@ -20387,20 +18973,20 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de exports.Apis = _ApiInstances2.default; exports.ChainConfig = _ChainConfig2.default; exports.Manager = _ConnectionManager2.default; -},{"71":71,"72":72,"74":74}],71:[function(require,module,exports){ +},{"./src/ApiInstances":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ApiInstances.js","./src/ChainConfig":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ChainConfig.js","./src/ConnectionManager":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ConnectionManager.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ApiInstances.js":[function(require,module,exports){ 'use strict'; exports.__esModule = true; -var _ChainWebSocket = require(73); +var _ChainWebSocket = require('./ChainWebSocket'); var _ChainWebSocket2 = _interopRequireDefault(_ChainWebSocket); -var _GrapheneApi = require(75); +var _GrapheneApi = require('./GrapheneApi'); var _GrapheneApi2 = _interopRequireDefault(_GrapheneApi); -var _ChainConfig = require(72); +var _ChainConfig = require('./ChainConfig'); var _ChainConfig2 = _interopRequireDefault(_ChainConfig); @@ -20575,7 +19161,7 @@ exports.default = { // crypto: (method, ...args) => Apis.instance().crypto_api().exec(method, toStrings(args)) }; -},{"72":72,"73":73,"75":75}],72:[function(require,module,exports){ +},{"./ChainConfig":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ChainConfig.js","./ChainWebSocket":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ChainWebSocket.js","./GrapheneApi":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/GrapheneApi.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ChainConfig.js":[function(require,module,exports){ 'use strict'; exports.__esModule = true; @@ -20652,7 +19238,7 @@ var ChainConfig = function () { }(); exports.default = new ChainConfig(); -},{}],73:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ChainWebSocket.js":[function(require,module,exports){ 'use strict'; exports.__esModule = true; @@ -20665,7 +19251,7 @@ var WebSocketClient = null; if (typeof WebSocket !== 'undefined') { WebSocketClient = WebSocket; } else { - WebSocketClient = require(34); // eslint-disable-line global-require + WebSocketClient = require('ws'); // eslint-disable-line global-require } var SUBSCRIBE_OPERATIONS = ['set_subscribe_callback', 'subscribe_to_market', 'broadcast_transaction_with_callback', 'set_pending_transaction_callback']; @@ -21136,16 +19722,16 @@ ChainWebSocket.status = { }; exports.default = ChainWebSocket; -},{"34":34}],74:[function(require,module,exports){ +},{"ws":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browser-resolve/empty.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ConnectionManager.js":[function(require,module,exports){ 'use strict'; exports.__esModule = true; -var _ApiInstances = require(71); +var _ApiInstances = require('./ApiInstances'); var _ApiInstances2 = _interopRequireDefault(_ApiInstances); -var _ChainWebSocket = require(73); +var _ChainWebSocket = require('./ChainWebSocket'); var _ChainWebSocket2 = _interopRequireDefault(_ChainWebSocket); @@ -21280,7 +19866,7 @@ var Manager = function () { }(); exports.default = Manager; -},{"71":71,"73":73}],75:[function(require,module,exports){ +},{"./ApiInstances":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ApiInstances.js","./ChainWebSocket":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/ChainWebSocket.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/peerplaysjs-ws/dist/src/GrapheneApi.js":[function(require,module,exports){ 'use strict'; exports.__esModule = true; @@ -21315,7 +19901,7 @@ var GrapheneApi = function () { }(); exports.default = GrapheneApi; -},{}],76:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process-nextick-args/index.js":[function(require,module,exports){ (function (process){ 'use strict'; @@ -21362,9 +19948,9 @@ function nextTick(fn, arg1, arg2, arg3) { } -}).call(this,require(77)) +}).call(this,require('_process')) -},{"77":77}],77:[function(require,module,exports){ +},{"_process":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process/browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process/browser.js":[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; @@ -21550,10 +20136,10 @@ process.chdir = function (dir) { }; process.umask = function() { return 0; }; -},{}],78:[function(require,module,exports){ -module.exports = require(79); +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/duplex-browser.js":[function(require,module,exports){ +module.exports = require('./lib/_stream_duplex.js'); -},{"79":79}],79:[function(require,module,exports){ +},{"./lib/_stream_duplex.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_duplex.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_duplex.js":[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -21584,7 +20170,7 @@ module.exports = require(79); /**/ -var pna = require(76); +var pna = require('process-nextick-args'); /**/ /**/ @@ -21599,12 +20185,12 @@ var objectKeys = Object.keys || function (obj) { module.exports = Duplex; /**/ -var util = require(40); -util.inherits = require(87); +var util = require('core-util-is'); +util.inherits = require('inherits'); /**/ -var Readable = require(81); -var Writable = require(83); +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); util.inherits(Duplex, Readable); @@ -21685,7 +20271,7 @@ Duplex.prototype._destroy = function (err, cb) { pna.nextTick(cb, err); }; -},{"40":40,"76":76,"81":81,"83":83,"87":87}],80:[function(require,module,exports){ +},{"./_stream_readable":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_readable.js","./_stream_writable":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_writable.js","core-util-is":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/core-util-is/lib/util.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","process-nextick-args":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process-nextick-args/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_passthrough.js":[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -21715,11 +20301,11 @@ Duplex.prototype._destroy = function (err, cb) { module.exports = PassThrough; -var Transform = require(82); +var Transform = require('./_stream_transform'); /**/ -var util = require(40); -util.inherits = require(87); +var util = require('core-util-is'); +util.inherits = require('inherits'); /**/ util.inherits(PassThrough, Transform); @@ -21733,7 +20319,7 @@ function PassThrough(options) { PassThrough.prototype._transform = function (chunk, encoding, cb) { cb(null, chunk); }; -},{"40":40,"82":82,"87":87}],81:[function(require,module,exports){ +},{"./_stream_transform":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_transform.js","core-util-is":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/core-util-is/lib/util.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_readable.js":[function(require,module,exports){ (function (process,global){ // Copyright Joyent, Inc. and other Node contributors. // @@ -21760,13 +20346,13 @@ PassThrough.prototype._transform = function (chunk, encoding, cb) { /**/ -var pna = require(76); +var pna = require('process-nextick-args'); /**/ module.exports = Readable; /**/ -var isArray = require(67); +var isArray = require('isarray'); /**/ /**/ @@ -21776,7 +20362,7 @@ var Duplex; Readable.ReadableState = ReadableState; /**/ -var EE = require(62).EventEmitter; +var EE = require('events').EventEmitter; var EElistenerCount = function (emitter, type) { return emitter.listeners(type).length; @@ -21784,12 +20370,12 @@ var EElistenerCount = function (emitter, type) { /**/ /**/ -var Stream = require(86); +var Stream = require('./internal/streams/stream'); /**/ /**/ -var Buffer = require(93).Buffer; +var Buffer = require('safe-buffer').Buffer; var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); @@ -21801,12 +20387,12 @@ function _isUint8Array(obj) { /**/ /**/ -var util = require(40); -util.inherits = require(87); +var util = require('core-util-is'); +util.inherits = require('inherits'); /**/ /**/ -var debugUtil = require(34); +var debugUtil = require('util'); var debug = void 0; if (debugUtil && debugUtil.debuglog) { debug = debugUtil.debuglog('stream'); @@ -21815,8 +20401,8 @@ if (debugUtil && debugUtil.debuglog) { } /**/ -var BufferList = require(84); -var destroyImpl = require(85); +var BufferList = require('./internal/streams/BufferList'); +var destroyImpl = require('./internal/streams/destroy'); var StringDecoder; util.inherits(Readable, Stream); @@ -21836,7 +20422,7 @@ function prependListener(emitter, event, fn) { } function ReadableState(options, stream) { - Duplex = Duplex || require(79); + Duplex = Duplex || require('./_stream_duplex'); options = options || {}; @@ -21906,14 +20492,14 @@ function ReadableState(options, stream) { this.decoder = null; this.encoding = null; if (options.encoding) { - if (!StringDecoder) StringDecoder = require(104).StringDecoder; + if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; this.decoder = new StringDecoder(options.encoding); this.encoding = options.encoding; } } function Readable(options) { - Duplex = Duplex || require(79); + Duplex = Duplex || require('./_stream_duplex'); if (!(this instanceof Readable)) return new Readable(options); @@ -22062,7 +20648,7 @@ Readable.prototype.isPaused = function () { // backwards compatibility. Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = require(104).StringDecoder; + if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; this._readableState.decoder = new StringDecoder(enc); this._readableState.encoding = enc; return this; @@ -22754,9 +21340,9 @@ function indexOf(xs, x) { } return -1; } -}).call(this,require(77),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"104":104,"34":34,"40":40,"62":62,"67":67,"76":76,"77":77,"79":79,"84":84,"85":85,"86":86,"87":87,"93":93}],82:[function(require,module,exports){ +},{"./_stream_duplex":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_duplex.js","./internal/streams/BufferList":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/BufferList.js","./internal/streams/destroy":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/destroy.js","./internal/streams/stream":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/stream-browser.js","_process":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process/browser.js","core-util-is":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/core-util-is/lib/util.js","events":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/events/events.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","isarray":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/isarray/index.js","process-nextick-args":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process-nextick-args/index.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js","string_decoder/":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/string_decoder/lib/string_decoder.js","util":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browser-resolve/empty.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_transform.js":[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -22824,11 +21410,11 @@ function indexOf(xs, x) { module.exports = Transform; -var Duplex = require(79); +var Duplex = require('./_stream_duplex'); /**/ -var util = require(40); -util.inherits = require(87); +var util = require('core-util-is'); +util.inherits = require('inherits'); /**/ util.inherits(Transform, Duplex); @@ -22971,7 +21557,7 @@ function done(stream, er, data) { return stream.push(null); } -},{"40":40,"79":79,"87":87}],83:[function(require,module,exports){ +},{"./_stream_duplex":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_duplex.js","core-util-is":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/core-util-is/lib/util.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_writable.js":[function(require,module,exports){ (function (process,global,setImmediate){ // Copyright Joyent, Inc. and other Node contributors. // @@ -23002,7 +21588,7 @@ function done(stream, er, data) { /**/ -var pna = require(76); +var pna = require('process-nextick-args'); /**/ module.exports = Writable; @@ -23039,23 +21625,23 @@ var Duplex; Writable.WritableState = WritableState; /**/ -var util = require(40); -util.inherits = require(87); +var util = require('core-util-is'); +util.inherits = require('inherits'); /**/ /**/ var internalUtil = { - deprecate: require(106) + deprecate: require('util-deprecate') }; /**/ /**/ -var Stream = require(86); +var Stream = require('./internal/streams/stream'); /**/ /**/ -var Buffer = require(93).Buffer; +var Buffer = require('safe-buffer').Buffer; var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); @@ -23066,14 +21652,14 @@ function _isUint8Array(obj) { /**/ -var destroyImpl = require(85); +var destroyImpl = require('./internal/streams/destroy'); util.inherits(Writable, Stream); function nop() {} function WritableState(options, stream) { - Duplex = Duplex || require(79); + Duplex = Duplex || require('./_stream_duplex'); options = options || {}; @@ -23223,7 +21809,7 @@ if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.protot } function Writable(options) { - Duplex = Duplex || require(79); + Duplex = Duplex || require('./_stream_duplex'); // Writable ctor is applied to Duplexes, too. // `realHasInstance` is necessary because using plain `instanceof` @@ -23660,15 +22246,15 @@ Writable.prototype._destroy = function (err, cb) { this.end(); cb(err); }; -}).call(this,require(77),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require(105).setImmediate) +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("timers").setImmediate) -},{"105":105,"106":106,"40":40,"76":76,"77":77,"79":79,"85":85,"86":86,"87":87,"93":93}],84:[function(require,module,exports){ +},{"./_stream_duplex":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_duplex.js","./internal/streams/destroy":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/destroy.js","./internal/streams/stream":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/stream-browser.js","_process":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process/browser.js","core-util-is":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/core-util-is/lib/util.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","process-nextick-args":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process-nextick-args/index.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js","timers":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/timers-browserify/main.js","util-deprecate":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/util-deprecate/browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/BufferList.js":[function(require,module,exports){ 'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var Buffer = require(93).Buffer; -var util = require(34); +var Buffer = require('safe-buffer').Buffer; +var util = require('util'); function copyBuffer(src, target, offset) { src.copy(target, offset); @@ -23742,12 +22328,12 @@ if (util && util.inspect && util.inspect.custom) { return this.constructor.name + ' ' + obj; }; } -},{"34":34,"93":93}],85:[function(require,module,exports){ +},{"safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js","util":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browser-resolve/empty.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/destroy.js":[function(require,module,exports){ 'use strict'; /**/ -var pna = require(76); +var pna = require('process-nextick-args'); /**/ // undocumented cb() API, needed for core, not for public API @@ -23817,34 +22403,32 @@ module.exports = { destroy: destroy, undestroy: undestroy }; -},{"76":76}],86:[function(require,module,exports){ -module.exports = require(62).EventEmitter; +},{"process-nextick-args":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process-nextick-args/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/stream-browser.js":[function(require,module,exports){ +module.exports = require('events').EventEmitter; -},{"62":62}],87:[function(require,module,exports){ -arguments[4][65][0].apply(exports,arguments) -},{"65":65}],88:[function(require,module,exports){ -module.exports = require(89).PassThrough +},{"events":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/events/events.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/passthrough.js":[function(require,module,exports){ +module.exports = require('./readable').PassThrough -},{"89":89}],89:[function(require,module,exports){ -exports = module.exports = require(81); +},{"./readable":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/readable-browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/readable-browser.js":[function(require,module,exports){ +exports = module.exports = require('./lib/_stream_readable.js'); exports.Stream = exports; exports.Readable = exports; -exports.Writable = require(83); -exports.Duplex = require(79); -exports.Transform = require(82); -exports.PassThrough = require(80); +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); -},{"79":79,"80":80,"81":81,"82":82,"83":83}],90:[function(require,module,exports){ -module.exports = require(89).Transform +},{"./lib/_stream_duplex.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_duplex.js","./lib/_stream_passthrough.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_passthrough.js","./lib/_stream_readable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_readable.js","./lib/_stream_transform.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_transform.js","./lib/_stream_writable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_writable.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/transform.js":[function(require,module,exports){ +module.exports = require('./readable').Transform -},{"89":89}],91:[function(require,module,exports){ -module.exports = require(83); +},{"./readable":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/readable-browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/writable-browser.js":[function(require,module,exports){ +module.exports = require('./lib/_stream_writable.js'); -},{"83":83}],92:[function(require,module,exports){ +},{"./lib/_stream_writable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_writable.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ripemd160/index.js":[function(require,module,exports){ 'use strict' -var Buffer = require(35).Buffer -var inherits = require(65) -var HashBase = require(63) +var Buffer = require('buffer').Buffer +var inherits = require('inherits') +var HashBase = require('hash-base') var ARRAY16 = new Array(16) @@ -24005,9 +22589,9 @@ function fn5 (a, b, c, d, e, m, k, s) { module.exports = RIPEMD160 -},{"35":35,"63":63,"65":65}],93:[function(require,module,exports){ +},{"buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","hash-base":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/hash-base/index.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js":[function(require,module,exports){ /* eslint-disable node/no-deprecated-api */ -var buffer = require(35) +var buffer = require('buffer') var Buffer = buffer.Buffer // alternative to using Object.keys for old browsers @@ -24069,7 +22653,7 @@ SafeBuffer.allocUnsafeSlow = function (size) { return buffer.SlowBuffer(size) } -},{"35":35}],94:[function(require,module,exports){ +},{"buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/secure-random/lib/secure-random.js":[function(require,module,exports){ (function (process,Buffer){ !function(globals){ 'use strict' @@ -24100,7 +22684,7 @@ function secureRandom(count, options) { } function nodeRandom(count, options) { - var crypto = require(34) + var crypto = require('crypto') var buf = crypto.randomBytes(count) switch (options.type) { @@ -24150,10 +22734,10 @@ secureRandom.randomBuffer = function(byteCount) { }(this); -}).call(this,require(77),require(35).Buffer) +}).call(this,require('_process'),require("buffer").Buffer) -},{"34":34,"35":35,"77":77}],95:[function(require,module,exports){ -var Buffer = require(93).Buffer +},{"_process":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process/browser.js","buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js","crypto":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browser-resolve/empty.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js":[function(require,module,exports){ +var Buffer = require('safe-buffer').Buffer // prototype class for hash functions function Hash (blockSize, finalSize) { @@ -24235,7 +22819,7 @@ Hash.prototype._update = function () { module.exports = Hash -},{"93":93}],96:[function(require,module,exports){ +},{"safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/index.js":[function(require,module,exports){ var exports = module.exports = function SHA (algorithm) { algorithm = algorithm.toLowerCase() @@ -24245,14 +22829,14 @@ var exports = module.exports = function SHA (algorithm) { return new Algorithm() } -exports.sha = require(97) -exports.sha1 = require(98) -exports.sha224 = require(99) -exports.sha256 = require(100) -exports.sha384 = require(101) -exports.sha512 = require(102) +exports.sha = require('./sha') +exports.sha1 = require('./sha1') +exports.sha224 = require('./sha224') +exports.sha256 = require('./sha256') +exports.sha384 = require('./sha384') +exports.sha512 = require('./sha512') -},{"100":100,"101":101,"102":102,"97":97,"98":98,"99":99}],97:[function(require,module,exports){ +},{"./sha":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha.js","./sha1":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha1.js","./sha224":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha224.js","./sha256":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha256.js","./sha384":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha384.js","./sha512":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha512.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha.js":[function(require,module,exports){ /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined * in FIPS PUB 180-1 @@ -24261,9 +22845,9 @@ exports.sha512 = require(102) * operation was added. */ -var inherits = require(65) -var Hash = require(95) -var Buffer = require(93).Buffer +var inherits = require('inherits') +var Hash = require('./hash') +var Buffer = require('safe-buffer').Buffer var K = [ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 @@ -24348,7 +22932,7 @@ Sha.prototype._hash = function () { module.exports = Sha -},{"65":65,"93":93,"95":95}],98:[function(require,module,exports){ +},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha1.js":[function(require,module,exports){ /* * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined * in FIPS PUB 180-1 @@ -24358,9 +22942,9 @@ module.exports = Sha * See http://pajhome.org.uk/crypt/md5 for details. */ -var inherits = require(65) -var Hash = require(95) -var Buffer = require(93).Buffer +var inherits = require('inherits') +var Hash = require('./hash') +var Buffer = require('safe-buffer').Buffer var K = [ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 @@ -24449,7 +23033,7 @@ Sha1.prototype._hash = function () { module.exports = Sha1 -},{"65":65,"93":93,"95":95}],99:[function(require,module,exports){ +},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha224.js":[function(require,module,exports){ /** * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined * in FIPS 180-2 @@ -24458,10 +23042,10 @@ module.exports = Sha1 * */ -var inherits = require(65) -var Sha256 = require(100) -var Hash = require(95) -var Buffer = require(93).Buffer +var inherits = require('inherits') +var Sha256 = require('./sha256') +var Hash = require('./hash') +var Buffer = require('safe-buffer').Buffer var W = new Array(64) @@ -24504,7 +23088,7 @@ Sha224.prototype._hash = function () { module.exports = Sha224 -},{"100":100,"65":65,"93":93,"95":95}],100:[function(require,module,exports){ +},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js","./sha256":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha256.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha256.js":[function(require,module,exports){ /** * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined * in FIPS 180-2 @@ -24513,9 +23097,9 @@ module.exports = Sha224 * */ -var inherits = require(65) -var Hash = require(95) -var Buffer = require(93).Buffer +var inherits = require('inherits') +var Hash = require('./hash') +var Buffer = require('safe-buffer').Buffer var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, @@ -24641,11 +23225,11 @@ Sha256.prototype._hash = function () { module.exports = Sha256 -},{"65":65,"93":93,"95":95}],101:[function(require,module,exports){ -var inherits = require(65) -var SHA512 = require(102) -var Hash = require(95) -var Buffer = require(93).Buffer +},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha384.js":[function(require,module,exports){ +var inherits = require('inherits') +var SHA512 = require('./sha512') +var Hash = require('./hash') +var Buffer = require('safe-buffer').Buffer var W = new Array(160) @@ -24700,10 +23284,10 @@ Sha384.prototype._hash = function () { module.exports = Sha384 -},{"102":102,"65":65,"93":93,"95":95}],102:[function(require,module,exports){ -var inherits = require(65) -var Hash = require(95) -var Buffer = require(93).Buffer +},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js","./sha512":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha512.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha512.js":[function(require,module,exports){ +var inherits = require('inherits') +var Hash = require('./hash') +var Buffer = require('safe-buffer').Buffer var K = [ 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, @@ -24962,7 +23546,7 @@ Sha512.prototype._hash = function () { module.exports = Sha512 -},{"65":65,"93":93,"95":95}],103:[function(require,module,exports){ +},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/stream-browserify/index.js":[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -24986,15 +23570,15 @@ module.exports = Sha512 module.exports = Stream; -var EE = require(62).EventEmitter; -var inherits = require(65); +var EE = require('events').EventEmitter; +var inherits = require('inherits'); inherits(Stream, EE); -Stream.Readable = require(89); -Stream.Writable = require(91); -Stream.Duplex = require(78); -Stream.Transform = require(90); -Stream.PassThrough = require(88); +Stream.Readable = require('readable-stream/readable.js'); +Stream.Writable = require('readable-stream/writable.js'); +Stream.Duplex = require('readable-stream/duplex.js'); +Stream.Transform = require('readable-stream/transform.js'); +Stream.PassThrough = require('readable-stream/passthrough.js'); // Backwards-compat with node 0.4.x Stream.Stream = Stream; @@ -25091,7 +23675,7 @@ Stream.prototype.pipe = function(dest, options) { return dest; }; -},{"62":62,"65":65,"78":78,"88":88,"89":89,"90":90,"91":91}],104:[function(require,module,exports){ +},{"events":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/events/events.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","readable-stream/duplex.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/duplex-browser.js","readable-stream/passthrough.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/passthrough.js","readable-stream/readable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/readable-browser.js","readable-stream/transform.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/transform.js","readable-stream/writable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/writable-browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/string_decoder/lib/string_decoder.js":[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -25117,7 +23701,7 @@ Stream.prototype.pipe = function(dest, options) { /**/ -var Buffer = require(93).Buffer; +var Buffer = require('safe-buffer').Buffer; /**/ var isEncoding = Buffer.isEncoding || function (encoding) { @@ -25388,9 +23972,9 @@ function simpleWrite(buf) { function simpleEnd(buf) { return buf && buf.length ? this.write(buf) : ''; } -},{"93":93}],105:[function(require,module,exports){ +},{"safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/timers-browserify/main.js":[function(require,module,exports){ (function (setImmediate,clearImmediate){ -var nextTick = require(77).nextTick; +var nextTick = require('process/browser.js').nextTick; var apply = Function.prototype.apply; var slice = Array.prototype.slice; var immediateIds = {}; @@ -25466,9 +24050,9 @@ exports.setImmediate = typeof setImmediate === "function" ? setImmediate : funct exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) { delete immediateIds[id]; }; -}).call(this,require(105).setImmediate,require(105).clearImmediate) +}).call(this,require("timers").setImmediate,require("timers").clearImmediate) -},{"105":105,"77":77}],106:[function(require,module,exports){ +},{"process/browser.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process/browser.js","timers":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/timers-browserify/main.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/util-deprecate/browser.js":[function(require,module,exports){ (function (global){ /** @@ -25540,14 +24124,16 @@ function config (name) { }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],107:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/util/node_modules/inherits/inherits_browser.js":[function(require,module,exports){ +arguments[4]["/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js"][0].apply(exports,arguments) +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/util/support/isBufferBrowser.js":[function(require,module,exports){ module.exports = function isBuffer(arg) { return arg && typeof arg === 'object' && typeof arg.copy === 'function' && typeof arg.fill === 'function' && typeof arg.readUInt8 === 'function'; } -},{}],108:[function(require,module,exports){ +},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/util/util.js":[function(require,module,exports){ (function (process,global){ // Copyright Joyent, Inc. and other Node contributors. // @@ -26074,7 +24660,7 @@ function isPrimitive(arg) { } exports.isPrimitive = isPrimitive; -exports.isBuffer = require(107); +exports.isBuffer = require('./support/isBuffer'); function objectToString(o) { return Object.prototype.toString.call(o); @@ -26118,7 +24704,7 @@ exports.log = function() { * prototype. * @param {function} superCtor Constructor function to inherit prototype from. */ -exports.inherits = require(65); +exports.inherits = require('inherits'); exports._extend = function(origin, add) { // Don't do anything if add isn't an object @@ -26136,9 +24722,9 @@ function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } -}).call(this,require(77),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"107":107,"65":65,"77":77}]},{},[1])(1) +},{"./support/isBuffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/util/support/isBufferBrowser.js","_process":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process/browser.js","inherits":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/util/node_modules/inherits/inherits_browser.js"}]},{},["/Users/mseaward/Documents/code/peerplaysjs-lib/dist/browser.js"])("/Users/mseaward/Documents/code/peerplaysjs-lib/dist/browser.js") }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJkaXN0L2Jyb3dzZXIuanMiLCJkaXN0L2NoYWluL3NyYy9BY2NvdW50TG9naW4uanMiLCJkaXN0L2NoYWluL3NyYy9DaGFpblR5cGVzLmpzIiwiZGlzdC9jaGFpbi9zcmMvT2JqZWN0SWQuanMiLCJkaXN0L2NoYWluL3NyYy9UcmFuc2FjdGlvbkJ1aWxkZXIuanMiLCJkaXN0L2NoYWluL3NyYy9zdGF0ZS5qcyIsImRpc3QvZWNjL2luZGV4LmpzIiwiZGlzdC9lY2Mvc3JjL0JyYWluS2V5LmpzIiwiZGlzdC9lY2Mvc3JjL0tleVV0aWxzLmpzIiwiZGlzdC9lY2Mvc3JjL1ByaXZhdGVLZXkuanMiLCJkaXN0L2VjYy9zcmMvUHVibGljS2V5LmpzIiwiZGlzdC9lY2Mvc3JjL2FkZHJlc3MuanMiLCJkaXN0L2VjYy9zcmMvYWVzLmpzIiwiZGlzdC9lY2Mvc3JjL2VjZHNhLmpzIiwiZGlzdC9lY2Mvc3JjL2Vjc2lnbmF0dXJlLmpzIiwiZGlzdC9lY2Mvc3JjL2VuZm9yY2VfdHlwZXMuanMiLCJkaXN0L2VjYy9zcmMvaGFzaC5qcyIsImRpc3QvZWNjL3NyYy9zaWduYXR1cmUuanMiLCJkaXN0L3NlcmlhbGl6ZXIvaW5kZXguanMiLCJkaXN0L3NlcmlhbGl6ZXIvc3JjL0Zhc3RQYXJzZXIuanMiLCJkaXN0L3NlcmlhbGl6ZXIvc3JjL1NlcmlhbGl6ZXJWYWxpZGF0aW9uLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9lcnJvcl93aXRoX2NhdXNlLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9vcGVyYXRpb25zLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9zZXJpYWxpemVyLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy90ZW1wbGF0ZS5qcyIsImRpc3Qvc2VyaWFsaXplci9zcmMvdHlwZXMuanMiLCJub2RlX21vZHVsZXMvYXNzZXJ0L2Fzc2VydC5qcyIsIm5vZGVfbW9kdWxlcy9iYXNlLXgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JpZ2kvbGliL2JpZ2kuanMiLCJub2RlX21vZHVsZXMvYmlnaS9saWIvY29udmVydC5qcyIsIm5vZGVfbW9kdWxlcy9iaWdpL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9iaWdpL3BhY2thZ2UuanNvbiIsIm5vZGVfbW9kdWxlcy9icm93c2VyLXJlc29sdmUvZW1wdHkuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JzNTgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnl0ZWJ1ZmZlci9kaXN0L2J5dGVidWZmZXIuanMiLCJub2RlX21vZHVsZXMvY2lwaGVyLWJhc2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzIiwibm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvbWQ1LmpzIiwibm9kZV9tb2R1bGVzL2NyZWF0ZS1obWFjL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhtYWMvbGVnYWN5LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9hZXMuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2NpcGhlci1jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9lbmMtYmFzZTY0LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9lbmMtaGV4LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9ldnBrZGYuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2htYWMuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL21kNS5qcyIsIm5vZGVfbW9kdWxlcy9jcnlwdG8tanMvc2hhMS5qcyIsIm5vZGVfbW9kdWxlcy9kZWVwLWVxdWFsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2RlZXAtZXF1YWwvbGliL2lzX2FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9kZWVwLWVxdWFsL2xpYi9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2VjdXJ2ZS9saWIvY3VydmUuanMiLCJub2RlX21vZHVsZXMvZWN1cnZlL2xpYi9jdXJ2ZXMuanNvbiIsIm5vZGVfbW9kdWxlcy9lY3VydmUvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2VjdXJ2ZS9saWIvbmFtZXMuanMiLCJub2RlX21vZHVsZXMvZWN1cnZlL2xpYi9wb2ludC5qcyIsIm5vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwibm9kZV9tb2R1bGVzL2hhc2gtYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvaXMtYnVmZmVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9uZy9kaXN0L2xvbmcuanMiLCJub2RlX21vZHVsZXMvbWQ1LmpzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcGVlcnBsYXlzanMtd3MvZGlzdC9zcmMvQXBpSW5zdGFuY2VzLmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0NoYWluQ29uZmlnLmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0NoYWluV2ViU29ja2V0LmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0Nvbm5lY3Rpb25NYW5hZ2VyLmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0dyYXBoZW5lQXBpLmpzIiwibm9kZV9tb2R1bGVzL3Byb2Nlc3MtbmV4dGljay1hcmdzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LWJyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9CdWZmZXJMaXN0LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9kZXN0cm95LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0tYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLWJyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUtYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yaXBlbWQxNjAvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2FmZS1idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2VjdXJlLXJhbmRvbS9saWIvc2VjdXJlLXJhbmRvbS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvaGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2hhLmpzL3NoYS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhMS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhMjI0LmpzIiwibm9kZV9tb2R1bGVzL3NoYS5qcy9zaGEyNTYuanMiLCJub2RlX21vZHVsZXMvc2hhLmpzL3NoYTM4NC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhNTEyLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2xpYi9zdHJpbmdfZGVjb2Rlci5qcyIsIm5vZGVfbW9kdWxlcy90aW1lcnMtYnJvd3NlcmlmeS9tYWluLmpzIiwibm9kZV9tb2R1bGVzL3V0aWwtZGVwcmVjYXRlL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvdXRpbC9zdXBwb3J0L2lzQnVmZmVyQnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy91dGlsL3V0aWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbHFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNuT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2hPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3hPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUM3VEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDelBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdk1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM1Z0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3pPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNyckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDcitDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM3dkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbHFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdk9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy8yQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdnZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDenJDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TEE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzEvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM5cUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBOzs7O0FDREE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7O0FDREE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25LQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3ZTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfcGVlcnBsYXlzanNXcyA9IHJlcXVpcmUoNzApO1xuXG52YXIgX3BlZXJwbGF5c2pzV3MyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcGVlcnBsYXlzanNXcyk7XG5cbnZhciBfUHJpdmF0ZUtleSA9IHJlcXVpcmUoMTApO1xuXG52YXIgX1ByaXZhdGVLZXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUHJpdmF0ZUtleSk7XG5cbnZhciBfUHVibGljS2V5ID0gcmVxdWlyZSgxMSk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbnZhciBfc2lnbmF0dXJlID0gcmVxdWlyZSgxOCk7XG5cbnZhciBfc2lnbmF0dXJlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3NpZ25hdHVyZSk7XG5cbnZhciBfS2V5VXRpbHMgPSByZXF1aXJlKDkpO1xuXG52YXIgX0tleVV0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0tleVV0aWxzKTtcblxudmFyIF9UcmFuc2FjdGlvbkJ1aWxkZXIgPSByZXF1aXJlKDUpO1xuXG52YXIgX1RyYW5zYWN0aW9uQnVpbGRlcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9UcmFuc2FjdGlvbkJ1aWxkZXIpO1xuXG52YXIgX0FjY291bnRMb2dpbiA9IHJlcXVpcmUoMik7XG5cbnZhciBfQWNjb3VudExvZ2luMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0FjY291bnRMb2dpbik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmV4cG9ydHMuZGVmYXVsdCA9IHtcbiAgUHJpdmF0ZUtleTogX1ByaXZhdGVLZXkyLmRlZmF1bHQsXG4gIFB1YmxpY0tleTogX1B1YmxpY0tleTIuZGVmYXVsdCxcbiAgU2lnbmF0dXJlOiBfc2lnbmF0dXJlMi5kZWZhdWx0LFxuICBrZXk6IF9LZXlVdGlsczIuZGVmYXVsdCxcbiAgVHJhbnNhY3Rpb25CdWlsZGVyOiBfVHJhbnNhY3Rpb25CdWlsZGVyMi5kZWZhdWx0LFxuICBMb2dpbjogX0FjY291bnRMb2dpbjIuZGVmYXVsdCxcbiAgcGVlcnBsYXlzanNfd3M6IF9wZWVycGxheXNqc1dzMi5kZWZhdWx0XG59O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX1ByaXZhdGVLZXkgPSByZXF1aXJlKDEwKTtcblxudmFyIF9Qcml2YXRlS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1ByaXZhdGVLZXkpO1xuXG52YXIgX0tleVV0aWxzID0gcmVxdWlyZSg5KTtcblxudmFyIF9LZXlVdGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9LZXlVdGlscyk7XG5cbnZhciBfc3RhdGUgPSByZXF1aXJlKDYpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgX2tleUNhY2hlUHJpdiA9IHt9O1xudmFyIF9rZXlDYWNoZVB1YiA9IHt9O1xuXG52YXIgQWNjb3VudExvZ2luID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBBY2NvdW50TG9naW4oKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEFjY291bnRMb2dpbik7XG5cbiAgICB2YXIgc3RhdGUgPSB7IGxvZ2dlZEluOiBmYWxzZSwgcm9sZXM6IFsnYWN0aXZlJywgJ293bmVyJywgJ21lbW8nXSB9O1xuICAgIHRoaXMuZ2V0ID0gKDAsIF9zdGF0ZS5nZXQpKHN0YXRlKTtcbiAgICB0aGlzLnNldCA9ICgwLCBfc3RhdGUuc2V0KShzdGF0ZSk7XG5cbiAgICB0aGlzLnN1YnMgPSB7fTtcbiAgfVxuXG4gIEFjY291bnRMb2dpbi5wcm90b3R5cGUuYWRkU3Vic2NyaXB0aW9uID0gZnVuY3Rpb24gYWRkU3Vic2NyaXB0aW9uKGNiKSB7XG4gICAgdGhpcy5zdWJzW2NiXSA9IGNiO1xuICB9O1xuXG4gIEFjY291bnRMb2dpbi5wcm90b3R5cGUuc2V0Um9sZXMgPSBmdW5jdGlvbiBzZXRSb2xlcyhyb2xlcykge1xuICAgIHRoaXMuc2V0KCdyb2xlcycsIHJvbGVzKTtcbiAgfTtcblxuICBBY2NvdW50TG9naW4ucHJvdG90eXBlLmdlbmVyYXRlS2V5cyA9IGZ1bmN0aW9uIGdlbmVyYXRlS2V5cyhhY2NvdW50TmFtZSwgcGFzc3dvcmQsIHJvbGVzLCBwcmVmaXgpIHtcbiAgICBpZiAoIWFjY291bnROYW1lIHx8ICFwYXNzd29yZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBY2NvdW50IG5hbWUgb3IgcGFzc3dvcmQgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAocGFzc3dvcmQubGVuZ3RoIDwgMTIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFzc3dvcmQgbXVzdCBoYXZlIGF0IGxlYXN0IDEyIGNoYXJhY3RlcnMnKTtcbiAgICB9XG5cbiAgICB2YXIgcHJpdktleXMgPSB7fTtcbiAgICB2YXIgcHViS2V5cyA9IHt9O1xuXG4gICAgKHJvbGVzIHx8IHRoaXMuZ2V0KCdyb2xlcycpKS5mb3JFYWNoKGZ1bmN0aW9uIChyb2xlKSB7XG4gICAgICB2YXIgc2VlZCA9IHBhc3N3b3JkICsgYWNjb3VudE5hbWUgKyByb2xlO1xuICAgICAgdmFyIHBrZXkgPSBfa2V5Q2FjaGVQcml2W3NlZWRdID8gX2tleUNhY2hlUHJpdltzZWVkXSA6IF9Qcml2YXRlS2V5Mi5kZWZhdWx0LmZyb21TZWVkKF9LZXlVdGlsczIuZGVmYXVsdC5ub3JtYWxpemVfYnJhaW5LZXkoc2VlZCkpO1xuICAgICAgX2tleUNhY2hlUHJpdltzZWVkXSA9IHBrZXk7XG5cbiAgICAgIHByaXZLZXlzW3JvbGVdID0gcGtleTtcbiAgICAgIHB1YktleXNbcm9sZV0gPSBfa2V5Q2FjaGVQdWJbc2VlZF0gPyBfa2V5Q2FjaGVQdWJbc2VlZF0gOiBwa2V5LnRvUHVibGljS2V5KCkudG9TdHJpbmcocHJlZml4KTtcblxuICAgICAgX2tleUNhY2hlUHViW3NlZWRdID0gcHViS2V5c1tyb2xlXTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7IHByaXZLZXlzOiBwcml2S2V5cywgcHViS2V5czogcHViS2V5cyB9O1xuICB9O1xuXG4gIEFjY291bnRMb2dpbi5wcm90b3R5cGUuY2hlY2tLZXlzID0gZnVuY3Rpb24gY2hlY2tLZXlzKF9yZWYpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIGFjY291bnROYW1lID0gX3JlZi5hY2NvdW50TmFtZSxcbiAgICAgICAgcGFzc3dvcmQgPSBfcmVmLnBhc3N3b3JkLFxuICAgICAgICBhdXRocyA9IF9yZWYuYXV0aHM7XG5cbiAgICBpZiAoIWFjY291bnROYW1lIHx8ICFwYXNzd29yZCB8fCAhYXV0aHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2hlY2tLZXlzOiBNaXNzaW5nIGlucHV0cycpO1xuICAgIH1cblxuICAgIHZhciBoYXNLZXkgPSBmYWxzZTtcbiAgICB2YXIgcm9sZXMgPSBPYmplY3Qua2V5cyhhdXRocyk7XG5cbiAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiBfbG9vcChpLCBsZW4pIHtcbiAgICAgIHZhciByb2xlID0gcm9sZXNbaV07XG5cbiAgICAgIHZhciBfZ2VuZXJhdGVLZXlzID0gX3RoaXMuZ2VuZXJhdGVLZXlzKGFjY291bnROYW1lLCBwYXNzd29yZCwgW3JvbGVdKSxcbiAgICAgICAgICBwcml2S2V5cyA9IF9nZW5lcmF0ZUtleXMucHJpdktleXMsXG4gICAgICAgICAgcHViS2V5cyA9IF9nZW5lcmF0ZUtleXMucHViS2V5cztcblxuICAgICAgYXV0aHNbcm9sZV0uZm9yRWFjaChmdW5jdGlvbiAocm9sZUtleSkge1xuICAgICAgICBpZiAocm9sZUtleVswXSA9PT0gcHViS2V5c1tyb2xlXSkge1xuICAgICAgICAgIGhhc0tleSA9IHRydWU7XG4gICAgICAgICAgX3RoaXMuc2V0KHJvbGUsIHsgcHJpdjogcHJpdktleXNbcm9sZV0sIHB1YjogcHViS2V5c1tyb2xlXSB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSByb2xlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgX2xvb3AoaSwgbGVuKTtcbiAgICB9XG5cbiAgICBpZiAoaGFzS2V5KSB7XG4gICAgICB0aGlzLnNldCgnbmFtZScsIGFjY291bnROYW1lKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldCgnbG9nZ2VkSW4nLCBoYXNLZXkpO1xuXG4gICAgcmV0dXJuIGhhc0tleTtcbiAgfTtcblxuICBBY2NvdW50TG9naW4ucHJvdG90eXBlLnNpZ25UcmFuc2FjdGlvbiA9IGZ1bmN0aW9uIHNpZ25UcmFuc2FjdGlvbih0cikge1xuICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgdmFyIGhhc0tleSA9IGZhbHNlO1xuXG4gICAgdGhpcy5nZXQoJ3JvbGVzJykuZm9yRWFjaChmdW5jdGlvbiAocm9sZSkge1xuICAgICAgdmFyIG15S2V5ID0gX3RoaXMyLmdldChyb2xlKTtcblxuICAgICAgaWYgKG15S2V5KSB7XG4gICAgICAgIGhhc0tleSA9IHRydWU7XG4gICAgICAgIGNvbnNvbGUubG9nKCdhZGRpbmcgc2lnbmVyOicsIG15S2V5LnB1Yik7XG4gICAgICAgIHRyLmFkZF9zaWduZXIobXlLZXkucHJpdiwgbXlLZXkucHViKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmICghaGFzS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBkbyBub3QgaGF2ZSBhbnkgcHJpdmF0ZSBrZXlzIHRvIHNpZ24gdGhpcyB0cmFuc2FjdGlvbicpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gQWNjb3VudExvZ2luO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBuZXcgQWNjb3VudExvZ2luKCk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbnZhciByZXNlcnZlZF9zcGFjZXMgPSB7XG4gIHJlbGF0aXZlX3Byb3RvY29sX2lkczogMCxcbiAgcHJvdG9jb2xfaWRzOiAxLFxuICBpbXBsZW1lbnRhdGlvbl9pZHM6IDJcbn07XG5cbnZhciBvYmplY3RfdHlwZSA9IHtcbiAgbnVsbDogMCxcbiAgYmFzZTogMSxcbiAgYWNjb3VudDogMixcbiAgYXNzZXQ6IDMsXG4gIGZvcmNlX3NldHRsZW1lbnQ6IDQsXG4gIGNvbW1pdHRlZV9tZW1iZXI6IDUsXG4gIHdpdG5lc3M6IDYsXG4gIGxpbWl0X29yZGVyOiA3LFxuICBjYWxsX29yZGVyOiA4LFxuICBjdXN0b206IDksXG4gIHByb3Bvc2FsOiAxMCxcbiAgb3BlcmF0aW9uX2hpc3Rvcnk6IDExLFxuICB3aXRoZHJhd19wZXJtaXNzaW9uOiAxMixcbiAgdmVzdGluZ19iYWxhbmNlOiAxMyxcbiAgd29ya2VyOiAxNCxcbiAgYmFsYW5jZTogMTUsXG4gIHRvdXJuYW1lbnQ6IDE2LFxuICB0b3VybmFtZW50X2RldGFpbHM6IDE3LFxuICBtYXRjaDogMTgsXG4gIGdhbWU6IDE5LFxuICBzcG9ydDogMjAsXG4gIGV2ZW50X2dyb3VwOiAyMSxcbiAgZXZlbnQ6IDIyLFxuICBiZXR0aW5nX21hcmtldF9ydWxlczogMjMsXG4gIGJldHRpbmdfbWFya2V0X2dyb3VwOiAyNCxcbiAgYmV0dGluZ19tYXJrZXQ6IDI1LFxuICBiZXQ6IDI2XG59O1xuXG52YXIgaW1wbF9vYmplY3RfdHlwZSA9IHtcbiAgZ2xvYmFsX3Byb3BlcnR5OiAwLFxuICBkeW5hbWljX2dsb2JhbF9wcm9wZXJ0eTogMSxcbiAgcmVzZXJ2ZWQwOiAyLFxuICBhc3NldF9keW5hbWljX2RhdGE6IDMsXG4gIGFzc2V0X2JpdGFzc2V0X2RhdGE6IDQsXG4gIGFjY291bnRfYmFsYW5jZTogNSxcbiAgYWNjb3VudF9zdGF0aXN0aWNzOiA2LFxuICB0cmFuc2FjdGlvbjogNyxcbiAgYmxvY2tfc3VtbWFyeTogOCxcbiAgYWNjb3VudF90cmFuc2FjdGlvbl9oaXN0b3J5OiA5LFxuICBibGluZGVkX2JhbGFuY2U6IDEwLFxuICBjaGFpbl9wcm9wZXJ0eTogMTEsXG4gIHdpdG5lc3Nfc2NoZWR1bGU6IDEyLFxuICBidWRnZXRfcmVjb3JkOiAxMyxcbiAgc3BlY2lhbF9hdXRob3JpdHk6IDE0LFxuICBidXliYWNrOiAxNSxcbiAgZmJhX2FjY3VtdWxhdG9yOiAxNixcbiAgYmV0dGluZ19tYXJrZXRfcG9zaXRpb246IDE3LFxuICBnbG9iYWxfYmV0dGluZ19zdGF0aXN0aWNzOiAxOCxcbiAgYXNzZXRfZGl2aWRlbmRfZGF0YTogMTksXG4gIHBlbmRpbmdfZGl2aWRlbmRfcGF5b3V0X2JhbGFuY2VfZm9yX2hvbGRlcjogMjAsXG4gIGRpc3RyaWJ1dGVkX2RpdmlkZW5kX2JhbGFuY2VfZGF0YTogMjFcbn07XG5cbnZhciB2b3RlX3R5cGUgPSB7XG4gIGNvbW1pdHRlZTogMCxcbiAgd2l0bmVzczogMSxcbiAgd29ya2VyOiAyXG59O1xuXG52YXIgb3BlcmF0aW9ucyA9IHtcbiAgdHJhbnNmZXI6IDAsXG4gIGxpbWl0X29yZGVyX2NyZWF0ZTogMSxcbiAgbGltaXRfb3JkZXJfY2FuY2VsOiAyLFxuICBjYWxsX29yZGVyX3VwZGF0ZTogMyxcbiAgZmlsbF9vcmRlcjogNCxcbiAgYWNjb3VudF9jcmVhdGU6IDUsXG4gIGFjY291bnRfdXBkYXRlOiA2LFxuICBhY2NvdW50X3doaXRlbGlzdDogNyxcbiAgYWNjb3VudF91cGdyYWRlOiA4LFxuICBhY2NvdW50X3RyYW5zZmVyOiA5LFxuICBhc3NldF9jcmVhdGU6IDEwLFxuICBhc3NldF91cGRhdGU6IDExLFxuICBhc3NldF91cGRhdGVfYml0YXNzZXQ6IDEyLFxuICBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnM6IDEzLFxuICBhc3NldF9pc3N1ZTogMTQsXG4gIGFzc2V0X3Jlc2VydmU6IDE1LFxuICBhc3NldF9mdW5kX2ZlZV9wb29sOiAxNixcbiAgYXNzZXRfc2V0dGxlOiAxNyxcbiAgYXNzZXRfZ2xvYmFsX3NldHRsZTogMTgsXG4gIGFzc2V0X3B1Ymxpc2hfZmVlZDogMTksXG4gIHdpdG5lc3NfY3JlYXRlOiAyMCxcbiAgd2l0bmVzc191cGRhdGU6IDIxLFxuICBwcm9wb3NhbF9jcmVhdGU6IDIyLFxuICBwcm9wb3NhbF91cGRhdGU6IDIzLFxuICBwcm9wb3NhbF9kZWxldGU6IDI0LFxuICB3aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZTogMjUsXG4gIHdpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlOiAyNixcbiAgd2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbTogMjcsXG4gIHdpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlOiAyOCxcbiAgY29tbWl0dGVlX21lbWJlcl9jcmVhdGU6IDI5LFxuICBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZTogMzAsXG4gIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzOiAzMSxcbiAgdmVzdGluZ19iYWxhbmNlX2NyZWF0ZTogMzIsXG4gIHZlc3RpbmdfYmFsYW5jZV93aXRoZHJhdzogMzMsXG4gIHdvcmtlcl9jcmVhdGU6IDM0LFxuICBjdXN0b206IDM1LFxuICBhc3NlcnQ6IDM2LFxuICBiYWxhbmNlX2NsYWltOiAzNyxcbiAgb3ZlcnJpZGVfdHJhbnNmZXI6IDM4LFxuICB0cmFuc2Zlcl90b19ibGluZDogMzksXG4gIGJsaW5kX3RyYW5zZmVyOiA0MCxcbiAgdHJhbnNmZXJfZnJvbV9ibGluZDogNDEsXG4gIGFzc2V0X3NldHRsZV9jYW5jZWw6IDQyLFxuICBhc3NldF9jbGFpbV9mZWVzOiA0MyxcbiAgZmJhX2Rpc3RyaWJ1dGVfb3BlcmF0aW9uOiA0NCxcbiAgdG91cm5hbWVudF9jcmVhdGU6IDQ1LFxuICB0b3VybmFtZW50X2pvaW46IDQ2LFxuICBnYW1lX21vdmU6IDQ3LFxuICBhc3NldF91cGRhdGVfZGl2aWRlbmQ6IDQ4LFxuICBhc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb246IDQ5LFxuICB0b3VybmFtZW50X3BheW91dDogNTAsXG4gIHRvdXJuYW1lbnRfbGVhdmU6IDUxLFxuICBzcG9ydF9jcmVhdGU6IDUyLFxuICBzcG9ydF91cGRhdGU6IDUzLFxuICBldmVudF9ncm91cF9jcmVhdGU6IDU0LFxuICBldmVudF9ncm91cF91cGRhdGU6IDU1LFxuICBldmVudF9jcmVhdGU6IDU2LFxuICBldmVudF91cGRhdGU6IDU3LFxuICBiZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGU6IDU4LFxuICBiZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGU6IDU5LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGU6IDYwLFxuICBiZXR0aW5nX21hcmtldF9jcmVhdGU6IDYxLFxuICBiZXRfcGxhY2U6IDYyLFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlOiA2MyxcbiAgYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWQ6IDY0LFxuICBiZXRfYWRqdXN0ZWQ6IDY1LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWw6IDY2LFxuICBiZXRfbWF0Y2hlZDogNjcsXG4gIGJldF9jYW5jZWw6IDY4LFxuICBiZXRfY2FuY2VsZWQ6IDY5LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGU6IDcwLFxuICBiZXR0aW5nX21hcmtldF91cGRhdGU6IDcxLFxuICBldmVudF91cGRhdGVfc3RhdHVzOiA3MlxufTtcblxudmFyIENoYWluVHlwZXMgPSB7XG4gIHJlc2VydmVkX3NwYWNlczogcmVzZXJ2ZWRfc3BhY2VzLFxuICBvYmplY3RfdHlwZTogb2JqZWN0X3R5cGUsXG4gIGltcGxfb2JqZWN0X3R5cGU6IGltcGxfb2JqZWN0X3R5cGUsXG4gIHZvdGVfdHlwZTogdm90ZV90eXBlLFxuICBvcGVyYXRpb25zOiBvcGVyYXRpb25zXG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBDaGFpblR5cGVzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYnl0ZWJ1ZmZlciA9IHJlcXVpcmUoMzgpO1xuXG52YXIgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uID0gcmVxdWlyZSgyMSk7XG5cbnZhciBfU2VyaWFsaXplclZhbGlkYXRpb24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2VyaWFsaXplclZhbGlkYXRpb24pO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgREJfTUFYX0lOU1RBTkNFX0lEID0gX2J5dGVidWZmZXIuTG9uZy5mcm9tTnVtYmVyKE1hdGgucG93KDIsIDQ4KSAtIDEpO1xuXG52YXIgT2JqZWN0SWQgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIE9iamVjdElkKHNwYWNlLCB0eXBlLCBpbnN0YW5jZSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBPYmplY3RJZCk7XG5cbiAgICB0aGlzLnNwYWNlID0gc3BhY2U7XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB0aGlzLmluc3RhbmNlID0gaW5zdGFuY2U7XG4gICAgdmFyIGluc3RhbmNlX3N0cmluZyA9IHRoaXMuaW5zdGFuY2UudG9TdHJpbmcoKTtcbiAgICB2YXIgaWQgPSB0aGlzLnNwYWNlICsgJy4nICsgdGhpcy50eXBlICsgJy4nICsgaW5zdGFuY2Vfc3RyaW5nO1xuXG4gICAgaWYgKCFfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQuaXNfZGlnaXRzKGluc3RhbmNlX3N0cmluZykpIHtcbiAgICAgIHRocm93IG5ldyAoJ0ludmFsaWQgb2JqZWN0IGlkICcgKyBpZCkoKTtcbiAgICB9XG4gIH1cblxuICBPYmplY3RJZC5mcm9tU3RyaW5nID0gZnVuY3Rpb24gZnJvbVN0cmluZyh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZS5zcGFjZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLnR5cGUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZS5pbnN0YW5jZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdmFyIHBhcmFtcyA9IF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX21hdGNoKC9eKFswLTldKylcXC4oWzAtOV0rKVxcLihbMC05XSspJC8sIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZCh2YWx1ZSwgJ09iamVjdElkJyksICdPYmplY3RJZCcpO1xuICAgIHJldHVybiBuZXcgT2JqZWN0SWQocGFyc2VJbnQocGFyYW1zWzFdLCAxMCksIHBhcnNlSW50KHBhcmFtc1syXSwgMTApLCBfYnl0ZWJ1ZmZlci5Mb25nLmZyb21TdHJpbmcocGFyYW1zWzNdKSk7XG4gIH07XG5cbiAgT2JqZWN0SWQuZnJvbUxvbmcgPSBmdW5jdGlvbiBmcm9tTG9uZyhsb25nKSB7XG4gICAgdmFyIHNwYWNlID0gbG9uZy5zaGlmdFJpZ2h0KDU2KS50b0ludCgpO1xuICAgIHZhciB0eXBlID0gbG9uZy5zaGlmdFJpZ2h0KDQ4KS50b0ludCgpICYgMHgwMGZmOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgdmFyIGluc3RhbmNlID0gbG9uZy5hbmQoREJfTUFYX0lOU1RBTkNFX0lEKTtcbiAgICByZXR1cm4gbmV3IE9iamVjdElkKHNwYWNlLCB0eXBlLCBpbnN0YW5jZSk7XG4gIH07XG5cbiAgT2JqZWN0SWQuZnJvbUJ5dGVCdWZmZXIgPSBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIE9iamVjdElkLmZyb21Mb25nKGIucmVhZFVpbnQ2NCgpKTtcbiAgfTtcblxuICBPYmplY3RJZC5wcm90b3R5cGUudG9Mb25nID0gZnVuY3Rpb24gdG9Mb25nKCkge1xuICAgIHJldHVybiBfYnl0ZWJ1ZmZlci5Mb25nLmZyb21OdW1iZXIodGhpcy5zcGFjZSkuc2hpZnRMZWZ0KDU2KS5vcihfYnl0ZWJ1ZmZlci5Mb25nLmZyb21OdW1iZXIodGhpcy50eXBlKS5zaGlmdExlZnQoNDgpLm9yKHRoaXMuaW5zdGFuY2UpKTtcbiAgfTtcblxuICBPYmplY3RJZC5wcm90b3R5cGUuYXBwZW5kQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYikge1xuICAgIHJldHVybiBiLndyaXRlVWludDY0KHRoaXMudG9Mb25nKCkpO1xuICB9O1xuXG4gIE9iamVjdElkLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLnNwYWNlICsgJy4nICsgdGhpcy50eXBlICsgJy4nICsgdGhpcy5pbnN0YW5jZS50b1N0cmluZygpO1xuICB9O1xuXG4gIHJldHVybiBPYmplY3RJZDtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gT2JqZWN0SWQ7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfcGVlcnBsYXlzanNXcyA9IHJlcXVpcmUoJ3BlZXJwbGF5c2pzLXdzJyk7XG5cbnZhciBfZWNjID0gcmVxdWlyZSgnLi4vLi4vZWNjJyk7XG5cbnZhciBfc2VyaWFsaXplciA9IHJlcXVpcmUoJy4uLy4uL3NlcmlhbGl6ZXInKTtcblxudmFyIF9DaGFpblR5cGVzID0gcmVxdWlyZSgnLi9DaGFpblR5cGVzJyk7XG5cbnZhciBfQ2hhaW5UeXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpblR5cGVzKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIFRyYW5zYWN0aW9uQnVpbGRlciA9IGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gVHJhbnNhY3Rpb25CdWlsZGVyKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUcmFuc2FjdGlvbkJ1aWxkZXIpO1xuXG4gICAgdGhpcy5yZWZfYmxvY2tfbnVtID0gMDtcbiAgICB0aGlzLnJlZl9ibG9ja19wcmVmaXggPSAwO1xuICAgIHRoaXMuZXhwaXJhdGlvbiA9IDA7XG4gICAgdGhpcy5vcGVyYXRpb25zID0gW107XG4gICAgdGhpcy5zaWduYXR1cmVzID0gW107XG4gICAgdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzID0gW107XG5cbiAgICB0aGlzLmhlYWRfYmxvY2tfdGltZV9zdHJpbmcgPSBudWxsO1xuICAgIHRoaXMuY29tbWl0dGVlX21pbl9yZXZpZXcgPSBudWxsO1xuXG4gICAgLy8gc2VtaS1wcml2YXRlIG1ldGhvZCBiaW5kaW5nc1xuICAgIHRoaXMuX2Jyb2FkY2FzdCA9IHRoaXMuX2Jyb2FkY2FzdC5iaW5kKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAgICAgIEBhcmcge3N0cmluZ30gbmFtZSAtIGxpa2UgXCJ0cmFuc2ZlclwiXG4gICAgICAgIEBhcmcge29iamVjdH0gb3BlcmF0aW9uIC0gSlNPTiBtYXRjaGNoaW5nIHRoZSBvcGVyYXRpb24ncyBmb3JtYXRcbiAgICAqL1xuXG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5hZGRfdHlwZV9vcGVyYXRpb24gPSBmdW5jdGlvbiBhZGRfdHlwZV9vcGVyYXRpb24obmFtZSwgb3BlcmF0aW9uKSB7XG4gICAgdGhpcy5hZGRfb3BlcmF0aW9uKHRoaXMuZ2V0X3R5cGVfb3BlcmF0aW9uKG5hbWUsIG9wZXJhdGlvbikpO1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBUaGlzIGRvZXMgaXQgYWxsOiBzZXQgZmVlcywgZmluYWxpemUsIHNpZ24sIGFuZCBicm9hZGNhc3QgKGlmIHdhbnRlZCkuXG4gICAgICAgICBAYXJnIHtDb25maWRlbnRpYWxXYWxsZXR9IGN3YWxsZXQgLSBtdXN0IGJlIHVubG9ja2VkLCB1c2VkIHRvIGdhdGhlciBzaWduaW5nIGtleXNcbiAgICAgICAgIEBhcmcge2FycmF5PHN0cmluZz59IFtzaWduZXJfcHVia2V5cyA9IG51bGxdIC0gT3B0aW9uYWwgW1wiR1BIQWJjOURlZjAuLi5cIiwgLi4uXS4gIFRoZXNlIGFyZVxuICAgICAgICBhZGRpdGlvbmFsIHNpZ25pbmcga2V5cy4gIFNvbWUgYmFsYW5jZSBjbGFpbXMgcmVxdWlyZSBwcm9wcml0YXJ5IGFkZHJlc3MgZm9ybWF0cywgdGhlXG4gICAgICAgIHdpdG5lc3Mgbm9kZSBjYW4ndCB0ZWxsIHVzIHdoaWNoIG9uZXMgYXJlIG5lZWRlZCBzbyB0aGV5IG11c3QgYmUgcGFzc2VkIGluLiAgSWYgdGhlXG4gICAgICAgIHdpdG5lc3Mgbm9kZSBjYW4gZmlndXJlIG91dCBhIHNpZ25pbmcga2V5IChtb3N0bHkgYWxsIG90aGVyIHRyYW5zYWN0aW9ucyksIGl0IHNob3VsZFxuICAgICAgICBub3QgYmUgcGFzc2VkIGluIGhlcmUuXG4gICAgICAgICBAYXJnIHtib29sZWFufSBbYnJvYWRjYXN0ID0gZmFsc2VdXG4gICAgKi9cblxuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUucHJvY2Vzc190cmFuc2FjdGlvbiA9IGZ1bmN0aW9uIHByb2Nlc3NfdHJhbnNhY3Rpb24oY3dhbGxldCkge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgc2lnbmVyX3B1YmtleXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IG51bGw7XG4gICAgdmFyIGJyb2FkY2FzdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogZmFsc2U7XG4gICAgdmFyIHdhbGxldF9vYmplY3QgPSBjd2FsbGV0LndhbGxldC53YWxsZXRfb2JqZWN0O1xuXG5cbiAgICBpZiAoX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmNoYWluX2lkICE9PSB3YWxsZXRfb2JqZWN0LmdldCgnY2hhaW5faWQnKSkge1xuICAgICAgdmFyIHdhbGxldF9jaGFpbl9pZCA9IHdhbGxldF9vYmplY3QuZ2V0KCdjaGFpbl9pZCcpO1xuICAgICAgdmFyIGFwaV9jaGFpbl9pZCA9IF9wZWVycGxheXNqc1dzLkFwaXMuaW5zdGFuY2UoKS5jaGFpbl9pZDtcblxuICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdNaXNtYXRjaGVkIGNoYWluX2lkOyBleHBlY3RpbmcgJyArIHdhbGxldF9jaGFpbl9pZCArICcsIGJ1dCBnb3QgJyArIGFwaV9jaGFpbl9pZCk7XG5cbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc2V0X3JlcXVpcmVkX2ZlZXMoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBzaWduZXJfcHVia2V5c19hZGRlZCA9IHt9O1xuXG4gICAgICBpZiAoc2lnbmVyX3B1YmtleXMpIHtcbiAgICAgICAgLy8gQmFsYW5jZSBjbGFpbXMgYXJlIGJ5IGFkZHJlc3MsIG9ubHkgdGhlIHByaXZhdGVcbiAgICAgICAgLy8ga2V5IGhvbGRlciBjYW4ga25vdyBhYm91dCB0aGVzZSBhZGRpdGlvbmFsXG4gICAgICAgIC8vIHBvdGVudGlhbCBrZXlzLlxuICAgICAgICB2YXIgcHVia2V5cyA9IGN3YWxsZXQuZ2V0UHVia2V5c19oYXZpbmdfUHJpdmF0ZUtleShzaWduZXJfcHVia2V5cyk7XG5cbiAgICAgICAgaWYgKCFwdWJrZXlzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzaWduaW5nIGtleScpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhwdWJrZXlzKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0ga2V5cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIHZhciBwdWJrZXlfc3RyaW5nID0gcHVia2V5c1tpXTtcbiAgICAgICAgICB2YXIgcHJpdmF0ZV9rZXkgPSBjd2FsbGV0LmdldFByaXZhdGVLZXkocHVia2V5X3N0cmluZyk7XG4gICAgICAgICAgX3RoaXMuYWRkX3NpZ25lcihwcml2YXRlX2tleSwgcHVia2V5X3N0cmluZyk7XG4gICAgICAgICAgc2lnbmVyX3B1YmtleXNfYWRkZWRbcHVia2V5X3N0cmluZ10gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBfdGhpcy5nZXRfcG90ZW50aWFsX3NpZ25hdHVyZXMoKS50aGVuKGZ1bmN0aW9uIChfcmVmKSB7XG4gICAgICAgIHZhciBwdWJrZXlzID0gX3JlZi5wdWJrZXlzLFxuICAgICAgICAgICAgYWRkeXMgPSBfcmVmLmFkZHlzO1xuXG4gICAgICAgIHZhciBteV9wdWJrZXlzID0gY3dhbGxldC5nZXRQdWJrZXlzX2hhdmluZ19Qcml2YXRlS2V5KHB1YmtleXMsIGFkZHlzKTtcblxuICAgICAgICByZXR1cm4gX3RoaXMuZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMobXlfcHVia2V5cykudGhlbihmdW5jdGlvbiAocmVxdWlyZWRfcHVia2V5cykge1xuICAgICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMocmVxdWlyZWRfcHVia2V5cyk7XG5cbiAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9sZW4gPSBrZXlzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgICAgICB2YXIgX3B1YmtleV9zdHJpbmcgPSBrZXlzW19pXTtcblxuICAgICAgICAgICAgaWYgKCFzaWduZXJfcHVia2V5c19hZGRlZFtfcHVia2V5X3N0cmluZ10pIHtcbiAgICAgICAgICAgICAgdmFyIF9wcml2YXRlX2tleSA9IGN3YWxsZXQuZ2V0UHJpdmF0ZUtleShfcHVia2V5X3N0cmluZyk7XG5cbiAgICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgbm90IGhhcHBlbiwgZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMgd2lsbCBvbmx5XG4gICAgICAgICAgICAgIC8vIHJldHVybmVkIGtleXMgZnJvbSBteV9wdWJrZXlzXG4gICAgICAgICAgICAgIGlmICghX3ByaXZhdGVfa2V5KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHNpZ25pbmcga2V5IGZvciAnICsgX3B1YmtleV9zdHJpbmcpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgX3RoaXMuYWRkX3NpZ25lcihfcHJpdmF0ZV9rZXksIF9wdWJrZXlfc3RyaW5nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBicm9hZGNhc3QgPyBfdGhpcy5icm9hZGNhc3QoKSA6IF90aGlzLnNlcmlhbGl6ZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqIFR5cGljYWxseSB0aGlzIGlzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IGp1c3QgcHJpb3IgdG8gc2lnbmluZy5cbiAgICogT25jZSBmaW5hbGl6ZWQgdGhpcyB0cmFuc2FjdGlvbiBjYW4gbm90IGJlIGNoYW5nZWQuICovXG5cblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLmZpbmFsaXplID0gZnVuY3Rpb24gZmluYWxpemUoKSB7XG4gICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgIGlmIChfdGhpczIudHJfYnVmZmVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBmaW5hbGl6ZWQnKTtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZShfcGVlcnBsYXlzanNXcy5BcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYygnZ2V0X29iamVjdHMnLCBbWycyLjEuMCddXSkudGhlbihmdW5jdGlvbiAocikge1xuICAgICAgICBfdGhpczIuaGVhZF9ibG9ja190aW1lX3N0cmluZyA9IHJbMF0udGltZTtcblxuICAgICAgICBpZiAoX3RoaXMyLmV4cGlyYXRpb24gPT09IDApIHtcbiAgICAgICAgICBfdGhpczIuZXhwaXJhdGlvbiA9IF90aGlzMi5iYXNlX2V4cGlyYXRpb25fc2VjKCkgKyBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5leHBpcmVfaW5fc2VjcztcbiAgICAgICAgfVxuXG4gICAgICAgIF90aGlzMi5yZWZfYmxvY2tfbnVtID0gclswXS5oZWFkX2Jsb2NrX251bWJlciAmIDB4ZmZmZjsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgICBfdGhpczIucmVmX2Jsb2NrX3ByZWZpeCA9IEJ1ZmZlci5mcm9tKHJbMF0uaGVhZF9ibG9ja19pZCwgJ2hleCcpLnJlYWRVSW50MzJMRSg0KTtcbiAgICAgICAgLy8gREVCVUcgY29uc29sZS5sb2coXCJyZWZfYmxvY2tcIixAcmVmX2Jsb2NrX251bSxAcmVmX2Jsb2NrX3ByZWZpeCxyKVxuXG4gICAgICAgIHZhciBpdGVyYWJsZSA9IF90aGlzMi5vcGVyYXRpb25zO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBpdGVyYWJsZS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIHZhciBvcCA9IGl0ZXJhYmxlW2ldO1xuXG4gICAgICAgICAgaWYgKG9wWzFdLmZpbmFsaXplKSB7XG4gICAgICAgICAgICBvcFsxXS5maW5hbGl6ZSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfdHlwZSA9IF9zZXJpYWxpemVyLm9wcy5vcGVyYXRpb24uc3Rfb3BlcmF0aW9uc1tvcFswXV07XG4gICAgICAgICAgdmFyIGhleEJ1ZmZlciA9IF90eXBlLnRvQnVmZmVyKG9wWzFdKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ09wZXJhdGlvbiAlczogJU8gPT4gJXMgKCVkIGJ5dGVzKScsIF90eXBlLm9wZXJhdGlvbl9uYW1lLCBvcFsxXSwgaGV4QnVmZmVyLCBoZXhCdWZmZXIubGVuZ3RoIC8gMik7XG4gICAgICAgIH1cblxuICAgICAgICBfdGhpczIudHJfYnVmZmVyID0gX3NlcmlhbGl6ZXIub3BzLnRyYW5zYWN0aW9uLnRvQnVmZmVyKF90aGlzMik7XG4gICAgICB9KSk7XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqIEByZXR1cm4ge3N0cmluZ30gaGV4IHRyYW5zYWN0aW9uIElEICovXG5cblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLmlkID0gZnVuY3Rpb24gaWQoKSB7XG4gICAgaWYgKCF0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgZmluYWxpemVkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9lY2MuaGFzaC5zaGEyNTYodGhpcy50cl9idWZmZXIpLnRvU3RyaW5nKCdoZXgnKS5zdWJzdHJpbmcoMCwgNDApO1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBUeXBpY2FsbHkgb25lIHdpbGwgdXNlIHtAbGluayB0aGlzLmFkZF90eXBlX29wZXJhdGlvbn0gaW5zdGVhZC5cbiAgICAgICAgQGFyZyB7YXJyYXl9IG9wZXJhdGlvbiAtIFtvcGVyYXRpb25faWQsIG9wZXJhdGlvbl1cbiAgICAqL1xuXG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5hZGRfb3BlcmF0aW9uID0gZnVuY3Rpb24gYWRkX29wZXJhdGlvbihvcGVyYXRpb24pIHtcbiAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBmaW5hbGl6ZWQnKTtcbiAgICB9XG5cbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkob3BlcmF0aW9uLCAnb3BlcmF0aW9uJyk7XG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkob3BlcmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RpbmcgYXJyYXkgW29wZXJhdGlvbl9pZCwgb3BlcmF0aW9uXScpO1xuICAgIH1cblxuICAgIHRoaXMub3BlcmF0aW9ucy5wdXNoKG9wZXJhdGlvbik7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5nZXRfdHlwZV9vcGVyYXRpb24gPSBmdW5jdGlvbiBnZXRfdHlwZV9vcGVyYXRpb24obmFtZSwgb3BlcmF0aW9uKSB7XG4gICAgaWYgKHRoaXMudHJfYnVmZmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FscmVhZHkgZmluYWxpemVkJyk7XG4gICAgfVxuXG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKG5hbWUsICduYW1lJyk7XG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKG9wZXJhdGlvbiwgJ29wZXJhdGlvbicpO1xuICAgIHZhciBfdHlwZSA9IF9zZXJpYWxpemVyLm9wc1tuYW1lXTtcbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoX3R5cGUsICdVbmtub3duIG9wZXJhdGlvbiAnICsgbmFtZSk7XG4gICAgdmFyIG9wZXJhdGlvbl9pZCA9IF9DaGFpblR5cGVzMi5kZWZhdWx0Lm9wZXJhdGlvbnNbX3R5cGUub3BlcmF0aW9uX25hbWVdO1xuXG4gICAgaWYgKG9wZXJhdGlvbl9pZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gb3BlcmF0aW9uOiAnICsgX3R5cGUub3BlcmF0aW9uX25hbWUpO1xuICAgIH1cblxuICAgIGlmICghb3BlcmF0aW9uLmZlZSkge1xuICAgICAgb3BlcmF0aW9uLmZlZSA9IHsgYW1vdW50OiAwLCBhc3NldF9pZDogMCB9O1xuICAgIH1cblxuICAgIGlmIChuYW1lID09PSAncHJvcG9zYWxfY3JlYXRlJykge1xuICAgICAgLypcbiAgICAgICAgICAgICogUHJvcG9zYWxzIGludm9sdmluZyB0aGUgY29tbWl0dGVlIGFjY291bnQgcmVxdWlyZSBhIHJldmlld1xuICAgICAgICAgICAgKiBwZXJpb2QgdG8gYmUgc2V0LCBsb29rIGZvciB0aGVtIGhlcmVcbiAgICAgICAgICAgICovXG4gICAgICB2YXIgcmVxdWlyZXNSZXZpZXcgPSBmYWxzZTtcbiAgICAgIHZhciBleHRyYVJldmlldyA9IDA7XG5cbiAgICAgIG9wZXJhdGlvbi5wcm9wb3NlZF9vcHMuZm9yRWFjaChmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgdmFyIENPTU1JVFRFX0FDQ09VTlQgPSAwO1xuICAgICAgICB2YXIga2V5ID0gdm9pZCAwO1xuXG4gICAgICAgIHN3aXRjaCAob3Aub3BbMF0pIHtcbiAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAvLyB0cmFuc2ZlclxuICAgICAgICAgICAga2V5ID0gJ2Zyb20nO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDY6IC8vIGFjY291bnRfdXBkYXRlXG4gICAgICAgICAgY2FzZSAxNzpcbiAgICAgICAgICAgIC8vIGFzc2V0X3NldHRsZVxuICAgICAgICAgICAga2V5ID0gJ2FjY291bnQnO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDEwOiAvLyBhc3NldF9jcmVhdGVcbiAgICAgICAgICBjYXNlIDExOiAvLyBhc3NldF91cGRhdGVcbiAgICAgICAgICBjYXNlIDEyOiAvLyBhc3NldF91cGRhdGVfYml0YXNzZXRcbiAgICAgICAgICBjYXNlIDEzOiAvLyBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnNcbiAgICAgICAgICBjYXNlIDE0OiAvLyBhc3NldF9pc3N1ZVxuICAgICAgICAgIGNhc2UgMTg6IC8vIGFzc2V0X2dsb2JhbF9zZXR0bGVcbiAgICAgICAgICBjYXNlIDQzOlxuICAgICAgICAgICAgLy8gYXNzZXRfY2xhaW1fZmVlc1xuICAgICAgICAgICAga2V5ID0gJ2lzc3Vlcic7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgMTU6XG4gICAgICAgICAgICAvLyBhc3NldF9yZXNlcnZlXG4gICAgICAgICAgICBrZXkgPSAncGF5ZXInO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDE2OlxuICAgICAgICAgICAgLy8gYXNzZXRfZnVuZF9mZWVfcG9vbFxuICAgICAgICAgICAga2V5ID0gJ2Zyb21fYWNjb3VudCc7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgMjI6IC8vIHByb3Bvc2FsX2NyZWF0ZVxuICAgICAgICAgIGNhc2UgMjM6IC8vIHByb3Bvc2FsX3VwZGF0ZVxuICAgICAgICAgIGNhc2UgMjQ6XG4gICAgICAgICAgICAvLyBwcm9wb3NhbF9kZWxldGVcbiAgICAgICAgICAgIGtleSA9ICdmZWVfcGF5aW5nX2FjY291bnQnO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIDMxOlxuICAgICAgICAgICAgLy8gY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnNcbiAgICAgICAgICAgIHJlcXVpcmVzUmV2aWV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGV4dHJhUmV2aWV3ID0gNjAgKiA2MCAqIDI0ICogMTM7IC8vIE1ha2UgdGhlIHJldmlldyBwZXJpb2QgMiB3ZWVrcyB0b3RhbFxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGtleSBpbiBvcC5vcFsxXSAmJiBvcC5vcFsxXVtrZXldID09PSBDT01NSVRURV9BQ0NPVU5UKSB7XG4gICAgICAgICAgcmVxdWlyZXNSZXZpZXcgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKCFvcGVyYXRpb24uZXhwaXJhdGlvbl90aW1lKSB7XG4gICAgICAgIHZhciBleHBlcmF0aW9uVGltZSA9IHRoaXMuYmFzZV9leHBpcmF0aW9uX3NlYygpO1xuICAgICAgICBvcGVyYXRpb24uZXhwaXJhdGlvbl90aW1lID0gZXhwZXJhdGlvblRpbWUgKyBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5leHBpcmVfaW5fc2Vjc19wcm9wb3NhbDtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcXVpcmVzUmV2aWV3KSB7XG4gICAgICAgIHZhciBvbmVfZGF5ID0gMjQgKiA2MCAqIDYwOyAvLyBPbmUgZGF5IGluIHNlY29uZHNcbiAgICAgICAgdmFyIG1heCA9IE1hdGgubWF4KHRoaXMuY29tbWl0ZWVfbWluX3Jldmlldywgb25lX2RheSwgX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcucmV2aWV3X2luX3NlY3NfY29tbWl0dGVlKTtcblxuICAgICAgICBvcGVyYXRpb24ucmV2aWV3X3BlcmlvZF9zZWNvbmRzID0gZXh0cmFSZXZpZXcgKyBtYXg7XG4gICAgICAgIC8qXG4gICAgICAgICAgICAgICAgKiBFeHBpcmF0aW9uIHRpbWUgbXVzdCBiZSBhdCBsZWFzdCBlcXVhbCB0b1xuICAgICAgICAgICAgICAgICogbm93ICsgcmV2aWV3X3BlcmlvZF9zZWNvbmRzLCBzbyB3ZSBhZGQgb25lIGhvdXIgdG8gbWFrZSBzdXJlXG4gICAgICAgICAgICAgICAgKi9cbiAgICAgICAgb3BlcmF0aW9uLmV4cGlyYXRpb25fdGltZSArPSA2MCAqIDYwICsgZXh0cmFSZXZpZXc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIG9wZXJhdGlvbl9pbnN0YW5jZSA9IF90eXBlLmZyb21PYmplY3Qob3BlcmF0aW9uKTtcbiAgICByZXR1cm4gW29wZXJhdGlvbl9pZCwgb3BlcmF0aW9uX2luc3RhbmNlXTtcbiAgfTtcblxuICAvKiBvcHRpb25hbDogZmV0Y2ggdGhlIGN1cnJlbnQgaGVhZCBibG9jayAqL1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUudXBkYXRlX2hlYWRfYmxvY2sgPSBmdW5jdGlvbiB1cGRhdGVfaGVhZF9ibG9jaygpIHtcbiAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgIHJldHVybiBfcGVlcnBsYXlzanNXcy5BcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYygnZ2V0X29iamVjdHMnLCBbWycyLjAuMCcsICcyLjEuMCddXSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICB2YXIgZyA9IHJlc1swXSxcbiAgICAgICAgICByID0gcmVzWzFdO1xuXG4gICAgICBfdGhpczMuaGVhZF9ibG9ja190aW1lX3N0cmluZyA9IHJbMF0udGltZTtcbiAgICAgIF90aGlzMy5jb21taXR0ZWVfbWluX3JldmlldyA9IGdbMF0ucGFyYW1ldGVycy5jb21taXR0ZWVfcHJvcG9zYWxfcmV2aWV3X3BlcmlvZDtcbiAgICB9KTtcbiAgfTtcblxuICAvKiogb3B0aW9uYWw6IHRoZXJlIGlzIGEgZGVhZnVsdCBleHBpcmF0aW9uICovXG5cblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLnNldF9leHBpcmVfc2Vjb25kcyA9IGZ1bmN0aW9uIHNldF9leHBpcmVfc2Vjb25kcyhzZWMpIHtcbiAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBmaW5hbGl6ZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLmV4cGlyYXRpb24gPSB0aGlzLmJhc2VfZXhwaXJhdGlvbl9zZWMoKSArIHNlYztcblxuICAgIHJldHVybiB0aGlzLmV4cGlyYXRpb247XG4gIH07XG5cbiAgLyogV3JhcHMgdGhpcyB0cmFuc2FjdGlvbiBpbiBhIHByb3Bvc2FsX2NyZWF0ZSB0cmFuc2FjdGlvbiAqL1xuXG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5wcm9wb3NlID0gZnVuY3Rpb24gcHJvcG9zZShwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucykge1xuICAgIGlmICh0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhbHJlYWR5IGZpbmFsaXplZCcpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5vcGVyYXRpb25zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhZGQgb3BlcmF0aW9uIGZpcnN0Jyk7XG4gICAgfVxuXG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKHByb3Bvc2FsX2NyZWF0ZV9vcHRpb25zLCAncHJvcG9zYWxfY3JlYXRlX29wdGlvbnMnKTtcbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkocHJvcG9zYWxfY3JlYXRlX29wdGlvbnMuZmVlX3BheWluZ19hY2NvdW50LCAncHJvcG9zYWxfY3JlYXRlX29wdGlvbnMuZmVlX3BheWluZ19hY2NvdW50Jyk7XG5cbiAgICB2YXIgcHJvcG9zZWRfb3BzID0gdGhpcy5vcGVyYXRpb25zLm1hcChmdW5jdGlvbiAob3ApIHtcbiAgICAgIHJldHVybiB7IG9wOiBvcCB9O1xuICAgIH0pO1xuXG4gICAgdGhpcy5vcGVyYXRpb25zID0gW107XG4gICAgdGhpcy5zaWduYXR1cmVzID0gW107XG4gICAgdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzID0gW107XG4gICAgcHJvcG9zYWxfY3JlYXRlX29wdGlvbnMucHJvcG9zZWRfb3BzID0gcHJvcG9zZWRfb3BzO1xuICAgIHRoaXMuYWRkX3R5cGVfb3BlcmF0aW9uKCdwcm9wb3NhbF9jcmVhdGUnLCBwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5oYXNfcHJvcG9zZWRfb3BlcmF0aW9uID0gZnVuY3Rpb24gaGFzX3Byb3Bvc2VkX29wZXJhdGlvbigpIHtcbiAgICB2YXIgaGFzUHJvcG9zZWQgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5vcGVyYXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoJ3Byb3Bvc2VkX29wcycgaW4gdGhpcy5vcGVyYXRpb25zW2ldWzFdKSB7XG4gICAgICAgIGhhc1Byb3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGhhc1Byb3Bvc2VkO1xuICB9O1xuXG4gIC8qKiBvcHRpb25hbDogdGhlIGZlZXMgY2FuIGJlIG9idGFpbmVkIGZyb20gdGhlIHdpdG5lc3Mgbm9kZSAqL1xuXG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5zZXRfcmVxdWlyZWRfZmVlcyA9IGZ1bmN0aW9uIHNldF9yZXF1aXJlZF9mZWVzKGFzc2V0X2lkKSB7XG4gICAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgICB2YXIgZmVlX3Bvb2wgPSB2b2lkIDA7XG5cbiAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBmaW5hbGl6ZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMub3BlcmF0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWRkIG9wZXJhdGlvbnMgZmlyc3QnKTtcbiAgICB9XG5cbiAgICB2YXIgb3BlcmF0aW9ucyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMub3BlcmF0aW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgdmFyIG9wID0gdGhpcy5vcGVyYXRpb25zW2ldO1xuICAgICAgb3BlcmF0aW9ucy5wdXNoKF9zZXJpYWxpemVyLm9wcy5vcGVyYXRpb24udG9PYmplY3Qob3ApKTtcbiAgICB9XG5cbiAgICBpZiAoIWFzc2V0X2lkKSB7XG4gICAgICB2YXIgb3AxX2ZlZSA9IG9wZXJhdGlvbnNbMF1bMV0uZmVlO1xuXG4gICAgICBpZiAob3AxX2ZlZSAmJiBvcDFfZmVlLmFzc2V0X2lkICE9PSBudWxsKSB7XG4gICAgICAgIGFzc2V0X2lkID0gb3AxX2ZlZS5hc3NldF9pZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFzc2V0X2lkID0gJzEuMy4wJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZXMgPSBbX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoJ2dldF9yZXF1aXJlZF9mZWVzJywgW29wZXJhdGlvbnMsIGFzc2V0X2lkXSldO1xuXG4gICAgaWYgKGFzc2V0X2lkICE9PSAnMS4zLjAnKSB7XG4gICAgICAvLyBUaGlzIGhhbmRsZXMgdGhlIGZhbGxiYWNrIHRvIHBheWluZyBmZWVzIGluIEJUUyBpZiB0aGUgZmVlIHBvb2wgaXMgZW1wdHkuXG4gICAgICBwcm9taXNlcy5wdXNoKF9wZWVycGxheXNqc1dzLkFwaXMuaW5zdGFuY2UoKS5kYl9hcGkoKS5leGVjKCdnZXRfcmVxdWlyZWRfZmVlcycsIFtvcGVyYXRpb25zLCAnMS4zLjAnXSkpO1xuICAgICAgcHJvbWlzZXMucHVzaChfcGVlcnBsYXlzanNXcy5BcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYygnZ2V0X29iamVjdHMnLCBbW2Fzc2V0X2lkXV0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oZnVuY3Rpb24gKHJlc3VsdHMpIHtcbiAgICAgIHZhciBmZWVzID0gcmVzdWx0c1swXSxcbiAgICAgICAgICBjb3JlRmVlcyA9IHJlc3VsdHNbMV0sXG4gICAgICAgICAgYXNzZXQgPSByZXN1bHRzWzJdO1xuXG4gICAgICBhc3NldCA9IGFzc2V0ID8gYXNzZXRbMF0gOiBudWxsO1xuXG4gICAgICB2YXIgZHluYW1pY1Byb21pc2UgPSBhc3NldF9pZCAhPT0gJzEuMy4wJyAmJiBhc3NldCA/IF9wZWVycGxheXNqc1dzLkFwaXMuaW5zdGFuY2UoKS5kYl9hcGkoKS5leGVjKCdnZXRfb2JqZWN0cycsIFtbYXNzZXQuZHluYW1pY19hc3NldF9kYXRhX2lkXV0pIDogbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBkeW5hbWljUHJvbWlzZS50aGVuKGZ1bmN0aW9uIChkeW5hbWljT2JqZWN0KSB7XG4gICAgICAgIGlmIChhc3NldF9pZCAhPT0gJzEuMy4wJykge1xuICAgICAgICAgIGZlZV9wb29sID0gZHluYW1pY09iamVjdCA/IGR5bmFtaWNPYmplY3RbMF0uZmVlX3Bvb2wgOiAwO1xuICAgICAgICAgIHZhciB0b3RhbEZlZXMgPSAwO1xuXG4gICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGZlZTsgaiA8IGNvcmVGZWVzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBmZWUgPSBjb3JlRmVlc1tqXTtcbiAgICAgICAgICAgIHRvdGFsRmVlcyArPSBmZWUuYW1vdW50O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0b3RhbEZlZXMgPiBwYXJzZUludChmZWVfcG9vbCwgMTApKSB7XG4gICAgICAgICAgICBmZWVzID0gY29yZUZlZXM7XG4gICAgICAgICAgICBhc3NldF9pZCA9ICcxLjMuMCc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvcG9zZWQgdHJhbnNhY3Rpb25zIG5lZWQgdG8gYmUgZmxhdHRlbmVkXG4gICAgICAgIHZhciBmbGF0X2Fzc2V0cyA9IFtdO1xuXG4gICAgICAgIHZhciBmbGF0dGVuID0gZnVuY3Rpb24gZmxhdHRlbihvYmopIHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBrID0gMCwgX2xlbjIgPSBvYmoubGVuZ3RoOyBrIDwgX2xlbjI7IGsrKykge1xuICAgICAgICAgICAgICB2YXIgaXRlbSA9IG9ialtrXTtcbiAgICAgICAgICAgICAgZmxhdHRlbihpdGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmxhdF9hc3NldHMucHVzaChvYmopO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBmbGF0dGVuKGZlZXMpO1xuXG4gICAgICAgIHZhciBhc3NldF9pbmRleCA9IDA7XG5cbiAgICAgICAgdmFyIHNldF9mZWUgPSBmdW5jdGlvbiBzZXRfZmVlKG9wZXJhdGlvbikge1xuICAgICAgICAgIGlmICghb3BlcmF0aW9uLmZlZSB8fCBvcGVyYXRpb24uZmVlLmFtb3VudCA9PT0gMCB8fCBvcGVyYXRpb24uZmVlLmFtb3VudC50b1N0cmluZyAmJiBvcGVyYXRpb24uZmVlLmFtb3VudC50b1N0cmluZygpID09PSAnMCcgLy8gTG9uZ1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgICBvcGVyYXRpb24uZmVlID0gZmxhdF9hc3NldHNbYXNzZXRfaW5kZXhdO1xuICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIm5ldyBvcGVyYXRpb24uZmVlXCIsIG9wZXJhdGlvbi5mZWUpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIm9sZCBvcGVyYXRpb24uZmVlXCIsIG9wZXJhdGlvbi5mZWUpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBhc3NldF9pbmRleCsrO1xuXG4gICAgICAgICAgaWYgKG9wZXJhdGlvbi5wcm9wb3NlZF9vcHMpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgICAgICAgICAgZm9yICh2YXIgeSA9IDA7IHkgPCBvcGVyYXRpb24ucHJvcG9zZWRfb3BzLmxlbmd0aDsgeSsrKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHNldF9mZWUob3BlcmF0aW9uLnByb3Bvc2VkX29wc1t5XS5vcFsxXSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBmb3IgKHZhciBfaTIgPSAwOyBfaTIgPCBfdGhpczQub3BlcmF0aW9ucy5sZW5ndGg7IF9pMisrKSB7XG4gICAgICAgICAgc2V0X2ZlZShfdGhpczQub3BlcmF0aW9uc1tfaTJdWzFdKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBERUJVRyBjb25zb2xlLmxvZygnLi4uIGdldF9yZXF1aXJlZF9mZWVzJyxvcGVyYXRpb25zLGFzc2V0X2lkLGZsYXRfYXNzZXRzKVxuICAgIH0pO1xuICB9O1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuZ2V0X3BvdGVudGlhbF9zaWduYXR1cmVzID0gZnVuY3Rpb24gZ2V0X3BvdGVudGlhbF9zaWduYXR1cmVzKCkge1xuICAgIHZhciB0cl9vYmplY3QgPSBfc2VyaWFsaXplci5vcHMuc2lnbmVkX3RyYW5zYWN0aW9uLnRvT2JqZWN0KHRoaXMpO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChbX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoJ2dldF9wb3RlbnRpYWxfc2lnbmF0dXJlcycsIFt0cl9vYmplY3RdKSwgX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoJ2dldF9wb3RlbnRpYWxfYWRkcmVzc19zaWduYXR1cmVzJywgW3RyX29iamVjdF0pXSkudGhlbihmdW5jdGlvbiAocmVzdWx0cykge1xuICAgICAgcmV0dXJuIHsgcHVia2V5czogcmVzdWx0c1swXSwgYWRkeXM6IHJlc3VsdHNbMV0gfTtcbiAgICB9KTtcbiAgfTtcblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLmdldF9yZXF1aXJlZF9zaWduYXR1cmVzID0gZnVuY3Rpb24gZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMoYXZhaWxhYmxlX2tleXMpIHtcbiAgICBpZiAoIWF2YWlsYWJsZV9rZXlzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbXSk7XG4gICAgfVxuXG4gICAgdmFyIHRyX29iamVjdCA9IF9zZXJpYWxpemVyLm9wcy5zaWduZWRfdHJhbnNhY3Rpb24udG9PYmplY3QodGhpcyk7XG4gICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiB0cl9vYmplY3QnLHRyX29iamVjdClcbiAgICByZXR1cm4gX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoJ2dldF9yZXF1aXJlZF9zaWduYXR1cmVzJywgW3RyX29iamVjdCwgYXZhaWxhYmxlX2tleXNdKS50aGVuKGZ1bmN0aW9uIChyZXF1aXJlZF9wdWJsaWNfa2V5cykge1xuICAgICAgcmV0dXJuIHJlcXVpcmVkX3B1YmxpY19rZXlzO1xuICAgIH0pO1xuICB9O1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuYWRkX3NpZ25lciA9IGZ1bmN0aW9uIGFkZF9zaWduZXIocHJpdmF0ZV9rZXkpIHtcbiAgICB2YXIgcHVibGljX2tleSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKTtcblxuICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShwcml2YXRlX2tleS5kLCAncmVxdWlyZWQgUHJpdmF0ZUtleSBvYmplY3QnKTtcblxuICAgIGlmICh0aGlzLnNpZ25lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhbHJlYWR5IHNpZ25lZCcpO1xuICAgIH1cblxuICAgIGlmICghcHVibGljX2tleS5RKSB7XG4gICAgICBwdWJsaWNfa2V5ID0gX2VjYy5QdWJsaWNLZXkuZnJvbVB1YmxpY0tleVN0cmluZyhwdWJsaWNfa2V5KTtcbiAgICB9XG5cbiAgICAvLyBwcmV2ZW50IGR1cGxpY2F0ZXNcbiAgICB2YXIgc3BIZXggPSBwcml2YXRlX2tleS50b0hleCgpO1xuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzLnNpZ25lcl9wcml2YXRlX2tleXMpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGtleXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBzcCA9IHRoaXMuc2lnbmVyX3ByaXZhdGVfa2V5c1trZXlzW2ldXTtcblxuICAgICAgaWYgKHNwWzBdLnRvSGV4KCkgPT09IHNwSGV4KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnNpZ25lcl9wcml2YXRlX2tleXMucHVzaChbcHJpdmF0ZV9rZXksIHB1YmxpY19rZXldKTtcbiAgfTtcblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbiBzaWduKCkge1xuICAgIHZhciBjaGFpbl9pZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLmNoYWluX2lkO1xuXG4gICAgaWYgKCF0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3QgZmluYWxpemVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2lnbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FscmVhZHkgc2lnbmVkJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnNpZ25lcl9wcml2YXRlX2tleXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zYWN0aW9uIHdhcyBub3Qgc2lnbmVkLiBEbyB5b3UgaGF2ZSBhIHByaXZhdGUga2V5PyBbbm9fc2lnbmVyc10nKTtcbiAgICB9XG5cbiAgICB2YXIgZW5kID0gdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzLmxlbmd0aDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBlbmQgPiAwID8gaSA8IGVuZCA6IGkgPiBlbmQ7IGVuZCA+IDAgPyBpKysgOiBpKyspIHtcbiAgICAgIHZhciBfc2lnbmVyX3ByaXZhdGVfa2V5cyQgPSB0aGlzLnNpZ25lcl9wcml2YXRlX2tleXNbaV0sXG4gICAgICAgICAgcHJpdmF0ZV9rZXkgPSBfc2lnbmVyX3ByaXZhdGVfa2V5cyRbMF0sXG4gICAgICAgICAgcHVibGljX2tleSA9IF9zaWduZXJfcHJpdmF0ZV9rZXlzJFsxXTtcblxuICAgICAgdmFyIHNpZyA9IF9lY2MuU2lnbmF0dXJlLnNpZ25CdWZmZXIoQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oY2hhaW5faWQsICdoZXgnKSwgdGhpcy50cl9idWZmZXJdKSwgcHJpdmF0ZV9rZXksIHB1YmxpY19rZXkpO1xuICAgICAgdGhpcy5zaWduYXR1cmVzLnB1c2goc2lnLnRvQnVmZmVyKCkpO1xuICAgIH1cblxuICAgIHRoaXMuc2lnbmVyX3ByaXZhdGVfa2V5cyA9IFtdO1xuICAgIHRoaXMuc2lnbmVkID0gdHJ1ZTtcbiAgfTtcblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLnNlcmlhbGl6ZSA9IGZ1bmN0aW9uIHNlcmlhbGl6ZSgpIHtcbiAgICByZXR1cm4gX3NlcmlhbGl6ZXIub3BzLnNpZ25lZF90cmFuc2FjdGlvbi50b09iamVjdCh0aGlzKTtcbiAgfTtcblxuICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QoKSB7XG4gICAgcmV0dXJuIF9zZXJpYWxpemVyLm9wcy5zaWduZWRfdHJhbnNhY3Rpb24udG9PYmplY3QodGhpcyk7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5icm9hZGNhc3QgPSBmdW5jdGlvbiBicm9hZGNhc3Qod2FzX2Jyb2FkY2FzdF9jYWxsYmFjaykge1xuICAgIHZhciBfdGhpczUgPSB0aGlzO1xuXG4gICAgaWYgKHRoaXMudHJfYnVmZmVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYnJvYWRjYXN0KHdhc19icm9hZGNhc3RfY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZpbmFsaXplKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gX3RoaXM1Ll9icm9hZGNhc3Qod2FzX2Jyb2FkY2FzdF9jYWxsYmFjayk7XG4gICAgfSk7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5fYnJvYWRjYXN0ID0gZnVuY3Rpb24gX2Jyb2FkY2FzdCh3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKSB7XG4gICAgdmFyIF90aGlzNiA9IHRoaXM7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgaWYgKCFfdGhpczYuc2lnbmVkKSB7XG4gICAgICAgIF90aGlzNi5zaWduKCk7XG4gICAgICB9XG5cbiAgICAgIGlmICghX3RoaXM2LnRyX2J1ZmZlcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vdCBmaW5hbGl6ZWQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFfdGhpczYuc2lnbmF0dXJlcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub3Qgc2lnbmVkJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghX3RoaXM2Lm9wZXJhdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm8gb3BlcmF0aW9ucycpO1xuICAgICAgfVxuXG4gICAgICB2YXIgdHJfb2JqZWN0ID0gX3NlcmlhbGl6ZXIub3BzLnNpZ25lZF90cmFuc2FjdGlvbi50b09iamVjdChfdGhpczYpO1xuICAgICAgLy8gY29uc29sZS5sb2coJy4uLiBicm9hZGNhc3RfdHJhbnNhY3Rpb25fd2l0aF9jYWxsYmFjayAhISEnKVxuICAgICAgX3BlZXJwbGF5c2pzV3MuQXBpcy5pbnN0YW5jZSgpLm5ldHdvcmtfYXBpKCkuZXhlYygnYnJvYWRjYXN0X3RyYW5zYWN0aW9uX3dpdGhfY2FsbGJhY2snLCBbZnVuY3Rpb24gKHJlcykge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXMpO1xuICAgICAgfSwgdHJfb2JqZWN0XSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCcuLi4gYnJvYWRjYXN0IHN1Y2Nlc3MsIHdhaXRpbmcgZm9yIGNhbGxiYWNrJylcbiAgICAgICAgaWYgKHdhc19icm9hZGNhc3RfY2FsbGJhY2spIHtcbiAgICAgICAgICB3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAvLyBjb25zb2xlLmxvZyBtYXkgYmUgcmVkdW5kYW50IGZvciBuZXR3b3JrIGVycm9ycywgb3RoZXIgZXJyb3JzIGNvdWxkIG9jY3VyXG4gICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuXG5cbiAgICAgICAgaWYgKCFtZXNzYWdlKSB7XG4gICAgICAgICAgbWVzc2FnZSA9ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihtZXNzYWdlICsgJ1xcbicgKyAncGVlcnBsYXlzLWNyeXB0byAnICsgKCcgZGlnZXN0ICcgKyBfZWNjLmhhc2guc2hhMjU2KF90aGlzNi50cl9idWZmZXIpLnRvU3RyaW5nKCdoZXgnKSArICcgdHJhbnNhY3Rpb24gJyArIF90aGlzNi50cl9idWZmZXIudG9TdHJpbmcoJ2hleCcpICsgJyAnICsgSlNPTi5zdHJpbmdpZnkodHJfb2JqZWN0KSkpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci50aW1lU3RyaW5nVG9EYXRlID0gZnVuY3Rpb24gdGltZVN0cmluZ1RvRGF0ZSh0aW1lX3N0cmluZykge1xuICAgIGlmICghdGltZV9zdHJpbmcpIHtcbiAgICAgIHRpbWVfc3RyaW5nID0gJzE5NzAtMDEtMDFUMDA6MDA6MDAuMDAwWic7XG4gICAgfVxuXG4gICAgaWYgKCEvWiQvLnRlc3QodGltZV9zdHJpbmcpKSB7XG4gICAgICAvLyBkb2VzIG5vdCBlbmQgaW4gWlxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NyeXB0b25vbWV4L2dyYXBoZW5lL2lzc3Vlcy8zNjhcbiAgICAgIHRpbWVfc3RyaW5nICs9ICdaJztcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IERhdGUodGltZV9zdHJpbmcpO1xuICB9O1xuXG4gIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuZ2V0SGVhZEJsb2NrRGF0ZSA9IGZ1bmN0aW9uIGdldEhlYWRCbG9ja0RhdGUoKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uQnVpbGRlci50aW1lU3RyaW5nVG9EYXRlKHRoaXMuaGVhZF9ibG9ja190aW1lX3N0cmluZyk7XG4gIH07XG5cbiAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5iYXNlX2V4cGlyYXRpb25fc2VjID0gZnVuY3Rpb24gYmFzZV9leHBpcmF0aW9uX3NlYygpIHtcbiAgICB2YXIgaGVhZF9ibG9ja19zZWMgPSBNYXRoLmNlaWwodGhpcy5nZXRIZWFkQmxvY2tEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7XG4gICAgdmFyIG5vd19zZWMgPSBNYXRoLmNlaWwoRGF0ZS5ub3coKSAvIDEwMDApO1xuXG4gICAgLy8gVGhlIGhlYWQgYmxvY2sgdGltZSBzaG91bGQgYmUgdXBkYXRlZCBldmVyeSAzIHNlY29uZHMuICBJZiBpdCBpc24ndFxuICAgIC8vIHRoZW4gaGVscCB0aGUgdHJhbnNhY3Rpb24gdG8gZXhwaXJlICh1c2UgaGVhZF9ibG9ja19zZWMpXG4gICAgaWYgKG5vd19zZWMgLSBoZWFkX2Jsb2NrX3NlYyA+IDMwKSB7XG4gICAgICByZXR1cm4gaGVhZF9ibG9ja19zZWM7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHVzZXIncyBjbG9jayBpcyB2ZXJ5IGZhciBiZWhpbmQsIHVzZSB0aGUgaGVhZCBibG9jayB0aW1lLlxuICAgIHJldHVybiBNYXRoLm1heChub3dfc2VjLCBoZWFkX2Jsb2NrX3NlYyk7XG4gIH07XG5cbiAgcmV0dXJuIFRyYW5zYWN0aW9uQnVpbGRlcjtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gVHJhbnNhY3Rpb25CdWlsZGVyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZnVuY3Rpb24gZ2V0KHN0YXRlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHN0YXRlW2tleV0gfHwgJyc7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHNldChzdGF0ZSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHJldHVybiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIHN0YXRlW2tleV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH07XG59XG5cbmV4cG9ydHMuZ2V0ID0gZ2V0O1xuZXhwb3J0cy5zZXQgPSBzZXQ7IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5rZXkgPSBleHBvcnRzLmhhc2ggPSBleHBvcnRzLmJyYWluS2V5ID0gZXhwb3J0cy5TaWduYXR1cmUgPSBleHBvcnRzLlB1YmxpY0tleSA9IGV4cG9ydHMuUHJpdmF0ZUtleSA9IGV4cG9ydHMuQWVzID0gZXhwb3J0cy5BZGRyZXNzID0gdW5kZWZpbmVkO1xuXG52YXIgX2FkZHJlc3MgPSByZXF1aXJlKDEyKTtcblxudmFyIF9hZGRyZXNzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2FkZHJlc3MpO1xuXG52YXIgX2FlcyA9IHJlcXVpcmUoMTMpO1xuXG52YXIgX2FlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hZXMpO1xuXG52YXIgX1ByaXZhdGVLZXkgPSByZXF1aXJlKDEwKTtcblxudmFyIF9Qcml2YXRlS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1ByaXZhdGVLZXkpO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoMTEpO1xuXG52YXIgX1B1YmxpY0tleTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9QdWJsaWNLZXkpO1xuXG52YXIgX3NpZ25hdHVyZSA9IHJlcXVpcmUoMTgpO1xuXG52YXIgX3NpZ25hdHVyZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zaWduYXR1cmUpO1xuXG52YXIgX0JyYWluS2V5ID0gcmVxdWlyZSg4KTtcblxudmFyIF9CcmFpbktleTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9CcmFpbktleSk7XG5cbnZhciBfaGFzaCA9IHJlcXVpcmUoMTcpO1xuXG52YXIgaGFzaCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9oYXNoKTtcblxudmFyIF9LZXlVdGlscyA9IHJlcXVpcmUoOSk7XG5cbnZhciBfS2V5VXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfS2V5VXRpbHMpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqLmRlZmF1bHQgPSBvYmo7IHJldHVybiBuZXdPYmo7IH0gfVxuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5leHBvcnRzLkFkZHJlc3MgPSBfYWRkcmVzczIuZGVmYXVsdDtcbmV4cG9ydHMuQWVzID0gX2FlczIuZGVmYXVsdDtcbmV4cG9ydHMuUHJpdmF0ZUtleSA9IF9Qcml2YXRlS2V5Mi5kZWZhdWx0O1xuZXhwb3J0cy5QdWJsaWNLZXkgPSBfUHVibGljS2V5Mi5kZWZhdWx0O1xuZXhwb3J0cy5TaWduYXR1cmUgPSBfc2lnbmF0dXJlMi5kZWZhdWx0O1xuZXhwb3J0cy5icmFpbktleSA9IF9CcmFpbktleTIuZGVmYXVsdDtcbmV4cG9ydHMuaGFzaCA9IGhhc2g7XG5leHBvcnRzLmtleSA9IF9LZXlVdGlsczIuZGVmYXVsdDsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLmRlZmF1bHQgPSBub3JtYWxpemU7XG5mdW5jdGlvbiBub3JtYWxpemUoYnJhaW5LZXkpIHtcbiAgaWYgKHR5cGVvZiBicmFpbktleSAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmluZyByZXF1aXJlZCBmb3IgYnJhaW5LZXknKTtcbiAgfVxuXG4gIGJyYWluS2V5ID0gYnJhaW5LZXkudHJpbSgpO1xuICByZXR1cm4gYnJhaW5LZXkuc3BsaXQoL1tcXHRcXG5cXHZcXGZcXHIgXSsvKS5qb2luKCcgJyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfc2VjdXJlUmFuZG9tID0gcmVxdWlyZSgnc2VjdXJlLXJhbmRvbScpO1xuXG52YXIgX3NlY3VyZVJhbmRvbTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zZWN1cmVSYW5kb20pO1xuXG52YXIgX3BlZXJwbGF5c2pzV3MgPSByZXF1aXJlKCdwZWVycGxheXNqcy13cycpO1xuXG52YXIgX1ByaXZhdGVLZXkgPSByZXF1aXJlKCcuL1ByaXZhdGVLZXknKTtcblxudmFyIF9Qcml2YXRlS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1ByaXZhdGVLZXkpO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoJy4vUHVibGljS2V5Jyk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbnZhciBfYWRkcmVzcyA9IHJlcXVpcmUoJy4vYWRkcmVzcycpO1xuXG52YXIgX2FkZHJlc3MyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWRkcmVzcyk7XG5cbnZhciBfYWVzID0gcmVxdWlyZSgnLi9hZXMnKTtcblxudmFyIF9hZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWVzKTtcblxudmFyIF9oYXNoID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8vIGltcG9ydCBkaWN0aW9uYXJ5IGZyb20gJy4vZGljdGlvbmFyeV9lbic7XG5cbi8vIGhhc2ggZm9yIC4yNSBzZWNvbmRcbnZhciBIQVNIX1BPV0VSX01JTExTID0gMjUwO1xuXG52YXIga2V5ID0ge1xuICAvKiogVXNlcyAxIHNlY29uZCBvZiBoYXNoaW5nIHBvd2VyIHRvIGNyZWF0ZSBhIGtleS9wYXNzd29yZCBjaGVja3N1bS4gIEFuXG4gICAgaW1wbGVtZW50YXRpb24gY2FuIHJlLWNhbGwgdGhpcyBtZXRob2Qgd2l0aCB0aGUgc2FtZSBwYXNzd29yZCB0byByZS1tYXRjaFxuICAgIHRoZSBzdHJlbmd0aCBvZiB0aGUgQ1BVIChlaXRoZXIgYWZ0ZXIgbW92aW5nIGZyb20gYSBkZXNrdG9wIHRvIGEgbW9iaWxlLFxuICAgIG1vYmlsZSB0byBkZXNrdG9wLCBvciBOIHllYXJzIGZyb20gbm93IHdoZW4gQ1BVcyBhcmUgcHJlc3VtYWJseSBzdHJvbmdlcikuXG4gICAgIEEgc2FsdCBpcyB1c2VkIGZvciBhbGwgdGhlIG5vcm1hbCByZWFzb25zLi4uXG4gICAgIEByZXR1cm4gb2JqZWN0IHtcbiAgICAgICAgYWVzX3ByaXZhdGU6IEFlcyxcbiAgICAgICAgY2hlY2tzdW06IFwie2hhc2hfaXRlcmF0aW9uX2NvdW50fSx7c2FsdH0se2NoZWNrc3VtfVwiXG4gICAgfVxuICAgICovXG4gIGFlc19jaGVja3N1bTogZnVuY3Rpb24gYWVzX2NoZWNrc3VtKHBhc3N3b3JkKSB7XG4gICAgaWYgKCEodHlwZW9mIHBhc3N3b3JkID09PSAnc3RyaW5nJykpIHtcbiAgICAgIHRocm93IG5ldyAncGFzc3dvcmQgc3RyaW5nIHJlcXVpcmVkJygpO1xuICAgIH1cblxuICAgIHZhciBzYWx0ID0gX3NlY3VyZVJhbmRvbTIuZGVmYXVsdC5yYW5kb21CdWZmZXIoNCkudG9TdHJpbmcoJ2hleCcpO1xuICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICB2YXIgc2VjcmV0ID0gc2FsdCArIHBhc3N3b3JkO1xuICAgIC8vIGhhc2ggZm9yIC4xIHNlY29uZFxuICAgIHZhciBzdGFydF90ID0gRGF0ZS5ub3coKTtcblxuICAgIHdoaWxlIChEYXRlLm5vdygpIC0gc3RhcnRfdCA8IEhBU0hfUE9XRVJfTUlMTFMpIHtcbiAgICAgIHNlY3JldCA9ICgwLCBfaGFzaC5zaGEyNTYpKHNlY3JldCk7XG4gICAgICBpdGVyYXRpb25zICs9IDE7XG4gICAgfVxuXG4gICAgdmFyIGNoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1Nikoc2VjcmV0KTtcbiAgICB2YXIgY2hlY2tzdW1fc3RyaW5nID0gW2l0ZXJhdGlvbnMsIHNhbHQudG9TdHJpbmcoJ2hleCcpLCBjaGVja3N1bS5zbGljZSgwLCA0KS50b1N0cmluZygnaGV4JyldLmpvaW4oJywnKTtcblxuICAgIHJldHVybiB7XG4gICAgICBhZXNfcHJpdmF0ZTogX2FlczIuZGVmYXVsdC5mcm9tU2VlZChzZWNyZXQpLFxuICAgICAgY2hlY2tzdW06IGNoZWNrc3VtX3N0cmluZ1xuICAgIH07XG4gIH0sXG5cblxuICAvKiogUHJvdmlkZSBhIG1hdGNoaW5nIHBhc3N3b3JkIGFuZCBrZXlfY2hlY2tzdW0uICBBIFwid3JvbmcgcGFzc3dvcmRcIlxuICAgIGVycm9yIGlzIHRocm93biBpZiB0aGUgcGFzc3dvcmQgZG9lcyBub3QgbWF0Y2guICBJZiB0aGlzIG1ldGhvZCB0YWtlc1xuICAgIG11Y2ggbW9yZSBvciBsZXNzIHRoYW4gMSBzZWNvbmQgdG8gcmV0dXJuLCBvbmUgc2hvdWxkIGNvbnNpZGVyIHVwZGF0aW5nXG4gICAgYWxsIGVuY3lycHRlZCBmaWVsZHMgdXNpbmcgYSBuZXcga2V5LmtleV9jaGVja3N1bS5cbiAgICAqL1xuICBhZXNfcHJpdmF0ZTogZnVuY3Rpb24gYWVzX3ByaXZhdGUocGFzc3dvcmQsIGtleV9jaGVja3N1bSkge1xuICAgIHZhciBfa2V5X2NoZWNrc3VtJHNwbGl0ID0ga2V5X2NoZWNrc3VtLnNwbGl0KCcsJyksXG4gICAgICAgIGl0ZXJhdGlvbnMgPSBfa2V5X2NoZWNrc3VtJHNwbGl0WzBdLFxuICAgICAgICBzYWx0ID0gX2tleV9jaGVja3N1bSRzcGxpdFsxXSxcbiAgICAgICAgY2hlY2tzdW0gPSBfa2V5X2NoZWNrc3VtJHNwbGl0WzJdO1xuXG4gICAgdmFyIHNlY3JldCA9IHNhbHQgKyBwYXNzd29yZDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpdGVyYXRpb25zID4gMCA/IGkgPCBpdGVyYXRpb25zIDogaSA+IGl0ZXJhdGlvbnM7IGl0ZXJhdGlvbnMgPiAwID8gaSsrIDogaSsrKSB7XG4gICAgICBzZWNyZXQgPSAoMCwgX2hhc2guc2hhMjU2KShzZWNyZXQpO1xuICAgIH1cblxuICAgIHZhciBuZXdfY2hlY2tzdW0gPSAoMCwgX2hhc2guc2hhMjU2KShzZWNyZXQpO1xuXG4gICAgaWYgKCEobmV3X2NoZWNrc3VtLnNsaWNlKDAsIDQpLnRvU3RyaW5nKCdoZXgnKSA9PT0gY2hlY2tzdW0pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dyb25nIHBhc3N3b3JkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9hZXMyLmRlZmF1bHQuZnJvbVNlZWQoc2VjcmV0KTtcbiAgfSxcblxuXG4gIC8qKlxuICAgICAgICBBIHdlZWsgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgY2FuIHJ1biBvdXQgb2YgZW50cm9weS5cbiAgICAgICAgVGhpcyBzaG91bGQgZW5zdXJlIGV2ZW4gdGhlIHdvcnN0IHJhbmRvbSBudW1iZXIgaW1wbGVtZW50YXRpb24gd2lsbCBiZSByZWFzb25hYmx5IHNhZmUuXG4gICAgICAgICBAcGFyYW0xIHN0cmluZyBlbnRyb3B5IG9mIGF0IGxlYXN0IDMyIGJ5dGVzXG4gICAgKi9cbiAgcmFuZG9tMzJCeXRlQnVmZmVyOiBmdW5jdGlvbiByYW5kb20zMkJ5dGVCdWZmZXIoKSB7XG4gICAgdmFyIGVudHJvcHkgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRoaXMuYnJvd3NlckVudHJvcHkoKTtcblxuICAgIGlmICghKHR5cGVvZiBlbnRyb3B5ID09PSAnc3RyaW5nJykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc3RyaW5nIHJlcXVpcmVkIGZvciBlbnRyb3B5Jyk7XG4gICAgfVxuXG4gICAgaWYgKGVudHJvcHkubGVuZ3RoIDwgMzIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0aW5nIGF0IGxlYXN0IDMyIGJ5dGVzIG9mIGVudHJvcHknKTtcbiAgICB9XG5cbiAgICB2YXIgc3RhcnRfdCA9IERhdGUubm93KCk7XG5cbiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0X3QgPCBIQVNIX1BPV0VSX01JTExTKSB7XG4gICAgICBlbnRyb3B5ID0gKDAsIF9oYXNoLnNoYTI1NikoZW50cm9weSk7XG4gICAgfVxuXG4gICAgdmFyIGhhc2hfYXJyYXkgPSBbXTtcbiAgICBoYXNoX2FycmF5LnB1c2goZW50cm9weSk7XG5cbiAgICAvLyBIYXNoaW5nIGZvciAxIHNlY29uZCBtYXkgaGVscHMgdGhlIGNvbXB1dGVyIGlzIG5vdCBsb3cgb24gZW50cm9weVxuICAgIC8vICh0aGlzIG1ldGhvZCBtYXkgYmUgY2FsbGVkIGJhY2stdG8tYmFjaykuXG4gICAgaGFzaF9hcnJheS5wdXNoKF9zZWN1cmVSYW5kb20yLmRlZmF1bHQucmFuZG9tQnVmZmVyKDMyKSk7XG5cbiAgICByZXR1cm4gKDAsIF9oYXNoLnNoYTI1NikoQnVmZmVyLmNvbmNhdChoYXNoX2FycmF5KSk7XG4gIH0sXG4gIHN1Z2dlc3RfYnJhaW5fa2V5OiBmdW5jdGlvbiBzdWdnZXN0X2JyYWluX2tleSgpIHtcbiAgICB2YXIgZGljdGlvbmFyeSA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJywnO1xuICAgIHZhciBlbnRyb3B5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB0aGlzLmJyb3dzZXJFbnRyb3B5KCk7XG5cbiAgICB2YXIgcmFuZG9tQnVmZmVyID0gdGhpcy5yYW5kb20zMkJ5dGVCdWZmZXIoZW50cm9weSk7XG5cbiAgICB2YXIgd29yZF9jb3VudCA9IDE2O1xuICAgIHZhciBkaWN0aW9uYXJ5X2xpbmVzID0gZGljdGlvbmFyeS5zcGxpdCgnLCcpO1xuXG4gICAgaWYgKCEoZGljdGlvbmFyeV9saW5lcy5sZW5ndGggPT09IDQ5NzQ0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdleHBlY3RpbmcgJyArIDQ5NzQ0ICsgJyBidXQgZ290ICcgKyBkaWN0aW9uYXJ5X2xpbmVzLmxlbmd0aCArICcgZGljdGlvbmFyeSB3b3JkcycpO1xuICAgIH1cblxuICAgIHZhciBicmFpbmtleSA9IFtdO1xuICAgIHZhciBlbmQgPSB3b3JkX2NvdW50ICogMjtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5kOyBpICs9IDIpIHtcbiAgICAgIC8vIHJhbmRvbUJ1ZmZlciBoYXMgMjU2IGJpdHMgLyAxNiBiaXRzIHBlciB3b3JkID09IDE2IHdvcmRzXG4gICAgICB2YXIgbnVtID0gKHJhbmRvbUJ1ZmZlcltpXSA8PCA4KSArIHJhbmRvbUJ1ZmZlcltpICsgMV07IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgICAgLy8gY29udmVydCBpbnRvIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMSAoaW5jbHVzaXZlKVxuICAgICAgdmFyIHJuZE11bHRpcGxpZXIgPSBudW0gLyBNYXRoLnBvdygyLCAxNik7XG4gICAgICB2YXIgd29yZEluZGV4ID0gTWF0aC5yb3VuZChkaWN0aW9uYXJ5X2xpbmVzLmxlbmd0aCAqIHJuZE11bHRpcGxpZXIpO1xuXG4gICAgICBicmFpbmtleS5wdXNoKGRpY3Rpb25hcnlfbGluZXNbd29yZEluZGV4XSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubm9ybWFsaXplX2JyYWluS2V5KGJyYWlua2V5LmpvaW4oJyAnKSk7XG4gIH0sXG4gIGdldF9yYW5kb21fa2V5OiBmdW5jdGlvbiBnZXRfcmFuZG9tX2tleShlbnRyb3B5KSB7XG4gICAgcmV0dXJuIF9Qcml2YXRlS2V5Mi5kZWZhdWx0LmZyb21CdWZmZXIodGhpcy5yYW5kb20zMkJ5dGVCdWZmZXIoZW50cm9weSkpO1xuICB9LFxuICBnZXRfYnJhaW5Qcml2YXRlS2V5OiBmdW5jdGlvbiBnZXRfYnJhaW5Qcml2YXRlS2V5KGJyYWluS2V5KSB7XG4gICAgdmFyIHNlcXVlbmNlID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAwO1xuXG4gICAgaWYgKHNlcXVlbmNlIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNlcXVlbmNlJyk7XG4gICAgfVxuXG4gICAgYnJhaW5LZXkgPSBrZXkubm9ybWFsaXplX2JyYWluS2V5KGJyYWluS2V5KTtcbiAgICByZXR1cm4gX1ByaXZhdGVLZXkyLmRlZmF1bHQuZnJvbUJ1ZmZlcigoMCwgX2hhc2guc2hhMjU2KSgoMCwgX2hhc2guc2hhNTEyKShicmFpbktleSArICcgJyArIHNlcXVlbmNlKSkpO1xuICB9LFxuXG5cbiAgLy8gVHVybiBpbnZpc2libGUgc3BhY2UgbGlrZSBjaGFyYWN0ZXJzIGludG8gYSBzaW5nbGUgc3BhY2VcbiAgbm9ybWFsaXplX2JyYWluS2V5OiBmdW5jdGlvbiBub3JtYWxpemVfYnJhaW5LZXkoYnJhaW5LZXkpIHtcbiAgICBpZiAoISh0eXBlb2YgYnJhaW5LZXkgPT09ICdzdHJpbmcnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdHJpbmcgcmVxdWlyZWQgZm9yIGJyYWluS2V5Jyk7XG4gICAgfVxuXG4gICAgYnJhaW5LZXkgPSBicmFpbktleS50cmltKCk7XG4gICAgcmV0dXJuIGJyYWluS2V5LnNwbGl0KC9bXFx0XFxuXFx2XFxmXFxyIF0rLykuam9pbignICcpO1xuICB9LFxuICBicm93c2VyRW50cm9weTogZnVuY3Rpb24gYnJvd3NlckVudHJvcHkoKSB7XG4gICAgdmFyIGVudHJvcHlTdHIgPSAnJztcblxuICAgIHRyeSB7XG4gICAgICBlbnRyb3B5U3RyID0gbmV3IERhdGUoKS50b1N0cmluZygpICsgJyAnICsgd2luZG93LnNjcmVlbi5oZWlnaHQgKyAnICcgKyB3aW5kb3cuc2NyZWVuLndpZHRoO1xuICAgICAgZW50cm9weVN0ciA9IGVudHJvcHlTdHIgKyAnICcgKyB3aW5kb3cuc2NyZWVuLmNvbG9yRGVwdGggKyAnICcgKyB3aW5kb3cuc2NyZWVuLmF2YWlsSGVpZ2h0O1xuICAgICAgZW50cm9weVN0ciA9IGVudHJvcHlTdHIgKyAnICcgKyB3aW5kb3cuc2NyZWVuLmF2YWlsV2lkdGggKyAnICcgKyB3aW5kb3cuc2NyZWVuLnBpeGVsRGVwdGg7XG4gICAgICBlbnRyb3B5U3RyID0gZW50cm9weVN0ciArICcgJyArIG5hdmlnYXRvci5sYW5ndWFnZSArICcgJyArIHdpbmRvdy5sb2NhdGlvbjtcbiAgICAgIGVudHJvcHlTdHIgPSBlbnRyb3B5U3RyICsgJyAnICsgd2luZG93Lmhpc3RvcnkubGVuZ3RoO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbmF2aWdhdG9yLm1pbWVUeXBlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgbWltZVR5cGUgPSBuYXZpZ2F0b3IubWltZVR5cGVzW2ldO1xuICAgICAgICBlbnRyb3B5U3RyICs9IG1pbWVUeXBlLmRlc2NyaXB0aW9uICsgJyAnICsgbWltZVR5cGUudHlwZSArICcgJyArIG1pbWVUeXBlLnN1ZmZpeGVzICsgJyAnO1xuICAgICAgfVxuXG4gICAgICBjb25zb2xlLmxvZygnSU5GT1xcdGJyb3dzZXJFbnRyb3B5IGdhdGhlcmVkJyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIG5vZGVqczpSZWZlcmVuY2VFcnJvcjogd2luZG93IGlzIG5vdCBkZWZpbmVkXG4gICAgICBlbnRyb3B5U3RyID0gKDAsIF9oYXNoLnNoYTI1NikobmV3IERhdGUoKS50b1N0cmluZygpKTtcbiAgICB9XG5cbiAgICB2YXIgYiA9IEJ1ZmZlci5mcm9tKGVudHJvcHlTdHIpO1xuICAgIGVudHJvcHlTdHIgKz0gYi50b1N0cmluZygnYmluYXJ5JykgKyAnICcgKyBuZXcgRGF0ZSgpLnRvU3RyaW5nKCk7XG4gICAgcmV0dXJuIGVudHJvcHlTdHI7XG4gIH0sXG5cblxuICAvLyBAcmV0dXJuIGFycmF5IG9mIDUgbGVnYWN5IGFkZHJlc3NlcyBmb3IgYSBwdWJrZXkgc3RyaW5nIHBhcmFtZXRlci5cbiAgYWRkcmVzc2VzOiBmdW5jdGlvbiBhZGRyZXNzZXMocHVia2V5KSB7XG4gICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgIHZhciBwdWJsaWNfa2V5ID0gX1B1YmxpY0tleTIuZGVmYXVsdC5mcm9tUHVibGljS2V5U3RyaW5nKHB1YmtleSwgYWRkcmVzc19wcmVmaXgpO1xuICAgIC8vIFMgTCBPIFdcbiAgICB2YXIgYWRkcmVzc19zdHJpbmcgPSBbX2FkZHJlc3MyLmRlZmF1bHQuZnJvbVB1YmxpYyhwdWJsaWNfa2V5LCBmYWxzZSwgMCkudG9TdHJpbmcoYWRkcmVzc19wcmVmaXgpLCAvLyBidGNfdW5jb21wcmVzc2VkXG4gICAgX2FkZHJlc3MyLmRlZmF1bHQuZnJvbVB1YmxpYyhwdWJsaWNfa2V5LCB0cnVlLCAwKS50b1N0cmluZyhhZGRyZXNzX3ByZWZpeCksIC8vIGJ0Y19jb21wcmVzc2VkXG4gICAgX2FkZHJlc3MyLmRlZmF1bHQuZnJvbVB1YmxpYyhwdWJsaWNfa2V5LCBmYWxzZSwgNTYpLnRvU3RyaW5nKGFkZHJlc3NfcHJlZml4KSwgLy8gcHRzX3VuY29tcHJlc3NlZFxuICAgIF9hZGRyZXNzMi5kZWZhdWx0LmZyb21QdWJsaWMocHVibGljX2tleSwgdHJ1ZSwgNTYpLnRvU3RyaW5nKGFkZHJlc3NfcHJlZml4KSwgLy8gcHRzX2NvbXByZXNzZWRcbiAgICBwdWJsaWNfa2V5LnRvQWRkcmVzc1N0cmluZyhhZGRyZXNzX3ByZWZpeCkgLy8gYnRzX3Nob3J0LCBtb3N0IHJlY2VudCBmb3JtYXRcbiAgICBdO1xuICAgIHJldHVybiBhZGRyZXNzX3N0cmluZztcbiAgfVxufTtcblxuZXhwb3J0cy5kZWZhdWx0ID0ga2V5O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2VjdXJ2ZSA9IHJlcXVpcmUoJ2VjdXJ2ZScpO1xuXG52YXIgX2JpZ2kgPSByZXF1aXJlKCdiaWdpJyk7XG5cbnZhciBfYmlnaTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9iaWdpKTtcblxudmFyIF9icyA9IHJlcXVpcmUoJ2JzNTgnKTtcblxudmFyIF9kZWVwRXF1YWwgPSByZXF1aXJlKCdkZWVwLWVxdWFsJyk7XG5cbnZhciBfZGVlcEVxdWFsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2RlZXBFcXVhbCk7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfaGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoJy4vUHVibGljS2V5Jyk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9IC8qIGdsb2JhbCBCeXRlQnVmZmVyICovXG5cblxudmFyIHNlY3AyNTZrMSA9ICgwLCBfZWN1cnZlLmdldEN1cnZlQnlOYW1lKSgnc2VjcDI1NmsxJyk7XG52YXIgbiA9IHNlY3AyNTZrMS5uO1xuXG5cbmZ1bmN0aW9uIHRvUHVibGljKGRhdGEpIHtcbiAgaWYgKCFkYXRhIHx8IGRhdGEuUSkge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgcmV0dXJuIF9QdWJsaWNLZXkyLmRlZmF1bHQuZnJvbVN0cmluZ09yVGhyb3coZGF0YSk7XG59XG5cbnZhciBQcml2YXRlS2V5ID0gZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICAgICAgQHByaXZhdGUgc2VlIHN0YXRpYyBmdW5jdGlvbnNcbiAgICAgICAgQHBhcmFtIHtCaWdJbnRlZ2VyfVxuICAgICovXG4gIGZ1bmN0aW9uIFByaXZhdGVLZXkoZCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQcml2YXRlS2V5KTtcblxuICAgIHRoaXMuZCA9IGQ7XG4gIH1cblxuICBQcml2YXRlS2V5LmZyb21CdWZmZXIgPSBmdW5jdGlvbiBmcm9tQnVmZmVyKGJ1Zikge1xuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0aW5nIHBhcmFtdGVyIHRvIGJlIGEgQnVmZmVyIHR5cGUnKTtcbiAgICB9XG5cbiAgICBpZiAoYnVmLmxlbmd0aCAhPT0gMzIpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdXQVJOOiBFeHBlY3RpbmcgMzIgYnl0ZXMsIGluc3RlYWQgZ290ICcgKyBidWYubGVuZ3RoICsgJywgc3RhY2sgdHJhY2U6JywgbmV3IEVycm9yKCkuc3RhY2spO1xuICAgIH1cblxuICAgIGlmIChidWYubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VtcHR5IGJ1ZmZlcicpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJpdmF0ZUtleShfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1ZikpO1xuICB9O1xuXG4gIC8qKiBAYXJnIHtzdHJpbmd9IHNlZWQgLSBhbnkgbGVuZ3RoIHN0cmluZy4gIFRoaXMgaXMgcHJpdmF0ZSxcbiAgICogdGhlIHNhbWUgc2VlZCBwcm9kdWNlcyB0aGUgc2FtZSBwcml2YXRlIGtleSBldmVyeSB0aW1lLiAgKi9cblxuXG4gIFByaXZhdGVLZXkuZnJvbVNlZWQgPSBmdW5jdGlvbiBmcm9tU2VlZChzZWVkKSB7XG4gICAgLy8gZ2VuZXJhdGVfcHJpdmF0ZV9rZXlcbiAgICBpZiAoISh0eXBlb2Ygc2VlZCA9PT0gJ3N0cmluZycpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NlZWQgbXVzdCBiZSBvZiB0eXBlIHN0cmluZycpO1xuICAgIH1cblxuICAgIHJldHVybiBQcml2YXRlS2V5LmZyb21CdWZmZXIoKDAsIF9oYXNoLnNoYTI1Nikoc2VlZCkpO1xuICB9O1xuXG4gIC8qKiBAcmV0dXJuIHtzdHJpbmd9IFdhbGxldCBJbXBvcnQgRm9ybWF0IChzdGlsbCBhIHNlY3JldCwgTm90IGVuY3J5cHRlZCkgKi9cblxuXG4gIFByaXZhdGVLZXkuZnJvbVdpZiA9IGZ1bmN0aW9uIGZyb21XaWYoX3ByaXZhdGVfd2lmKSB7XG4gICAgdmFyIHByaXZhdGVfd2lmID0gQnVmZmVyLmZyb20oKDAsIF9icy5kZWNvZGUpKF9wcml2YXRlX3dpZikpO1xuICAgIHZhciB2ZXJzaW9uID0gcHJpdmF0ZV93aWYucmVhZFVJbnQ4KDApO1xuICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoMHg4MCwgdmVyc2lvbiwgJ0V4cGVjdGVkIHZlcnNpb24gJyArIDB4ODAgKyAnLCBpbnN0ZWFkIGdvdCAnICsgdmVyc2lvbik7XG4gICAgLy8gY2hlY2tzdW0gaW5jbHVkZXMgdGhlIHZlcnNpb25cbiAgICB2YXIgcHJpdmF0ZV9rZXkgPSBwcml2YXRlX3dpZi5zbGljZSgwLCAtNCk7XG4gICAgdmFyIGNoZWNrc3VtID0gcHJpdmF0ZV93aWYuc2xpY2UoLTQpO1xuICAgIHZhciBuZXdfY2hlY2tzdW0gPSAoMCwgX2hhc2guc2hhMjU2KShwcml2YXRlX2tleSk7XG4gICAgbmV3X2NoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1NikobmV3X2NoZWNrc3VtKTtcbiAgICBuZXdfY2hlY2tzdW0gPSBuZXdfY2hlY2tzdW0uc2xpY2UoMCwgNCk7XG4gICAgdmFyIGlzRXF1YWwgPSAoMCwgX2RlZXBFcXVhbDIuZGVmYXVsdCkoY2hlY2tzdW0sIG5ld19jaGVja3N1bSk7IC8vICwgJ0ludmFsaWQgY2hlY2tzdW0nXG5cbiAgICBpZiAoIWlzRXF1YWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2hlY2tzdW0gZGlkIG5vdCBtYXRjaCcpO1xuICAgIH1cblxuICAgIHByaXZhdGVfa2V5ID0gcHJpdmF0ZV9rZXkuc2xpY2UoMSk7XG4gICAgcHJpdmF0ZV9rZXkgPSBwcml2YXRlX2tleS5zbGljZSgwLCAzMik7XG4gICAgcmV0dXJuIFByaXZhdGVLZXkuZnJvbUJ1ZmZlcihwcml2YXRlX2tleSk7XG4gIH07XG5cbiAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9XaWYgPSBmdW5jdGlvbiB0b1dpZigpIHtcbiAgICB2YXIgcHJpdmF0ZV9rZXkgPSB0aGlzLnRvQnVmZmVyKCk7XG4gICAgLy8gY2hlY2tzdW0gaW5jbHVkZXMgdGhlIHZlcnNpb25cbiAgICBwcml2YXRlX2tleSA9IEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKFsweDgwXSksIHByaXZhdGVfa2V5XSk7XG4gICAgdmFyIGNoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1NikocHJpdmF0ZV9rZXkpO1xuICAgIGNoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1NikoY2hlY2tzdW0pO1xuICAgIGNoZWNrc3VtID0gY2hlY2tzdW0uc2xpY2UoMCwgNCk7XG4gICAgdmFyIHByaXZhdGVfd2lmID0gQnVmZmVyLmNvbmNhdChbcHJpdmF0ZV9rZXksIGNoZWNrc3VtXSk7XG4gICAgcmV0dXJuICgwLCBfYnMuZW5jb2RlKShwcml2YXRlX3dpZik7XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEByZXR1cm4ge1BvaW50fVxuICAgICovXG5cblxuICBQcml2YXRlS2V5LnByb3RvdHlwZS50b1B1YmxpY0tleVBvaW50ID0gZnVuY3Rpb24gdG9QdWJsaWNLZXlQb2ludCgpIHtcbiAgICB2YXIgUSA9IHNlY3AyNTZrMS5HLm11bHRpcGx5KHRoaXMuZCk7XG4gICAgcmV0dXJuIFE7XG4gIH07XG5cbiAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9QdWJsaWNLZXkgPSBmdW5jdGlvbiB0b1B1YmxpY0tleSgpIHtcbiAgICBpZiAodGhpcy5wdWJsaWNfa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5wdWJsaWNfa2V5O1xuICAgIH1cblxuICAgIHRoaXMucHVibGljX2tleSA9IF9QdWJsaWNLZXkyLmRlZmF1bHQuZnJvbVBvaW50KHRoaXMudG9QdWJsaWNLZXlQb2ludCgpKTtcblxuICAgIHJldHVybiB0aGlzLnB1YmxpY19rZXk7XG4gIH07XG5cbiAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiB0b0J1ZmZlcigpIHtcbiAgICByZXR1cm4gdGhpcy5kLnRvQnVmZmVyKDMyKTtcbiAgfTtcblxuICAvKiogRUNJRVMgKi9cblxuXG4gIFByaXZhdGVLZXkucHJvdG90eXBlLmdldF9zaGFyZWRfc2VjcmV0ID0gZnVuY3Rpb24gZ2V0X3NoYXJlZF9zZWNyZXQocHVibGljX2tleSkge1xuICAgIHZhciBsZWdhY3kgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZhbHNlO1xuXG4gICAgcHVibGljX2tleSA9IHRvUHVibGljKHB1YmxpY19rZXkpO1xuICAgIHZhciBLQiA9IHB1YmxpY19rZXkudG9VbmNvbXByZXNzZWQoKS50b0J1ZmZlcigpO1xuICAgIHZhciBLQlAgPSBfZWN1cnZlLlBvaW50LmZyb21BZmZpbmUoc2VjcDI1NmsxLCBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKEtCLnNsaWNlKDEsIDMzKSksIC8vIHhcbiAgICBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKEtCLnNsaWNlKDMzLCA2NSkpIC8vIHlcbiAgICApO1xuICAgIHZhciByID0gdGhpcy50b0J1ZmZlcigpO1xuICAgIHZhciBQID0gS0JQLm11bHRpcGx5KF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIocikpO1xuICAgIHZhciBTID0gUC5hZmZpbmVYLnRvQnVmZmVyKHsgc2l6ZTogMzIgfSk7XG5cbiAgICAvKlxuICAgICAgICB0aGUgaW5wdXQgdG8gc2hhNTEyIG11c3QgYmUgZXhhY3RseSAzMi1ieXRlcywgdG8gbWF0Y2ggdGhlIGMrKyBpbXBsZW1lbnRhdGlvblxuICAgICAgICBvZiBnZXRfc2hhcmVkX3NlY3JldC4gIFJpZ2h0IG5vdyBTIHdpbGwgYmUgc2hvcnRlciBpZiB0aGUgbW9zdCBzaWduaWZpY2FudFxuICAgICAgICBieXRlKHMpIGlzIHplcm8uICBQYWQgaXQgYmFjayB0byB0aGUgZnVsbCAzMi1ieXRlc1xuICAgICAgICAqL1xuICAgIGlmICghbGVnYWN5ICYmIFMubGVuZ3RoIDwgMzIpIHtcbiAgICAgIHZhciBwYWQgPSBCdWZmZXIuYWxsb2MoMzIgLSBTLmxlbmd0aCwgMCk7XG4gICAgICBTID0gQnVmZmVyLmNvbmNhdChbcGFkLCBTXSk7XG4gICAgfVxuXG4gICAgLy8gU0hBNTEyIHVzZWQgaW4gRUNJRVNcbiAgICByZXR1cm4gKDAsIF9oYXNoLnNoYTUxMikoUyk7XG4gIH07XG5cbiAgLy8gLyoqIEVDSUVTIChkb2VzIG5vdCBhbHdheXMgbWF0Y2ggdGhlIFBvaW50LmZyb21BZmZpbmUgdmVyc2lvbiBhYm92ZSkgKi9cbiAgLy8gZ2V0X3NoYXJlZF9zZWNyZXQocHVibGljX2tleSl7XG4gIC8vICAgICBwdWJsaWNfa2V5ID0gdG9QdWJsaWMocHVibGljX2tleSlcbiAgLy8gICAgIHZhciBQID0gcHVibGljX2tleS5RLm11bHRpcGx5KCB0aGlzLmQgKTtcbiAgLy8gICAgIHZhciBTID0gUC5hZmZpbmVYLnRvQnVmZmVyKHtzaXplOiAzMn0pO1xuICAvLyAgICAgLy8gRUNJRVMsIGFkZHMgYW4gZXh0cmEgc2hhNTEyXG4gIC8vICAgICByZXR1cm4gc2hhNTEyKFMpO1xuICAvLyB9XG5cbiAgLyoqIEB0aHJvd3Mge0Vycm9yfSAtIG92ZXJmbG93IG9mIHRoZSBrZXkgY291bGQgbm90IGJlIGRlcml2ZWQgKi9cblxuXG4gIFByaXZhdGVLZXkucHJvdG90eXBlLmNoaWxkID0gZnVuY3Rpb24gY2hpbGQob2Zmc2V0KSB7XG4gICAgb2Zmc2V0ID0gQnVmZmVyLmNvbmNhdChbdGhpcy50b1B1YmxpY0tleSgpLnRvQnVmZmVyKCksIG9mZnNldF0pO1xuICAgIG9mZnNldCA9ICgwLCBfaGFzaC5zaGEyNTYpKG9mZnNldCk7XG4gICAgdmFyIGMgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKG9mZnNldCk7XG5cbiAgICBpZiAoYy5jb21wYXJlVG8obikgPj0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCBvZmZzZXQgd2VudCBvdXQgb2YgYm91bmRzLCB0cnkgYWdhaW4nKTtcbiAgICB9XG5cbiAgICB2YXIgZGVyaXZlZCA9IHRoaXMuZC5hZGQoYyk7IC8vIC5tb2QobilcblxuICAgIGlmIChkZXJpdmVkLnNpZ251bSgpID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NoaWxkIG9mZnNldCBkZXJpdmVkIHRvIGFuIGludmFsaWQga2V5LCB0cnkgYWdhaW4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByaXZhdGVLZXkoZGVyaXZlZCk7XG4gIH07XG5cbiAgLyogPGhlbHBlcl9mdW5jdGlvbnM+ICovXG5cbiAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9CeXRlQnVmZmVyID0gZnVuY3Rpb24gdG9CeXRlQnVmZmVyKCkge1xuICAgIHZhciBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiKTtcbiAgICByZXR1cm4gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgfTtcblxuICBQcml2YXRlS2V5LmZyb21IZXggPSBmdW5jdGlvbiBmcm9tSGV4KGhleCkge1xuICAgIHJldHVybiBQcml2YXRlS2V5LmZyb21CdWZmZXIoQnVmZmVyLmZyb20oaGV4LCAnaGV4JykpO1xuICB9O1xuXG4gIFByaXZhdGVLZXkucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24gdG9IZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9CdWZmZXIoKS50b1N0cmluZygnaGV4Jyk7XG4gIH07XG5cbiAgLyogPC9oZWxwZXJfZnVuY3Rpb25zPiAqL1xuXG5cbiAgcmV0dXJuIFByaXZhdGVLZXk7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IFByaXZhdGVLZXk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYmlnaSA9IHJlcXVpcmUoJ2JpZ2knKTtcblxudmFyIF9iaWdpMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2JpZ2kpO1xuXG52YXIgX2VjdXJ2ZSA9IHJlcXVpcmUoJ2VjdXJ2ZScpO1xuXG52YXIgX2JzID0gcmVxdWlyZSgnYnM1OCcpO1xuXG52YXIgX3BlZXJwbGF5c2pzV3MgPSByZXF1aXJlKCdwZWVycGxheXNqcy13cycpO1xuXG52YXIgX2Fzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xuXG52YXIgX2Fzc2VydDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnQpO1xuXG52YXIgX2RlZXBFcXVhbCA9IHJlcXVpcmUoJ2RlZXAtZXF1YWwnKTtcblxudmFyIF9kZWVwRXF1YWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZGVlcEVxdWFsKTtcblxudmFyIF9oYXNoID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9IC8qIGdsb2JhbCBCeXRlQnVmZmVyICovXG5cblxudmFyIHNlY3AyNTZrMSA9ICgwLCBfZWN1cnZlLmdldEN1cnZlQnlOYW1lKSgnc2VjcDI1NmsxJyk7XG5cbnZhciBHID0gc2VjcDI1NmsxLkcsXG4gICAgbiA9IHNlY3AyNTZrMS5uO1xuXG52YXIgUHVibGljS2V5ID0gZnVuY3Rpb24gKCkge1xuICAvKiogQHBhcmFtIHtQb2ludH0gcHVibGljIGtleSAqL1xuICBmdW5jdGlvbiBQdWJsaWNLZXkoUSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQdWJsaWNLZXkpO1xuXG4gICAgdGhpcy5RID0gUTtcbiAgfVxuXG4gIFB1YmxpY0tleS5mcm9tQmluYXJ5ID0gZnVuY3Rpb24gZnJvbUJpbmFyeShiaW4pIHtcbiAgICByZXR1cm4gUHVibGljS2V5LmZyb21CdWZmZXIoQnVmZmVyLmZyb20oYmluLCAnYmluYXJ5JykpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICBpZiAoYnVmZmVyLnRvU3RyaW5nKCdoZXgnKSA9PT0gJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcpIHtcbiAgICAgIHJldHVybiBuZXcgUHVibGljS2V5KG51bGwpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHVibGljS2V5KF9lY3VydmUuUG9pbnQuZGVjb2RlRnJvbShzZWNwMjU2azEsIGJ1ZmZlcikpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiB0b0J1ZmZlcigpIHtcbiAgICB2YXIgY29tcHJlc3NlZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogdGhpcy5RID8gdGhpcy5RLmNvbXByZXNzZWQgOiBudWxsO1xuXG4gICAgaWYgKHRoaXMuUSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKCcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLCAnaGV4Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuUS5nZXRFbmNvZGVkKGNvbXByZXNzZWQpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5mcm9tUG9pbnQgPSBmdW5jdGlvbiBmcm9tUG9pbnQocG9pbnQpIHtcbiAgICByZXR1cm4gbmV3IFB1YmxpY0tleShwb2ludCk7XG4gIH07XG5cbiAgUHVibGljS2V5LnByb3RvdHlwZS50b1VuY29tcHJlc3NlZCA9IGZ1bmN0aW9uIHRvVW5jb21wcmVzc2VkKCkge1xuICAgIHZhciBidWYgPSB0aGlzLlEuZ2V0RW5jb2RlZChmYWxzZSk7XG4gICAgdmFyIHBvaW50ID0gX2VjdXJ2ZS5Qb2ludC5kZWNvZGVGcm9tKHNlY3AyNTZrMSwgYnVmKTtcbiAgICByZXR1cm4gUHVibGljS2V5LmZyb21Qb2ludChwb2ludCk7XG4gIH07XG5cbiAgLyoqIGJ0czo6YmxvY2tjaGFpbjo6YWRkcmVzcyAodW5pcXVlIGJ1dCBub3QgYSBmdWxsIHB1YmxpYyBrZXkpICovXG5cblxuICBQdWJsaWNLZXkucHJvdG90eXBlLnRvQmxvY2tjaGFpbkFkZHJlc3MgPSBmdW5jdGlvbiB0b0Jsb2NrY2hhaW5BZGRyZXNzKCkge1xuICAgIHZhciBwdWJfYnVmID0gdGhpcy50b0J1ZmZlcigpO1xuICAgIHZhciBwdWJfc2hhID0gKDAsIF9oYXNoLnNoYTUxMikocHViX2J1Zik7XG4gICAgcmV0dXJuICgwLCBfaGFzaC5yaXBlbWQxNjApKHB1Yl9zaGEpO1xuICB9O1xuXG4gIC8qKiBBbGlhcyBmb3Ige0BsaW5rIHRvUHVibGljS2V5U3RyaW5nfSAqL1xuXG5cbiAgUHVibGljS2V5LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICByZXR1cm4gdGhpcy50b1B1YmxpY0tleVN0cmluZyhhZGRyZXNzX3ByZWZpeCk7XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEZ1bGwgcHVibGljIGtleVxuICAgICAgICB7cmV0dXJufSBzdHJpbmdcbiAgICAqL1xuXG5cbiAgUHVibGljS2V5LnByb3RvdHlwZS50b1B1YmxpY0tleVN0cmluZyA9IGZ1bmN0aW9uIHRvUHVibGljS2V5U3RyaW5nKCkge1xuICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICB2YXIgcHViX2J1ZiA9IHRoaXMudG9CdWZmZXIoKTtcbiAgICB2YXIgY2hlY2tzdW0gPSAoMCwgX2hhc2gucmlwZW1kMTYwKShwdWJfYnVmKTtcbiAgICAvLyBTbGljZSBmcm9tIHRoZSBidWZmZXIgZGlyZWN0bHksIHNsaWNpbmcgZnJvbSB0aGUgY2hlY2tzdW1cbiAgICAvLyBVaW50OGFycmF5IHdpbGwgcmV0dXJuIHRoZSBlbnRpcmUgYXJyYXkgZWFjaCB0aW1lLlxuICAgIHZhciBzbGljZWQgPSBuZXcgVWludDhBcnJheShjaGVja3N1bS5idWZmZXIuc2xpY2UoMCwgNCkpO1xuXG4gICAgLy8gY29uY2F0IG9ubHkgYWNjZXB0cyBidWZmZXJzIHNvIGluaXRpYWxpemUgdGhlIHNsaWNlZCBVaW50OGFycmF5IGFzIGEgQnVmZmVyLlxuICAgIHZhciBhZGR5ID0gQnVmZmVyLmNvbmNhdChbcHViX2J1ZiwgQnVmZmVyLmZyb20oc2xpY2VkKV0pO1xuICAgIHJldHVybiBhZGRyZXNzX3ByZWZpeCArICgwLCBfYnMuZW5jb2RlKShhZGR5KTtcbiAgfTtcblxuICAvKipcbiAgICAgICAgQGFyZyB7c3RyaW5nfSBwdWJsaWNfa2V5IC0gbGlrZSBHUEhYeXouLi5cbiAgICAgICAgQGFyZyB7c3RyaW5nfSBhZGRyZXNzX3ByZWZpeCAtIGxpa2UgR1BIXG4gICAgICAgIEByZXR1cm4gUHVibGljS2V5IG9yIGBudWxsYCAoaWYgdGhlIHB1YmxpY19rZXkgc3RyaW5nIGlzIGludmFsaWQpXG4gICAgKi9cblxuXG4gIFB1YmxpY0tleS5mcm9tUHVibGljS2V5U3RyaW5nID0gZnVuY3Rpb24gZnJvbVB1YmxpY0tleVN0cmluZyhwdWJsaWNfa2V5KSB7XG4gICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gUHVibGljS2V5LmZyb21TdHJpbmdPclRocm93KHB1YmxpY19rZXksIGFkZHJlc3NfcHJlZml4KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEBhcmcge3N0cmluZ30gcHVibGljX2tleSAtIGxpa2UgR1BIWHl6Li4uXG4gICAgICAgIEBhcmcge3N0cmluZ30gYWRkcmVzc19wcmVmaXggLSBsaWtlIEdQSFxuICAgICAgICBAdGhyb3dzIHtFcnJvcn0gaWYgcHVibGljIGtleSBpcyBpbnZhbGlkXG4gICAgICAgIEByZXR1cm4gUHVibGljS2V5XG4gICAgKi9cblxuXG4gIFB1YmxpY0tleS5mcm9tU3RyaW5nT3JUaHJvdyA9IGZ1bmN0aW9uIGZyb21TdHJpbmdPclRocm93KHB1YmxpY19rZXkpIHtcbiAgICB2YXIgYWRkcmVzc19wcmVmaXggPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IF9wZWVycGxheXNqc1dzLkNoYWluQ29uZmlnLmFkZHJlc3NfcHJlZml4O1xuXG4gICAgdmFyIHByZWZpeCA9IHB1YmxpY19rZXkuc2xpY2UoMCwgYWRkcmVzc19wcmVmaXgubGVuZ3RoKTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGFkZHJlc3NfcHJlZml4LCBwcmVmaXgsICdFeHBlY3Rpbmcga2V5IHRvIGJlZ2luIHdpdGggJyArIGFkZHJlc3NfcHJlZml4ICsgJywgaW5zdGVhZCBnb3QgJyArIHByZWZpeCk7XG4gICAgcHVibGljX2tleSA9IHB1YmxpY19rZXkuc2xpY2UoYWRkcmVzc19wcmVmaXgubGVuZ3RoKTtcblxuICAgIHB1YmxpY19rZXkgPSBCdWZmZXIuZnJvbSgoMCwgX2JzLmRlY29kZSkocHVibGljX2tleSksICdiaW5hcnknKTtcbiAgICB2YXIgY2hlY2tzdW0gPSBwdWJsaWNfa2V5LnNsaWNlKC00KTtcbiAgICBwdWJsaWNfa2V5ID0gcHVibGljX2tleS5zbGljZSgwLCAtNCk7XG4gICAgdmFyIG5ld19jaGVja3N1bSA9ICgwLCBfaGFzaC5yaXBlbWQxNjApKHB1YmxpY19rZXkpO1xuICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS5zbGljZSgwLCA0KTtcbiAgICB2YXIgaXNFcXVhbCA9ICgwLCBfZGVlcEVxdWFsMi5kZWZhdWx0KShjaGVja3N1bSwgbmV3X2NoZWNrc3VtKTsgLy8gLCAnSW52YWxpZCBjaGVja3N1bSdcblxuICAgIGlmICghaXNFcXVhbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGVja3N1bSBkaWQgbm90IG1hdGNoJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tQnVmZmVyKHB1YmxpY19rZXkpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5wcm90b3R5cGUudG9BZGRyZXNzU3RyaW5nID0gZnVuY3Rpb24gdG9BZGRyZXNzU3RyaW5nKCkge1xuICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICB2YXIgcHViX2J1ZiA9IHRoaXMudG9CdWZmZXIoKTtcbiAgICB2YXIgcHViX3NoYSA9ICgwLCBfaGFzaC5zaGE1MTIpKHB1Yl9idWYpO1xuICAgIHZhciBhZGR5ID0gKDAsIF9oYXNoLnJpcGVtZDE2MCkocHViX3NoYSk7XG4gICAgdmFyIGNoZWNrc3VtID0gKDAsIF9oYXNoLnJpcGVtZDE2MCkoYWRkeSk7XG4gICAgYWRkeSA9IEJ1ZmZlci5jb25jYXQoW2FkZHksIGNoZWNrc3VtLnNsaWNlKDAsIDQpXSk7XG4gICAgcmV0dXJuIGFkZHJlc3NfcHJlZml4ICsgKDAsIF9icy5lbmNvZGUpKGFkZHkpO1xuICB9O1xuXG4gIFB1YmxpY0tleS5wcm90b3R5cGUudG9QdHNBZGR5ID0gZnVuY3Rpb24gdG9QdHNBZGR5KCkge1xuICAgIHZhciBwdWJfYnVmID0gdGhpcy50b0J1ZmZlcigpO1xuICAgIHZhciBwdWJfc2hhID0gKDAsIF9oYXNoLnNoYTI1NikocHViX2J1Zik7XG4gICAgdmFyIGFkZHkgPSAoMCwgX2hhc2gucmlwZW1kMTYwKShwdWJfc2hhKTtcbiAgICBhZGR5ID0gQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oWzB4MzhdKSwgYWRkeV0pOyAvLyB2ZXJzaW9uIDU2KGRlY2ltYWwpXG5cbiAgICB2YXIgY2hlY2tzdW0gPSAoMCwgX2hhc2guc2hhMjU2KShhZGR5KTtcbiAgICBjaGVja3N1bSA9ICgwLCBfaGFzaC5zaGEyNTYpKGNoZWNrc3VtKTtcblxuICAgIGFkZHkgPSBCdWZmZXIuY29uY2F0KFthZGR5LCBjaGVja3N1bS5zbGljZSgwLCA0KV0pO1xuICAgIHJldHVybiAoMCwgX2JzLmVuY29kZSkoYWRkeSk7XG4gIH07XG5cbiAgUHVibGljS2V5LnByb3RvdHlwZS5jaGlsZCA9IGZ1bmN0aW9uIGNoaWxkKG9mZnNldCkge1xuICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShCdWZmZXIuaXNCdWZmZXIob2Zmc2V0KSwgJ0J1ZmZlciByZXF1aXJlZDogb2Zmc2V0Jyk7XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChvZmZzZXQubGVuZ3RoLCAzMiwgJ29mZnNldCBsZW5ndGgnKTtcblxuICAgIG9mZnNldCA9IEJ1ZmZlci5jb25jYXQoW3RoaXMudG9CdWZmZXIoKSwgb2Zmc2V0XSk7XG4gICAgb2Zmc2V0ID0gKDAsIF9oYXNoLnNoYTI1Nikob2Zmc2V0KTtcblxuICAgIHZhciBjID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcihvZmZzZXQpO1xuXG4gICAgaWYgKGMuY29tcGFyZVRvKG4pID49IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2hpbGQgb2Zmc2V0IHdlbnQgb3V0IG9mIGJvdW5kcywgdHJ5IGFnYWluJyk7XG4gICAgfVxuXG4gICAgdmFyIGNHID0gRy5tdWx0aXBseShjKTtcbiAgICB2YXIgUXByaW1lID0gdGhpcy5RLmFkZChjRyk7XG5cbiAgICBpZiAoc2VjcDI1NmsxLmlzSW5maW5pdHkoUXByaW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCBvZmZzZXQgZGVyaXZlZCB0byBhbiBpbnZhbGlkIGtleSwgdHJ5IGFnYWluJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tUG9pbnQoUXByaW1lKTtcbiAgfTtcblxuICAvKiA8SEVYPiAqL1xuXG4gIFB1YmxpY0tleS5wcm90b3R5cGUudG9CeXRlQnVmZmVyID0gZnVuY3Rpb24gdG9CeXRlQnVmZmVyKCkge1xuICAgIHZhciBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiKTtcbiAgICByZXR1cm4gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgfTtcblxuICBQdWJsaWNLZXkuZnJvbUhleCA9IGZ1bmN0aW9uIGZyb21IZXgoaGV4KSB7XG4gICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tQnVmZmVyKEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpKTtcbiAgfTtcblxuICBQdWJsaWNLZXkucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24gdG9IZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9CdWZmZXIoKS50b1N0cmluZygnaGV4Jyk7XG4gIH07XG5cbiAgUHVibGljS2V5LmZyb21QdWJsaWNLZXlTdHJpbmdIZXggPSBmdW5jdGlvbiBmcm9tUHVibGljS2V5U3RyaW5nSGV4KGhleCkge1xuICAgIHJldHVybiBQdWJsaWNLZXkuZnJvbVB1YmxpY0tleVN0cmluZyhCdWZmZXIuZnJvbShoZXgsICdoZXgnKSk7XG4gIH07XG5cbiAgLyogPC9IRVg+ICovXG5cblxuICByZXR1cm4gUHVibGljS2V5O1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBQdWJsaWNLZXk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfcGVlcnBsYXlzanNXcyA9IHJlcXVpcmUoJ3BlZXJwbGF5c2pzLXdzJyk7XG5cbnZhciBfYnMgPSByZXF1aXJlKCdiczU4Jyk7XG5cbnZhciBfZGVlcEVxdWFsID0gcmVxdWlyZSgnZGVlcC1lcXVhbCcpO1xuXG52YXIgX2RlZXBFcXVhbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9kZWVwRXF1YWwpO1xuXG52YXIgX2hhc2gyID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbi8qKiBBZGRyZXNzZXMgYXJlIHNob3J0ZW5lZCBub24tcmV2ZXJzYWJsZSBoYXNoZXMgb2YgYSBwdWJsaWMga2V5LiAgVGhlIGZ1bGwgUHVibGljS2V5IGlzIHByZWZlcnJlZC5cbiAgICBAZGVwcmVjYXRlZFxuKi9cbnZhciBBZGRyZXNzID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBBZGRyZXNzKGFkZHkpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWRkcmVzcyk7XG5cbiAgICB0aGlzLmFkZHkgPSBhZGR5O1xuICB9XG5cbiAgQWRkcmVzcy5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICB2YXIgX2hhc2ggPSAoMCwgX2hhc2gyLnNoYTUxMikoYnVmZmVyKTtcbiAgICB2YXIgYWRkeSA9ICgwLCBfaGFzaDIucmlwZW1kMTYwKShfaGFzaCk7XG4gICAgcmV0dXJuIG5ldyBBZGRyZXNzKGFkZHkpO1xuICB9O1xuXG4gIEFkZHJlc3MuZnJvbVN0cmluZyA9IGZ1bmN0aW9uIGZyb21TdHJpbmcoc3RyaW5nKSB7XG4gICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgIHZhciBwcmVmaXggPSBzdHJpbmcuc2xpY2UoMCwgYWRkcmVzc19wcmVmaXgubGVuZ3RoKTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGFkZHJlc3NfcHJlZml4LCBwcmVmaXgsICdFeHBlY3Rpbmcga2V5IHRvIGJlZ2luIHdpdGggJyArIGFkZHJlc3NfcHJlZml4ICsgJywgaW5zdGVhZCBnb3QgJyArIHByZWZpeCk7XG4gICAgdmFyIGFkZHkgPSBzdHJpbmcuc2xpY2UoYWRkcmVzc19wcmVmaXgubGVuZ3RoKTtcbiAgICBhZGR5ID0gQnVmZmVyLmZyb20oKDAsIF9icy5kZWNvZGUpKGFkZHkpLCAnYmluYXJ5Jyk7XG4gICAgdmFyIGNoZWNrc3VtID0gYWRkeS5zbGljZSgtNCk7XG4gICAgYWRkeSA9IGFkZHkuc2xpY2UoMCwgLTQpO1xuICAgIHZhciBuZXdfY2hlY2tzdW0gPSAoMCwgX2hhc2gyLnJpcGVtZDE2MCkoYWRkeSk7XG4gICAgbmV3X2NoZWNrc3VtID0gbmV3X2NoZWNrc3VtLnNsaWNlKDAsIDQpO1xuICAgIHZhciBpc0VxdWFsID0gKDAsIF9kZWVwRXF1YWwyLmRlZmF1bHQpKGNoZWNrc3VtLCBuZXdfY2hlY2tzdW0pOyAvLyAsICdJbnZhbGlkIGNoZWNrc3VtJ1xuXG4gICAgaWYgKCFpc0VxdWFsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NoZWNrc3VtIGRpZCBub3QgbWF0Y2gnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEFkZHJlc3MoYWRkeSk7XG4gIH07XG5cbiAgLyoqIEByZXR1cm4gQWRkcmVzcyAtIENvbXByZXNzZWQgUFRTIGZvcm1hdCAoYnkgZGVmYXVsdCkgKi9cblxuXG4gIEFkZHJlc3MuZnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGZyb21QdWJsaWMocHVibGljX2tleSkge1xuICAgIHZhciBjb21wcmVzc2VkID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB0cnVlO1xuICAgIHZhciB2ZXJzaW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiA1NjtcblxuICAgIHZhciBzaGEyID0gKDAsIF9oYXNoMi5zaGEyNTYpKHB1YmxpY19rZXkudG9CdWZmZXIoY29tcHJlc3NlZCkpO1xuICAgIHZhciByZXAgPSAoMCwgX2hhc2gyLnJpcGVtZDE2MCkoc2hhMik7XG4gICAgdmFyIHZlcnNpb25CdWZmZXIgPSBCdWZmZXIuYWxsb2MoMSk7XG4gICAgdmVyc2lvbkJ1ZmZlci53cml0ZVVJbnQ4KDB4ZmYgJiB2ZXJzaW9uLCAwKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIHZhciBhZGRyID0gQnVmZmVyLmNvbmNhdChbdmVyc2lvbkJ1ZmZlciwgcmVwXSk7XG4gICAgdmFyIGNoZWNrID0gKDAsIF9oYXNoMi5zaGEyNTYpKGFkZHIpO1xuICAgIGNoZWNrID0gKDAsIF9oYXNoMi5zaGEyNTYpKGNoZWNrKTtcbiAgICB2YXIgYnVmZmVyID0gQnVmZmVyLmNvbmNhdChbYWRkciwgY2hlY2suc2xpY2UoMCwgNCldKTtcbiAgICByZXR1cm4gbmV3IEFkZHJlc3MoKDAsIF9oYXNoMi5yaXBlbWQxNjApKGJ1ZmZlcikpO1xuICB9O1xuXG4gIEFkZHJlc3MucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gdG9CdWZmZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkeTtcbiAgfTtcblxuICBBZGRyZXNzLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICB2YXIgY2hlY2tzdW0gPSAoMCwgX2hhc2gyLnJpcGVtZDE2MCkodGhpcy5hZGR5KTtcbiAgICB2YXIgYWRkeSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuYWRkeSwgY2hlY2tzdW0uc2xpY2UoMCwgNCldKTtcbiAgICByZXR1cm4gYWRkcmVzc19wcmVmaXggKyAoMCwgX2JzLmVuY29kZSkoYWRkeSk7XG4gIH07XG5cbiAgcmV0dXJuIEFkZHJlc3M7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEFkZHJlc3M7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYWVzID0gcmVxdWlyZSgnY3J5cHRvLWpzL2FlcycpO1xuXG52YXIgX2FlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hZXMpO1xuXG52YXIgX2VuY0hleCA9IHJlcXVpcmUoJ2NyeXB0by1qcy9lbmMtaGV4Jyk7XG5cbnZhciBfZW5jSGV4MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2VuY0hleCk7XG5cbnZhciBfZW5jQmFzZSA9IHJlcXVpcmUoJ2NyeXB0by1qcy9lbmMtYmFzZTY0Jyk7XG5cbnZhciBfZW5jQmFzZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lbmNCYXNlKTtcblxudmFyIF9hc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTtcblxudmFyIF9hc3NlcnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0KTtcblxudmFyIF9oYXNoMiA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfSAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qc1xuXG5cbi8qKiBQcm92aWRlcyBzeW1ldHJpYyBlbmNyeXB0IGFuZCBkZWNyeXB0IHZpYSBBRVMuICovXG52YXIgQWVzID0gZnVuY3Rpb24gKCkge1xuICAvKiogQHByaXZhdGUgKi9cbiAgZnVuY3Rpb24gQWVzKGl2LCBrZXkpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWVzKTtcblxuICAgIHRoaXMuaXYgPSBpdjtcbiAgICB0aGlzLmtleSA9IGtleTtcbiAgfVxuXG4gIC8qKiBUaGlzIGlzIGFuIGV4Y2VsbGVudCB3YXkgdG8gZW5zdXJlIHRoYXQgYWxsIHJlZmVyZW5jZXMgdG8gQWVzIGNhbiBub3Qgb3BlcmF0ZSBhbnltb3JlXG4gICAqIChleGFtcGxlOiBhIHdhbGxldCBiZWNvbWVzIGxvY2tlZCkuICBBbiBhcHBsaWNhdGlvbiBzaG91bGQgZW5zdXJlIHRoZXJlIGlzIG9ubHkgb25lXG4gICAqIEFlcyBvYmplY3QgaW5zdGFuY2UgZm9yIGEgZ2l2ZW4gc2VjcmV0IGBzZWVkYC4gKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICB0aGlzLml2ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMua2V5ID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG5cbiAgLyoqIEBhcmcge3N0cmluZ30gc2VlZCAtIHNlY3JldCBzZWVkIG1heSBiZSB1c2VkIHRvIGVuY3J5cHQgb3IgZGVjcnlwdC4gKi9cblxuXG4gIEFlcy5mcm9tU2VlZCA9IGZ1bmN0aW9uIGZyb21TZWVkKHNlZWQpIHtcbiAgICBpZiAoc2VlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NlZWQgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICB2YXIgX2hhc2ggPSAoMCwgX2hhc2gyLnNoYTUxMikoc2VlZCk7XG4gICAgX2hhc2ggPSBfaGFzaC50b1N0cmluZygnaGV4Jyk7XG4gICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiBmcm9tU2VlZCBfaGFzaCcsX2hhc2gpXG4gICAgcmV0dXJuIEFlcy5mcm9tU2hhNTEyKF9oYXNoKTtcbiAgfTtcblxuICAvKiogQGFyZyB7c3RyaW5nfSBoYXNoIC0gQSAxMjggYnl0ZSBoZXggc3RyaW5nLCB0eXBpY2FsbHkgb25lXG4gICAqIHdvdWxkIGNhbGwge0BsaW5rIGZyb21TZWVkfSBpbnN0ZWFkLiAqL1xuXG5cbiAgQWVzLmZyb21TaGE1MTIgPSBmdW5jdGlvbiBmcm9tU2hhNTEyKGhhc2gpIHtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGhhc2gubGVuZ3RoLCAxMjgsICdBIFNoYTUxMiBpbiBIRVggc2hvdWxkIGJlIDEyOCBjaGFyYWN0ZXJzIGxvbmcsIGluc3RlYWQgZ290ICcgKyBoYXNoLmxlbmd0aCk7XG4gICAgdmFyIGl2ID0gX2VuY0hleDIuZGVmYXVsdC5wYXJzZShoYXNoLnN1YnN0cmluZyg2NCwgOTYpKTtcbiAgICB2YXIga2V5ID0gX2VuY0hleDIuZGVmYXVsdC5wYXJzZShoYXNoLnN1YnN0cmluZygwLCA2NCkpO1xuICAgIHJldHVybiBuZXcgQWVzKGl2LCBrZXkpO1xuICB9O1xuXG4gIEFlcy5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWYpIHtcbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoQnVmZmVyLmlzQnVmZmVyKGJ1ZiksICdFeHBlY3RpbmcgQnVmZmVyJyk7XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChidWYubGVuZ3RoLCA2NCwgJ0EgU2hhNTEyIEJ1ZmZlciBzaG91bGQgYmUgNjQgY2hhcmFjdGVycyBsb25nLCBpbnN0ZWFkIGdvdCAnICsgYnVmLmxlbmd0aCk7XG4gICAgcmV0dXJuIEFlcy5mcm9tU2hhNTEyKGJ1Zi50b1N0cmluZygnaGV4JykpO1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBAdGhyb3dzIHtFcnJvcn0gLSBcIkludmFsaWQgS2V5LCAuLi5cIlxuICAgICAgICBAYXJnIHtQcml2YXRlS2V5fSBwcml2YXRlX2tleSAtIHJlcXVpcmVkIGFuZCB1c2VkIGZvciBkZWNyeXB0aW9uXG4gICAgICAgIEBhcmcge1B1YmxpY0tleX0gcHVibGljX2tleSAtIHJlcXVpcmVkIGFuZCB1c2VkIHRvIGNhbGN1YWx0ZSB0aGUgc2hhcmVkIHNlY3JldFxuICAgICAgICBAYXJnIHtzdHJpbmd9IFtub25jZSA9IFwiXCJdIG9wdGlvbmFsIGJ1dCBzaG91bGQgYWx3YXlzIGJlIHByb3ZpZGVkIGFuZCBiZSB1bmlxdWVcbiAgICAgICAgd2hlbiByZS11c2luZyB0aGUgc2FtZSBwcml2YXRlL3B1YmxpYyBrZXlzIG1vcmUgdGhhbiBvbmNlLiAgVGhpcyBub25jZSBpcyBub3QgYSBzZWNyZXQuXG4gICAgICAgIEBhcmcge3N0cmluZ3xCdWZmZXJ9IG1lc3NhZ2UgLSBFbmNyeXB0ZWQgbWVzc2FnZSBjb250YWluaW5nIGEgY2hlY2tzdW1cbiAgICAgICAgQHJldHVybiB7QnVmZmVyfVxuICAgICovXG5cblxuICBBZXMuZGVjcnlwdF93aXRoX2NoZWNrc3VtID0gZnVuY3Rpb24gZGVjcnlwdF93aXRoX2NoZWNrc3VtKHByaXZhdGVfa2V5LCBwdWJsaWNfa2V5LCBub25jZSwgbWVzc2FnZSkge1xuICAgIHZhciBsZWdhY3kgPSBhcmd1bWVudHMubGVuZ3RoID4gNCAmJiBhcmd1bWVudHNbNF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1s0XSA6IGZhbHNlO1xuXG4gICAgLy8gV2FybmluZzogRG8gbm90IHB1dCBgbm9uY2UgPSBcIlwiYCBpbiB0aGUgYXJndW1lbnRzLCBpbiBlczYgdGhpcyB3aWxsXG4gICAgLy8gbm90IGNvbnZlcnQgXCJudWxsXCIgaW50byBhbiBlbXRweSBzdHJpbmdcbiAgICBpZiAobm9uY2UgPT0gbnVsbCkge1xuICAgICAgbm9uY2UgPSAnJztcbiAgICB9XG5cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihtZXNzYWdlKSkge1xuICAgICAgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKG1lc3NhZ2UsICdoZXgnKTtcbiAgICB9XG5cbiAgICB2YXIgUyA9IHByaXZhdGVfa2V5LmdldF9zaGFyZWRfc2VjcmV0KHB1YmxpY19rZXksIGxlZ2FjeSk7XG4gICAgLy8gRCBFIEIgVSBHXG4gICAgLy8gY29uc29sZS5sb2coJ2RlY3J5cHRfd2l0aF9jaGVja3N1bScsIHtcbiAgICAvLyAgICAgcHJpdl90b19wdWI6IHByaXZhdGVfa2V5LnRvUHVibGljS2V5KCkudG9TdHJpbmcoKSxcbiAgICAvLyAgICAgcHViOiBwdWJsaWNfa2V5LnRvUHVibGljS2V5U3RyaW5nKCksXG4gICAgLy8gICAgIG5vbmNlOiBub25jZSxcbiAgICAvLyAgICAgbWVzc2FnZTogbWVzc2FnZS5sZW5ndGgsXG4gICAgLy8gICAgIFM6IFMudG9TdHJpbmcoJ2hleCcpXG4gICAgLy8gfSlcblxuICAgIHZhciBhZXMgPSBBZXMuZnJvbVNlZWQoQnVmZmVyLmNvbmNhdChbXG4gICAgLy8gQSBudWxsIG9yIGVtcHR5IHN0cmluZyBub25jZSB3aWxsIG5vdCBlZmZlY3QgdGhlIGhhc2hcbiAgICBCdWZmZXIuZnJvbSgnJyArIG5vbmNlKSwgQnVmZmVyLmZyb20oUy50b1N0cmluZygnaGV4JykpXSkpO1xuXG4gICAgdmFyIHBsYW5lYnVmZmVyID0gYWVzLmRlY3J5cHQobWVzc2FnZSk7XG5cbiAgICBpZiAoIShwbGFuZWJ1ZmZlci5sZW5ndGggPj0gNCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBrZXksIGNvdWxkIG5vdCBkZWNyeXB0IG1lc3NhZ2UoMSknKTtcbiAgICB9XG5cbiAgICAvLyBERUJVRyBjb25zb2xlLmxvZygnLi4uIHBsYW5lYnVmZmVyJyxwbGFuZWJ1ZmZlcilcbiAgICB2YXIgY2hlY2tzdW0gPSBwbGFuZWJ1ZmZlci5zbGljZSgwLCA0KTtcbiAgICB2YXIgcGxhaW50ZXh0ID0gcGxhbmVidWZmZXIuc2xpY2UoNCk7XG5cbiAgICAvLyBjb25zb2xlLmxvZygnLi4uIGNoZWNrc3VtJyxjaGVja3N1bS50b1N0cmluZygnaGV4JykpXG4gICAgLy8gY29uc29sZS5sb2coJy4uLiBwbGFpbnRleHQnLHBsYWludGV4dC50b1N0cmluZygpKVxuXG4gICAgdmFyIG5ld19jaGVja3N1bSA9ICgwLCBfaGFzaDIuc2hhMjU2KShwbGFpbnRleHQpO1xuICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS5zbGljZSgwLCA0KTtcbiAgICBuZXdfY2hlY2tzdW0gPSBuZXdfY2hlY2tzdW0udG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgaWYgKCEoY2hlY2tzdW0udG9TdHJpbmcoJ2hleCcpID09PSBuZXdfY2hlY2tzdW0pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5LCBjb3VsZCBub3QgZGVjcnlwdCBtZXNzYWdlKDIpJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBsYWludGV4dDtcbiAgfTtcblxuICAvKiogSWRlbnRpY2FsIHRvIHtAbGluayBkZWNyeXB0X3dpdGhfY2hlY2tzdW19IGJ1dCB1c2VkIHRvIGVuY3J5cHQuICBTaG91bGQgbm90IHRocm93IGFuIGVycm9yLlxuICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9IG1lc3NhZ2UgLSBFbmNyeXB0ZWQgbWVzc2FnZSB3aGljaCBpbmNsdWRlcyBhIGNoZWNrc3VtXG4gICAgKi9cblxuXG4gIEFlcy5lbmNyeXB0X3dpdGhfY2hlY2tzdW0gPSBmdW5jdGlvbiBlbmNyeXB0X3dpdGhfY2hlY2tzdW0ocHJpdmF0ZV9rZXksIHB1YmxpY19rZXksIG5vbmNlLCBtZXNzYWdlKSB7XG4gICAgLy8gV2FybmluZzogRG8gbm90IHB1dCBgbm9uY2UgPSBcIlwiYCBpbiB0aGUgYXJndW1lbnRzLCBpbiBlczYgdGhpcyB3aWxsXG4gICAgLy8gbm90IGNvbnZlcnQgXCJudWxsXCIgaW50byBhbiBlbXRweSBzdHJpbmdcblxuICAgIGlmIChub25jZSA9PSBudWxsKSB7XG4gICAgICBub25jZSA9ICcnO1xuICAgIH1cblxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKG1lc3NhZ2UpKSB7XG4gICAgICBtZXNzYWdlID0gQnVmZmVyLmZyb20obWVzc2FnZSwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIHZhciBTID0gcHJpdmF0ZV9rZXkuZ2V0X3NoYXJlZF9zZWNyZXQocHVibGljX2tleSk7XG5cbiAgICAvLyBEIEUgQiBVIEdcbiAgICAvLyBjb25zb2xlLmxvZygnZW5jcnlwdF93aXRoX2NoZWNrc3VtJywge1xuICAgIC8vICAgICBwcml2X3RvX3B1YjogcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKS50b1N0cmluZygpXG4gICAgLy8gICAgIHB1YjogcHVibGljX2tleS50b1B1YmxpY0tleVN0cmluZygpXG4gICAgLy8gICAgIG5vbmNlOiBub25jZVxuICAgIC8vICAgICBtZXNzYWdlOiBtZXNzYWdlLmxlbmd0aFxuICAgIC8vICAgICBTOiBTLnRvU3RyaW5nKCdoZXgnKVxuICAgIC8vIH0pXG5cbiAgICB2YXIgYWVzID0gQWVzLmZyb21TZWVkKEJ1ZmZlci5jb25jYXQoW1xuICAgIC8vIEEgbnVsbCBvciBlbXB0eSBzdHJpbmcgbm9uY2Ugd2lsbCBub3QgZWZmZWN0IHRoZSBoYXNoXG4gICAgQnVmZmVyLmZyb20oJycgKyBub25jZSksIEJ1ZmZlci5mcm9tKFMudG9TdHJpbmcoJ2hleCcpKV0pKTtcbiAgICAvLyBERUJVRyBjb25zb2xlLmxvZygnLi4uIFMnLFMudG9TdHJpbmcoJ2hleCcpKVxuICAgIHZhciBjaGVja3N1bSA9ICgwLCBfaGFzaDIuc2hhMjU2KShtZXNzYWdlKS5zbGljZSgwLCA0KTtcbiAgICB2YXIgcGF5bG9hZCA9IEJ1ZmZlci5jb25jYXQoW2NoZWNrc3VtLCBtZXNzYWdlXSk7XG4gICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiBwYXlsb2FkJyxwYXlsb2FkLnRvU3RyaW5nKCkpXG4gICAgcmV0dXJuIGFlcy5lbmNyeXB0KHBheWxvYWQpO1xuICB9O1xuXG4gIC8qKiBAcHJpdmF0ZSAqL1xuXG5cbiAgQWVzLnByb3RvdHlwZS5fZGVjcnlwdF93b3JkX2FycmF5ID0gZnVuY3Rpb24gX2RlY3J5cHRfd29yZF9hcnJheShjaXBoZXIpIHtcbiAgICAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy8jQ3VzdG9tX0tleV9hbmRfSVZcbiAgICAvLyBzZWUgd2FsbGV0X3JlY29yZHMuY3BwIG1hc3Rlcl9rZXk6OmRlY3J5cHRfa2V5XG4gICAgcmV0dXJuIF9hZXMyLmRlZmF1bHQuZGVjcnlwdCh7IGNpcGhlcnRleHQ6IGNpcGhlciwgc2FsdDogbnVsbCB9LCB0aGlzLmtleSwgeyBpdjogdGhpcy5pdiB9KTtcbiAgfTtcblxuICAvKiogQHByaXZhdGUgKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuX2VuY3J5cHRfd29yZF9hcnJheSA9IGZ1bmN0aW9uIF9lbmNyeXB0X3dvcmRfYXJyYXkocGxhaW50ZXh0KSB7XG4gICAgLy8gaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvaXNzdWVzL2RldGFpbD9pZD04NVxuICAgIHZhciBjaXBoZXIgPSBfYWVzMi5kZWZhdWx0LmVuY3J5cHQocGxhaW50ZXh0LCB0aGlzLmtleSwgeyBpdjogdGhpcy5pdiB9KTtcbiAgICByZXR1cm4gX2VuY0Jhc2UyLmRlZmF1bHQucGFyc2UoY2lwaGVyLnRvU3RyaW5nKCkpO1xuICB9O1xuXG4gIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ30gY2lwaGVydGV4dFxuICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9IGJpbmFyeVxuICAgICovXG5cblxuICBBZXMucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbiBkZWNyeXB0KGNpcGhlcnRleHQpIHtcbiAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjaXBoZXJ0ZXh0ID0gQnVmZmVyLmZyb20oY2lwaGVydGV4dCwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGNpcGhlcnRleHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1ZmZlciByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShjaXBoZXJ0ZXh0LCAnTWlzc2luZyBjaXBoZXIgdGV4dCcpO1xuICAgIC8vIGhleCBpcyB0aGUgb25seSBjb21tb24gZm9ybWF0XG4gICAgdmFyIGhleCA9IHRoaXMuZGVjcnlwdEhleChjaXBoZXJ0ZXh0LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpO1xuICB9O1xuXG4gIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ30gcGxhaW50ZXh0XG4gICAgICAgIEByZXR1cm4ge0J1ZmZlcn0gYmluYXJ5XG4gICAgKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuZW5jcnlwdCA9IGZ1bmN0aW9uIGVuY3J5cHQocGxhaW50ZXh0KSB7XG4gICAgaWYgKHR5cGVvZiBwbGFpbnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBwbGFpbnRleHQgPSBCdWZmZXIuZnJvbShwbGFpbnRleHQsICdiaW5hcnknKTtcbiAgICB9XG5cbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwbGFpbnRleHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1ZmZlciByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8vIGFzc2VydCBwbGFpbnRleHQsIFwiTWlzc2luZyBwbGFpbiB0ZXh0XCJcbiAgICAvLyBoZXggaXMgdGhlIG9ubHkgY29tbW9uIGZvcm1hdFxuICAgIHZhciBoZXggPSB0aGlzLmVuY3J5cHRIZXgocGxhaW50ZXh0LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpO1xuICB9O1xuXG4gIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ3xCdWZmZXJ9IHBsYWludGV4dFxuICAgICAgICBAcmV0dXJuIHtzdHJpbmd9IGhleFxuICAgICovXG5cblxuICBBZXMucHJvdG90eXBlLmVuY3J5cHRUb0hleCA9IGZ1bmN0aW9uIGVuY3J5cHRUb0hleChwbGFpbnRleHQpIHtcbiAgICBpZiAodHlwZW9mIHBsYWludGV4dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHBsYWludGV4dCA9IEJ1ZmZlci5mcm9tKHBsYWludGV4dCwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKHBsYWludGV4dCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYnVmZmVyIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgLy8gYXNzZXJ0IHBsYWludGV4dCwgXCJNaXNzaW5nIHBsYWluIHRleHRcIlxuICAgIC8vIGhleCBpcyB0aGUgb25seSBjb21tb24gZm9ybWF0XG4gICAgcmV0dXJuIHRoaXMuZW5jcnlwdEhleChwbGFpbnRleHQudG9TdHJpbmcoJ2hleCcpKTtcbiAgfTtcblxuICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICBAYXJnIHtzdHJpbmd9IGNpcGhlciAtIGhleFxuICAgICAgICBAcmV0dXJuIHtzdHJpbmd9IGJpbmFyeSAoY291bGQgZWFzaWx5IGJlIHJlYWRhYmxlIHRleHQpXG4gICAgKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuZGVjcnlwdEhleCA9IGZ1bmN0aW9uIGRlY3J5cHRIZXgoY2lwaGVyKSB7XG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKGNpcGhlciwgJ01pc3NpbmcgY2lwaGVyIHRleHQnKTtcbiAgICAvLyBDb252ZXJ0IGRhdGEgaW50byB3b3JkIGFycmF5cyAodXNlZCBieSBDcnlwdG8pXG4gICAgdmFyIGNpcGhlcl9hcnJheSA9IF9lbmNIZXgyLmRlZmF1bHQucGFyc2UoY2lwaGVyKTtcbiAgICB2YXIgcGxhaW53b3JkcyA9IHRoaXMuX2RlY3J5cHRfd29yZF9hcnJheShjaXBoZXJfYXJyYXkpO1xuICAgIHJldHVybiBfZW5jSGV4Mi5kZWZhdWx0LnN0cmluZ2lmeShwbGFpbndvcmRzKTtcbiAgfTtcblxuICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICBAYXJnIHtzdHJpbmd9IGNpcGhlciAtIGhleFxuICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9IGVuY29kZWQgYXMgc3BlY2lmaWVkIGJ5IHRoZSBwYXJhbWV0ZXJcbiAgICAqL1xuXG5cbiAgQWVzLnByb3RvdHlwZS5kZWNyeXB0SGV4VG9CdWZmZXIgPSBmdW5jdGlvbiBkZWNyeXB0SGV4VG9CdWZmZXIoY2lwaGVyKSB7XG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKGNpcGhlciwgJ01pc3NpbmcgY2lwaGVyIHRleHQnKTtcbiAgICAvLyBDb252ZXJ0IGRhdGEgaW50byB3b3JkIGFycmF5cyAodXNlZCBieSBDcnlwdG8pXG4gICAgdmFyIGNpcGhlcl9hcnJheSA9IF9lbmNIZXgyLmRlZmF1bHQucGFyc2UoY2lwaGVyKTtcbiAgICB2YXIgcGxhaW53b3JkcyA9IHRoaXMuX2RlY3J5cHRfd29yZF9hcnJheShjaXBoZXJfYXJyYXkpO1xuICAgIHZhciBwbGFpbmhleCA9IF9lbmNIZXgyLmRlZmF1bHQuc3RyaW5naWZ5KHBsYWlud29yZHMpO1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShwbGFpbmhleCwgJ2hleCcpO1xuICB9O1xuXG4gIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ30gY2lwaGVyIC0gaGV4XG4gICAgICAgIEBhcmcge3N0cmluZ30gW2VuY29kaW5nID0gJ2JpbmFyeSddIC0gYSB2YWxpZCBCdWZmZXIgZW5jb2RpbmdcbiAgICAgICAgQHJldHVybiB7U3RyaW5nfSBlbmNvZGVkIGFzIHNwZWNpZmllZCBieSB0aGUgcGFyYW1ldGVyXG4gICAgKi9cblxuXG4gIEFlcy5wcm90b3R5cGUuZGVjcnlwdEhleFRvVGV4dCA9IGZ1bmN0aW9uIGRlY3J5cHRIZXhUb1RleHQoY2lwaGVyKSB7XG4gICAgdmFyIGVuY29kaW5nID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnYmluYXJ5JztcblxuICAgIHJldHVybiB0aGlzLmRlY3J5cHRIZXhUb0J1ZmZlcihjaXBoZXIpLnRvU3RyaW5nKGVuY29kaW5nKTtcbiAgfTtcblxuICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICBAYXJnIHtzdHJpbmd9IHBsYWluaGV4IC0gaGV4IGZvcm1hdFxuICAgICAgICBAcmV0dXJuIHtTdHJpbmd9IGhleFxuICAgICovXG5cblxuICBBZXMucHJvdG90eXBlLmVuY3J5cHRIZXggPSBmdW5jdGlvbiBlbmNyeXB0SGV4KHBsYWluaGV4KSB7XG4gICAgdmFyIHBsYWluX2FycmF5ID0gX2VuY0hleDIuZGVmYXVsdC5wYXJzZShwbGFpbmhleCk7XG4gICAgdmFyIGNpcGhlcl9hcnJheSA9IHRoaXMuX2VuY3J5cHRfd29yZF9hcnJheShwbGFpbl9hcnJheSk7XG4gICAgcmV0dXJuIF9lbmNIZXgyLmRlZmF1bHQuc3RyaW5naWZ5KGNpcGhlcl9hcnJheSk7XG4gIH07XG5cbiAgcmV0dXJuIEFlcztcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gQWVzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy52ZXJpZnlSYXcgPSBleHBvcnRzLnZlcmlmeSA9IGV4cG9ydHMuc2lnbiA9IGV4cG9ydHMucmVjb3ZlclB1YktleSA9IGV4cG9ydHMuZGV0ZXJtaW5pc3RpY0dlbmVyYXRlSyA9IGV4cG9ydHMuY2FsY1B1YktleVJlY292ZXJ5UGFyYW0gPSB1bmRlZmluZWQ7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfYmlnaSA9IHJlcXVpcmUoJ2JpZ2knKTtcblxudmFyIF9iaWdpMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2JpZ2kpO1xuXG52YXIgX2hhc2ggPSByZXF1aXJlKCcuL2hhc2gnKTtcblxudmFyIF9lbmZvcmNlX3R5cGVzID0gcmVxdWlyZSgnLi9lbmZvcmNlX3R5cGVzJyk7XG5cbnZhciBfZW5mb3JjZV90eXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lbmZvcmNlX3R5cGVzKTtcblxudmFyIF9lY3NpZ25hdHVyZSA9IHJlcXVpcmUoJy4vZWNzaWduYXR1cmUnKTtcblxudmFyIF9lY3NpZ25hdHVyZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lY3NpZ25hdHVyZSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8vIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM2OTc5I3NlY3Rpb24tMy4yXG5cbi8vIGZyb20gZ2l0aHViLmNvbS9iaXRjb2luanMvYml0Y29pbmpzLWxpYiBmcm9tIGdpdGh1Yi5jb20vY3J5cHRvY29pbmpzL2VjZHNhXG5mdW5jdGlvbiBkZXRlcm1pbmlzdGljR2VuZXJhdGVLKGN1cnZlLCBoYXNoLCBkLCBjaGVja1NpZywgbm9uY2UpIHtcbiAgKDAsIF9lbmZvcmNlX3R5cGVzMi5kZWZhdWx0KSgnQnVmZmVyJywgaGFzaCk7XG4gICgwLCBfZW5mb3JjZV90eXBlczIuZGVmYXVsdCkoX2JpZ2kyLmRlZmF1bHQsIGQpO1xuXG4gIGlmIChub25jZSkge1xuICAgIGhhc2ggPSAoMCwgX2hhc2guc2hhMjU2KShCdWZmZXIuY29uY2F0KFtoYXNoLCBCdWZmZXIuYWxsb2Mobm9uY2UpXSkpO1xuICB9XG5cbiAgLy8gc2FuaXR5IGNoZWNrXG4gIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoaGFzaC5sZW5ndGgsIDMyLCAnSGFzaCBtdXN0IGJlIDI1NiBiaXQnKTtcblxuICB2YXIgeCA9IGQudG9CdWZmZXIoMzIpO1xuICB2YXIgayA9IEJ1ZmZlci5hbGxvYygzMik7XG4gIHZhciB2ID0gQnVmZmVyLmFsbG9jKDMyKTtcblxuICAvLyBTdGVwIEJcbiAgdi5maWxsKDEpO1xuXG4gIC8vIFN0ZXAgQ1xuICBrLmZpbGwoMCk7XG5cbiAgLy8gU3RlcCBEXG4gIGsgPSAoMCwgX2hhc2guSG1hY1NIQTI1NikoQnVmZmVyLmNvbmNhdChbdiwgQnVmZmVyLmZyb20oWzBdKSwgeCwgaGFzaF0pLCBrKTtcblxuICAvLyBTdGVwIEVcbiAgdiA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KSh2LCBrKTtcblxuICAvLyBTdGVwIEZcbiAgayA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KShCdWZmZXIuY29uY2F0KFt2LCBCdWZmZXIuZnJvbShbMV0pLCB4LCBoYXNoXSksIGspO1xuXG4gIC8vIFN0ZXAgR1xuICB2ID0gKDAsIF9oYXNoLkhtYWNTSEEyNTYpKHYsIGspO1xuXG4gIC8vIFN0ZXAgSDEvSDJhLCBpZ25vcmVkIGFzIHRsZW4gPT09IHFsZW4gKDI1NiBiaXQpXG4gIC8vIFN0ZXAgSDJiXG4gIHYgPSAoMCwgX2hhc2guSG1hY1NIQTI1Nikodiwgayk7XG5cbiAgdmFyIFQgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKHYpO1xuXG4gIC8vIFN0ZXAgSDMsIHJlcGVhdCB1bnRpbCBUIGlzIHdpdGhpbiB0aGUgaW50ZXJ2YWwgWzEsIG4gLSAxXVxuICB3aGlsZSAoVC5zaWdudW0oKSA8PSAwIHx8IFQuY29tcGFyZVRvKGN1cnZlLm4pID49IDAgfHwgIWNoZWNrU2lnKFQpKSB7XG4gICAgayA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KShCdWZmZXIuY29uY2F0KFt2LCBCdWZmZXIuZnJvbShbMF0pXSksIGspO1xuICAgIHYgPSAoMCwgX2hhc2guSG1hY1NIQTI1Nikodiwgayk7XG5cbiAgICAvLyBTdGVwIEgxL0gyYSwgYWdhaW4sIGlnbm9yZWQgYXMgdGxlbiA9PT0gcWxlbiAoMjU2IGJpdClcbiAgICAvLyBTdGVwIEgyYiBhZ2FpblxuICAgIHYgPSAoMCwgX2hhc2guSG1hY1NIQTI1Nikodiwgayk7XG5cbiAgICBUID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcih2KTtcbiAgfVxuXG4gIHJldHVybiBUO1xufVxuXG5mdW5jdGlvbiBzaWduKGN1cnZlLCBoYXNoLCBkLCBub25jZSkge1xuICB2YXIgZSA9IF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoaGFzaCk7XG4gIHZhciBuID0gY3VydmUubjtcbiAgdmFyIEcgPSBjdXJ2ZS5HO1xuXG4gIHZhciByID0gdm9pZCAwO1xuICB2YXIgcyA9IHZvaWQgMDtcblxuICBkZXRlcm1pbmlzdGljR2VuZXJhdGVLKGN1cnZlLCBoYXNoLCBkLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgLy8gZmluZCBjYW5vbmljYWxseSB2YWxpZCBzaWduYXR1cmVcbiAgICB2YXIgUSA9IEcubXVsdGlwbHkoa2V5KTtcblxuICAgIGlmIChjdXJ2ZS5pc0luZmluaXR5KFEpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgciA9IFEuYWZmaW5lWC5tb2Qobik7XG5cbiAgICBpZiAoci5zaWdudW0oKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHMgPSBrZXkubW9kSW52ZXJzZShuKS5tdWx0aXBseShlLmFkZChkLm11bHRpcGx5KHIpKSkubW9kKG4pO1xuXG4gICAgaWYgKHMuc2lnbnVtKCkgPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgbm9uY2UpO1xuXG4gIHZhciBOX09WRVJfVFdPID0gbi5zaGlmdFJpZ2h0KDEpO1xuXG4gIC8vIGVuZm9yY2UgbG93IFMgdmFsdWVzLCBzZWUgYmlwNjI6ICdsb3cgcyB2YWx1ZXMgaW4gc2lnbmF0dXJlcydcbiAgaWYgKHMuY29tcGFyZVRvKE5fT1ZFUl9UV08pID4gMCkge1xuICAgIHMgPSBuLnN1YnRyYWN0KHMpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBfZWNzaWduYXR1cmUyLmRlZmF1bHQociwgcyk7XG59XG5cbmZ1bmN0aW9uIHZlcmlmeVJhdyhjdXJ2ZSwgZSwgc2lnbmF0dXJlLCBRKSB7XG4gIHZhciBuID0gY3VydmUubjtcbiAgdmFyIEcgPSBjdXJ2ZS5HO1xuXG4gIHZhciByID0gc2lnbmF0dXJlLnI7XG4gIHZhciBzID0gc2lnbmF0dXJlLnM7XG5cbiAgLy8gMS40LjEgRW5mb3JjZSByIGFuZCBzIGFyZSBib3RoIGludGVnZXJzIGluIHRoZSBpbnRlcnZhbCBbMSwgbiDiiJIgMV1cbiAgaWYgKHIuc2lnbnVtKCkgPD0gMCB8fCByLmNvbXBhcmVUbyhuKSA+PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKHMuc2lnbnVtKCkgPD0gMCB8fCBzLmNvbXBhcmVUbyhuKSA+PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gYyA9IHNeLTEgbW9kIG5cbiAgdmFyIGMgPSBzLm1vZEludmVyc2Uobik7XG5cbiAgLy8gMS40LjQgQ29tcHV0ZSB1MSA9IGVzXuKIkjEgbW9kIG5cbiAgLy8gICAgICAgICAgICAgICB1MiA9IHJzXuKIkjEgbW9kIG5cbiAgdmFyIHUxID0gZS5tdWx0aXBseShjKS5tb2Qobik7XG4gIHZhciB1MiA9IHIubXVsdGlwbHkoYykubW9kKG4pO1xuXG4gIC8vIDEuNC41IENvbXB1dGUgUiA9ICh4UiwgeVIpID0gdTFHICsgdTJRXG4gIHZhciBSID0gRy5tdWx0aXBseVR3byh1MSwgUSwgdTIpO1xuXG4gIC8vIDEuNC41IChjb250LikgRW5mb3JjZSBSIGlzIG5vdCBhdCBpbmZpbml0eVxuICBpZiAoY3VydmUuaXNJbmZpbml0eShSKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIDEuNC42IENvbnZlcnQgdGhlIGZpZWxkIGVsZW1lbnQgUi54IHRvIGFuIGludGVnZXJcbiAgdmFyIHhSID0gUi5hZmZpbmVYO1xuXG4gIC8vIDEuNC43IFNldCB2ID0geFIgbW9kIG5cbiAgdmFyIHYgPSB4Ui5tb2Qobik7XG5cbiAgLy8gMS40LjggSWYgdiA9IHIsIG91dHB1dCBcInZhbGlkXCIsIGFuZCBpZiB2ICE9IHIsIG91dHB1dCBcImludmFsaWRcIlxuICByZXR1cm4gdi5lcXVhbHMocik7XG59XG5cbmZ1bmN0aW9uIHZlcmlmeShjdXJ2ZSwgaGFzaCwgc2lnbmF0dXJlLCBRKSB7XG4gIC8vIDEuNC4yIEggPSBIYXNoKE0pLCBhbHJlYWR5IGRvbmUgYnkgdGhlIHVzZXJcbiAgLy8gMS40LjMgZSA9IEhcbiAgdmFyIGUgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGhhc2gpO1xuICByZXR1cm4gdmVyaWZ5UmF3KGN1cnZlLCBlLCBzaWduYXR1cmUsIFEpO1xufVxuXG4vKipcbiAqIFJlY292ZXIgYSBwdWJsaWMga2V5IGZyb20gYSBzaWduYXR1cmUuXG4gKlxuICogU2VlIFNFQyAxOiBFbGxpcHRpYyBDdXJ2ZSBDcnlwdG9ncmFwaHksIHNlY3Rpb24gNC4xLjYsIFwiUHVibGljXG4gKiBLZXkgUmVjb3ZlcnkgT3BlcmF0aW9uXCIuXG4gKlxuICogaHR0cDovL3d3dy5zZWNnLm9yZy9kb3dubG9hZC9haWQtNzgwL3NlYzEtdjIucGRmXG4gKi9cbmZ1bmN0aW9uIHJlY292ZXJQdWJLZXkoY3VydmUsIGUsIHNpZ25hdHVyZSwgaSkge1xuICBfYXNzZXJ0Mi5kZWZhdWx0LnN0cmljdEVxdWFsKGkgJiAzLCBpLCAnUmVjb3ZlcnkgcGFyYW0gaXMgbW9yZSB0aGFuIHR3byBiaXRzJyk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICB2YXIgbiA9IGN1cnZlLm47XG4gIHZhciBHID0gY3VydmUuRztcblxuICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICB2YXIgcyA9IHNpZ25hdHVyZS5zO1xuXG4gICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShyLnNpZ251bSgpID4gMCAmJiByLmNvbXBhcmVUbyhuKSA8IDAsICdJbnZhbGlkIHIgdmFsdWUnKTtcbiAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKHMuc2lnbnVtKCkgPiAwICYmIHMuY29tcGFyZVRvKG4pIDwgMCwgJ0ludmFsaWQgcyB2YWx1ZScpO1xuXG4gIC8vIEEgc2V0IExTQiBzaWduaWZpZXMgdGhhdCB0aGUgeS1jb29yZGluYXRlIGlzIG9kZFxuICB2YXIgaXNZT2RkID0gaSAmIDE7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAvLyBUaGUgbW9yZSBzaWduaWZpY2FudCBiaXQgc3BlY2lmaWVzIHdoZXRoZXIgd2Ugc2hvdWxkIHVzZSB0aGVcbiAgLy8gZmlyc3Qgb3Igc2Vjb25kIGNhbmRpZGF0ZSBrZXkuXG4gIHZhciBpc1NlY29uZEtleSA9IGkgPj4gMTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gIC8vIDEuMSBMZXQgeCA9IHIgKyBqblxuICB2YXIgeCA9IGlzU2Vjb25kS2V5ID8gci5hZGQobikgOiByO1xuICB2YXIgUiA9IGN1cnZlLnBvaW50RnJvbVgoaXNZT2RkLCB4KTtcblxuICAvLyAxLjQgQ2hlY2sgdGhhdCBuUiBpcyBhdCBpbmZpbml0eVxuICB2YXIgblIgPSBSLm11bHRpcGx5KG4pO1xuICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoY3VydmUuaXNJbmZpbml0eShuUiksICduUiBpcyBub3QgYSB2YWxpZCBjdXJ2ZSBwb2ludCcpO1xuXG4gIC8vIENvbXB1dGUgLWUgZnJvbSBlXG4gIHZhciBlTmVnID0gZS5uZWdhdGUoKS5tb2Qobik7XG5cbiAgLy8gMS42LjEgQ29tcHV0ZSBRID0gcl4tMSAoc1IgLSAgZUcpXG4gIC8vICAgICAgICAgICAgICAgUSA9IHJeLTEgKHNSICsgLWVHKVxuICB2YXIgckludiA9IHIubW9kSW52ZXJzZShuKTtcblxuICB2YXIgUSA9IFIubXVsdGlwbHlUd28ocywgRywgZU5lZykubXVsdGlwbHkockludik7XG4gIGN1cnZlLnZhbGlkYXRlKFEpO1xuXG4gIHJldHVybiBRO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBwdWJrZXkgZXh0cmFjdGlvbiBwYXJhbWV0ZXIuXG4gKlxuICogV2hlbiBleHRyYWN0aW5nIGEgcHVia2V5IGZyb20gYSBzaWduYXR1cmUsIHdlIGhhdmUgdG9cbiAqIGRpc3Rpbmd1aXNoIGZvdXIgZGlmZmVyZW50IGNhc2VzLiBSYXRoZXIgdGhhbiBwdXR0aW5nIHRoaXNcbiAqIGJ1cmRlbiBvbiB0aGUgdmVyaWZpZXIsIEJpdGNvaW4gaW5jbHVkZXMgYSAyLWJpdCB2YWx1ZSB3aXRoIHRoZVxuICogc2lnbmF0dXJlLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gc2ltcGx5IHRyaWVzIGFsbCBmb3VyIGNhc2VzIGFuZCByZXR1cm5zIHRoZSB2YWx1ZVxuICogdGhhdCByZXN1bHRlZCBpbiBhIHN1Y2Nlc3NmdWwgcHVia2V5IHJlY292ZXJ5LlxuICovXG5mdW5jdGlvbiBjYWxjUHViS2V5UmVjb3ZlcnlQYXJhbShjdXJ2ZSwgZSwgc2lnbmF0dXJlLCBRKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgdmFyIFFwcmltZSA9IHJlY292ZXJQdWJLZXkoY3VydmUsIGUsIHNpZ25hdHVyZSwgaSk7XG5cbiAgICAvLyAxLjYuMiBWZXJpZnkgUVxuICAgIGlmIChRcHJpbWUuZXF1YWxzKFEpKSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIHZhbGlkIHJlY292ZXJ5IGZhY3RvcicpO1xufVxuXG5leHBvcnRzLmNhbGNQdWJLZXlSZWNvdmVyeVBhcmFtID0gY2FsY1B1YktleVJlY292ZXJ5UGFyYW07XG5leHBvcnRzLmRldGVybWluaXN0aWNHZW5lcmF0ZUsgPSBkZXRlcm1pbmlzdGljR2VuZXJhdGVLO1xuZXhwb3J0cy5yZWNvdmVyUHViS2V5ID0gcmVjb3ZlclB1YktleTtcbmV4cG9ydHMuc2lnbiA9IHNpZ247XG5leHBvcnRzLnZlcmlmeSA9IHZlcmlmeTtcbmV4cG9ydHMudmVyaWZ5UmF3ID0gdmVyaWZ5UmF3OyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9hc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTtcblxudmFyIF9hc3NlcnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0KTtcblxudmFyIF9iaWdpID0gcmVxdWlyZSgnYmlnaScpO1xuXG52YXIgX2JpZ2kyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYmlnaSk7XG5cbnZhciBfZW5mb3JjZV90eXBlcyA9IHJlcXVpcmUoJy4vZW5mb3JjZV90eXBlcycpO1xuXG52YXIgX2VuZm9yY2VfdHlwZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZW5mb3JjZV90eXBlcyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8vIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2JpdGNvaW5qcy9iaXRjb2luanMtbGliXG5mdW5jdGlvbiBFQ1NpZ25hdHVyZShyLCBzKSB7XG4gICgwLCBfZW5mb3JjZV90eXBlczIuZGVmYXVsdCkoX2JpZ2kyLmRlZmF1bHQsIHIpO1xuICAoMCwgX2VuZm9yY2VfdHlwZXMyLmRlZmF1bHQpKF9iaWdpMi5kZWZhdWx0LCBzKTtcblxuICB0aGlzLnIgPSByO1xuICB0aGlzLnMgPSBzO1xufVxuXG4vLyBJbXBvcnQgb3BlcmF0aW9uc1xuLyogZXNsaW50IG5vLWJpdHdpc2U6IFwib2ZmXCIgKi9cbkVDU2lnbmF0dXJlLnBhcnNlQ29tcGFjdCA9IGZ1bmN0aW9uIChidWZmZXIpIHtcbiAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChidWZmZXIubGVuZ3RoLCA2NSwgJ0ludmFsaWQgc2lnbmF0dXJlIGxlbmd0aCcpO1xuICB2YXIgaSA9IGJ1ZmZlci5yZWFkVUludDgoMCkgLSAyNztcblxuICAvLyBBdCBtb3N0IDMgYml0c1xuICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGksIGkgJiA3LCAnSW52YWxpZCBzaWduYXR1cmUgcGFyYW1ldGVyJyk7XG4gIHZhciBjb21wcmVzc2VkID0gISEoaSAmIDQpO1xuXG4gIC8vIFJlY292ZXJ5IHBhcmFtIG9ubHlcbiAgaSAmPSAzO1xuXG4gIHZhciByID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcihidWZmZXIuc2xpY2UoMSwgMzMpKTtcbiAgdmFyIHMgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1ZmZlci5zbGljZSgzMykpO1xuXG4gIHJldHVybiB7XG4gICAgY29tcHJlc3NlZDogY29tcHJlc3NlZCxcbiAgICBpOiBpLFxuICAgIHNpZ25hdHVyZTogbmV3IEVDU2lnbmF0dXJlKHIsIHMpXG4gIH07XG59O1xuXG5FQ1NpZ25hdHVyZS5mcm9tREVSID0gZnVuY3Rpb24gKGJ1ZmZlcikge1xuICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGJ1ZmZlci5yZWFkVUludDgoMCksIDB4MzAsICdOb3QgYSBERVIgc2VxdWVuY2UnKTtcbiAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChidWZmZXIucmVhZFVJbnQ4KDEpLCBidWZmZXIubGVuZ3RoIC0gMiwgJ0ludmFsaWQgc2VxdWVuY2UgbGVuZ3RoJyk7XG4gIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoYnVmZmVyLnJlYWRVSW50OCgyKSwgMHgwMiwgJ0V4cGVjdGVkIGEgREVSIGludGVnZXInKTtcblxuICB2YXIgckxlbiA9IGJ1ZmZlci5yZWFkVUludDgoMyk7XG4gICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShyTGVuID4gMCwgJ1IgbGVuZ3RoIGlzIHplcm8nKTtcblxuICB2YXIgb2Zmc2V0ID0gNCArIHJMZW47XG4gIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoYnVmZmVyLnJlYWRVSW50OChvZmZzZXQpLCAweDAyLCAnRXhwZWN0ZWQgYSBERVIgaW50ZWdlciAoMiknKTtcblxuICB2YXIgc0xlbiA9IGJ1ZmZlci5yZWFkVUludDgob2Zmc2V0ICsgMSk7XG4gICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShzTGVuID4gMCwgJ1MgbGVuZ3RoIGlzIHplcm8nKTtcblxuICB2YXIgckIgPSBidWZmZXIuc2xpY2UoNCwgb2Zmc2V0KTtcbiAgdmFyIHNCID0gYnVmZmVyLnNsaWNlKG9mZnNldCArIDIpO1xuICBvZmZzZXQgKz0gMiArIHNMZW47XG5cbiAgaWYgKHJMZW4gPiAxICYmIHJCLnJlYWRVSW50OCgwKSA9PT0gMHgwMCkge1xuICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShyQi5yZWFkVUludDgoMSkgJiAweDgwLCAnUiB2YWx1ZSBleGNlc3NpdmVseSBwYWRkZWQnKTtcbiAgfVxuXG4gIGlmIChzTGVuID4gMSAmJiBzQi5yZWFkVUludDgoMCkgPT09IDB4MDApIHtcbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoc0IucmVhZFVJbnQ4KDEpICYgMHg4MCwgJ1MgdmFsdWUgZXhjZXNzaXZlbHkgcGFkZGVkJyk7XG4gIH1cblxuICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKG9mZnNldCwgYnVmZmVyLmxlbmd0aCwgJ0ludmFsaWQgREVSIGVuY29kaW5nJyk7XG4gIHZhciByID0gX2JpZ2kyLmRlZmF1bHQuZnJvbURFUkludGVnZXIockIpO1xuICB2YXIgcyA9IF9iaWdpMi5kZWZhdWx0LmZyb21ERVJJbnRlZ2VyKHNCKTtcblxuICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoci5zaWdudW0oKSA+PSAwLCAnUiB2YWx1ZSBpcyBuZWdhdGl2ZScpO1xuICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkocy5zaWdudW0oKSA+PSAwLCAnUyB2YWx1ZSBpcyBuZWdhdGl2ZScpO1xuXG4gIHJldHVybiBuZXcgRUNTaWduYXR1cmUociwgcyk7XG59O1xuXG4vLyBGSVhNRTogMHgwMCwgMHgwNCwgMHg4MCBhcmUgU0lHSEFTSF8qIGJvdW5kYXJ5IGNvbnN0YW50cyxcbi8vIGltcG9ydGluZyBUcmFuc2FjdGlvbiBjYXVzZXMgYSBjaXJjdWxhciBkZXBlbmRlbmN5XG5FQ1NpZ25hdHVyZS5wYXJzZVNjcmlwdFNpZ25hdHVyZSA9IGZ1bmN0aW9uIChidWZmZXIpIHtcbiAgdmFyIGhhc2hUeXBlID0gYnVmZmVyLnJlYWRVSW50OChidWZmZXIubGVuZ3RoIC0gMSk7XG4gIHZhciBoYXNoVHlwZU1vZCA9IGhhc2hUeXBlICYgfjB4ODA7XG5cbiAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKGhhc2hUeXBlTW9kID4gMHgwMCAmJiBoYXNoVHlwZU1vZCA8IDB4MDQsICdJbnZhbGlkIGhhc2hUeXBlJyk7XG5cbiAgcmV0dXJuIHtcbiAgICBzaWduYXR1cmU6IEVDU2lnbmF0dXJlLmZyb21ERVIoYnVmZmVyLnNsaWNlKDAsIC0xKSksXG4gICAgaGFzaFR5cGU6IGhhc2hUeXBlXG4gIH07XG59O1xuXG4vLyBFeHBvcnQgb3BlcmF0aW9uc1xuRUNTaWduYXR1cmUucHJvdG90eXBlLnRvQ29tcGFjdCA9IGZ1bmN0aW9uIHRvQ29tcGFjdChpLCBjb21wcmVzc2VkKSB7XG4gIGlmIChjb21wcmVzc2VkKSB7XG4gICAgaSArPSA0O1xuICB9XG5cbiAgaSArPSAyNztcblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDY1KTtcbiAgYnVmZmVyLndyaXRlVUludDgoaSwgMCk7XG5cbiAgdGhpcy5yLnRvQnVmZmVyKDMyKS5jb3B5KGJ1ZmZlciwgMSk7XG4gIHRoaXMucy50b0J1ZmZlcigzMikuY29weShidWZmZXIsIDMzKTtcblxuICByZXR1cm4gYnVmZmVyO1xufTtcblxuRUNTaWduYXR1cmUucHJvdG90eXBlLnRvREVSID0gZnVuY3Rpb24gdG9ERVIoKSB7XG4gIHZhciByQmEgPSB0aGlzLnIudG9ERVJJbnRlZ2VyKCk7XG4gIHZhciBzQmEgPSB0aGlzLnMudG9ERVJJbnRlZ2VyKCk7XG5cbiAgdmFyIHNlcXVlbmNlID0gW107XG5cbiAgLy8gSU5URUdFUlxuICBzZXF1ZW5jZS5wdXNoKDB4MDIsIHJCYS5sZW5ndGgpO1xuICBzZXF1ZW5jZSA9IHNlcXVlbmNlLmNvbmNhdChyQmEpO1xuXG4gIC8vIElOVEVHRVJcbiAgc2VxdWVuY2UucHVzaCgweDAyLCBzQmEubGVuZ3RoKTtcbiAgc2VxdWVuY2UgPSBzZXF1ZW5jZS5jb25jYXQoc0JhKTtcblxuICAvLyBTRVFVRU5DRVxuICBzZXF1ZW5jZS51bnNoaWZ0KDB4MzAsIHNlcXVlbmNlLmxlbmd0aCk7XG5cbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNlcXVlbmNlKTtcbn07XG5cbkVDU2lnbmF0dXJlLnByb3RvdHlwZS50b1NjcmlwdFNpZ25hdHVyZSA9IGZ1bmN0aW9uIHRvU2NyaXB0U2lnbmF0dXJlKGhhc2hUeXBlKSB7XG4gIHZhciBoYXNoVHlwZUJ1ZmZlciA9IEJ1ZmZlci5hbGxvYygxKTtcbiAgaGFzaFR5cGVCdWZmZXIud3JpdGVVSW50OChoYXNoVHlwZSwgMCk7XG5cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW3RoaXMudG9ERVIoKSwgaGFzaFR5cGVCdWZmZXJdKTtcbn07XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEVDU2lnbmF0dXJlO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5kZWZhdWx0ID0gZW5mb3JjZTtcblxuZnVuY3Rpb24gZ2V0TmFtZShmbikge1xuICAvLyBXaHkgbm90IGZuLm5hbWU6IGh0dHBzOi8va2FuZ2F4LmdpdGh1Yi5pby9jb21wYXQtdGFibGUvZXM2LyNmdW5jdGlvbl9uYW1lX3Byb3BlcnR5XG4gIHZhciBtYXRjaCA9IGZuLnRvU3RyaW5nKCkubWF0Y2goL2Z1bmN0aW9uICguKj8pXFwoLyk7XG4gIHJldHVybiBtYXRjaCA/IG1hdGNoWzFdIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gZW5mb3JjZSh0eXBlLCB2YWx1ZSkge1xuICAvLyBDb3BpZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vYml0Y29pbmpzL2JpdGNvaW5qcy1saWJcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgJ0J1ZmZlcic6XG4gICAgICB7XG4gICAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlICdOdW1iZXInOlxuICAgICAge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIGlmIChnZXROYW1lKHZhbHVlLmNvbnN0cnVjdG9yKSA9PT0gZ2V0TmFtZSh0eXBlKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgJyArIChnZXROYW1lKHR5cGUpIHx8IHR5cGUpICsgJywgZ290ICcgKyB2YWx1ZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLnJpcGVtZDE2MCA9IGV4cG9ydHMuSG1hY1NIQTI1NiA9IGV4cG9ydHMuc2hhNTEyID0gZXhwb3J0cy5zaGEyNTYgPSBleHBvcnRzLnNoYTEgPSB1bmRlZmluZWQ7XG5cbnZhciBfY3JlYXRlSGFzaCA9IHJlcXVpcmUoNDEpO1xuXG52YXIgX2NyZWF0ZUhhc2gyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfY3JlYXRlSGFzaCk7XG5cbnZhciBfY3JlYXRlSG1hYyA9IHJlcXVpcmUoNDMpO1xuXG52YXIgX2NyZWF0ZUhtYWMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfY3JlYXRlSG1hYyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8qKiBAYXJnIHtzdHJpbmd8QnVmZmVyfSBkYXRhXG4gICAgQGFyZyB7c3RyaW5nfSBbZGlnZXN0ID0gbnVsbF0gLSAnaGV4JywgJ2JpbmFyeScgb3IgJ2Jhc2U2NCdcbiAgICBAcmV0dXJuIHtzdHJpbmd8QnVmZmVyfSAtIEJ1ZmZlciB3aGVuIGRpZ2VzdCBpcyBudWxsLCBvciBzdHJpbmdcbiovXG5mdW5jdGlvbiBzaGExKGRhdGEsIGVuY29kaW5nKSB7XG4gIHJldHVybiAoMCwgX2NyZWF0ZUhhc2gyLmRlZmF1bHQpKCdzaGExJykudXBkYXRlKGRhdGEpLmRpZ2VzdChlbmNvZGluZyk7XG59XG5cbi8qKiBAYXJnIHtzdHJpbmd8QnVmZmVyfSBkYXRhXG4gICAgQGFyZyB7c3RyaW5nfSBbZGlnZXN0ID0gbnVsbF0gLSAnaGV4JywgJ2JpbmFyeScgb3IgJ2Jhc2U2NCdcbiAgICBAcmV0dXJuIHtzdHJpbmd8QnVmZmVyfSAtIEJ1ZmZlciB3aGVuIGRpZ2VzdCBpcyBudWxsLCBvciBzdHJpbmdcbiovXG5mdW5jdGlvbiBzaGEyNTYoZGF0YSwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuICgwLCBfY3JlYXRlSGFzaDIuZGVmYXVsdCkoJ3NoYTI1NicpLnVwZGF0ZShkYXRhKS5kaWdlc3QoZW5jb2RpbmcpO1xufVxuXG4vKiogQGFyZyB7c3RyaW5nfEJ1ZmZlcn0gZGF0YVxuICAgIEBhcmcge3N0cmluZ30gW2RpZ2VzdCA9IG51bGxdIC0gJ2hleCcsICdiaW5hcnknIG9yICdiYXNlNjQnXG4gICAgQHJldHVybiB7c3RyaW5nfEJ1ZmZlcn0gLSBCdWZmZXIgd2hlbiBkaWdlc3QgaXMgbnVsbCwgb3Igc3RyaW5nXG4qL1xuZnVuY3Rpb24gc2hhNTEyKGRhdGEsIGVuY29kaW5nKSB7XG4gIHJldHVybiAoMCwgX2NyZWF0ZUhhc2gyLmRlZmF1bHQpKCdzaGE1MTInKS51cGRhdGUoZGF0YSkuZGlnZXN0KGVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gSG1hY1NIQTI1NihidWZmZXIsIHNlY3JldCkge1xuICByZXR1cm4gKDAsIF9jcmVhdGVIbWFjMi5kZWZhdWx0KSgnc2hhMjU2Jywgc2VjcmV0KS51cGRhdGUoYnVmZmVyKS5kaWdlc3QoKTtcbn1cblxuZnVuY3Rpb24gcmlwZW1kMTYwKGRhdGEpIHtcbiAgcmV0dXJuICgwLCBfY3JlYXRlSGFzaDIuZGVmYXVsdCkoJ3JtZDE2MCcpLnVwZGF0ZShkYXRhKS5kaWdlc3QoKTtcbn1cblxuLy8gZnVuY3Rpb24gaGFzaDE2MChidWZmZXIpIHtcbi8vICAgcmV0dXJuIHJpcGVtZDE2MChzaGEyNTYoYnVmZmVyKSlcbi8vIH1cbi8vXG4vLyBmdW5jdGlvbiBoYXNoMjU2KGJ1ZmZlcikge1xuLy8gICByZXR1cm4gc2hhMjU2KHNoYTI1NihidWZmZXIpKVxuLy8gfVxuXG4vL1xuLy8gZnVuY3Rpb24gSG1hY1NIQTUxMihidWZmZXIsIHNlY3JldCkge1xuLy8gICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTUxMicsIHNlY3JldCkudXBkYXRlKGJ1ZmZlcikuZGlnZXN0KClcbi8vIH1cblxuZXhwb3J0cy5zaGExID0gc2hhMTtcbmV4cG9ydHMuc2hhMjU2ID0gc2hhMjU2O1xuZXhwb3J0cy5zaGE1MTIgPSBzaGE1MTI7XG5leHBvcnRzLkhtYWNTSEEyNTYgPSBIbWFjU0hBMjU2O1xuZXhwb3J0cy5yaXBlbWQxNjAgPSByaXBlbWQxNjA7IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2VjdXJ2ZSA9IHJlcXVpcmUoJ2VjdXJ2ZScpO1xuXG52YXIgX2Fzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xuXG52YXIgX2Fzc2VydDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnQpO1xuXG52YXIgX2JpZ2kgPSByZXF1aXJlKCdiaWdpJyk7XG5cbnZhciBfYmlnaTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9iaWdpKTtcblxudmFyIF9oYXNoMiA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG52YXIgX2VjZHNhID0gcmVxdWlyZSgnLi9lY2RzYScpO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoJy4vUHVibGljS2V5Jyk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9IC8qIGdsb2JhbCBCeXRlQnVmZmVyICovXG5cblxudmFyIHNlY3AyNTZrMSA9ICgwLCBfZWN1cnZlLmdldEN1cnZlQnlOYW1lKSgnc2VjcDI1NmsxJyk7XG5cbnZhciBTaWduYXR1cmUgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFNpZ25hdHVyZShyMSwgczEsIGkxKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNpZ25hdHVyZSk7XG5cbiAgICB0aGlzLnIgPSByMTtcbiAgICB0aGlzLnMgPSBzMTtcbiAgICB0aGlzLmkgPSBpMTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKHRoaXMuciAhPSBudWxsLCB0cnVlLCAnTWlzc2luZyBwYXJhbWV0ZXInKTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKHRoaXMucyAhPSBudWxsLCB0cnVlLCAnTWlzc2luZyBwYXJhbWV0ZXInKTtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKHRoaXMuaSAhPSBudWxsLCB0cnVlLCAnTWlzc2luZyBwYXJhbWV0ZXInKTtcbiAgfVxuXG4gIFNpZ25hdHVyZS5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWYpIHtcbiAgICB2YXIgaSA9IHZvaWQgMDtcbiAgICB2YXIgciA9IHZvaWQgMDtcbiAgICB2YXIgcyA9IHZvaWQgMDtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGJ1Zi5sZW5ndGgsIDY1LCAnSW52YWxpZCBzaWduYXR1cmUgbGVuZ3RoJyk7XG4gICAgaSA9IGJ1Zi5yZWFkVUludDgoMCk7XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChpIC0gMjcsIGkgLSAyNyAmIDcsICdJbnZhbGlkIHNpZ25hdHVyZSBwYXJhbWV0ZXInKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIHIgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1Zi5zbGljZSgxLCAzMykpO1xuICAgIHMgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1Zi5zbGljZSgzMykpO1xuICAgIHJldHVybiBuZXcgU2lnbmF0dXJlKHIsIHMsIGkpO1xuICB9O1xuXG4gIFNpZ25hdHVyZS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiB0b0J1ZmZlcigpIHtcbiAgICB2YXIgYnVmID0gdm9pZCAwO1xuICAgIGJ1ZiA9IEJ1ZmZlci5hbGxvYyg2NSk7XG4gICAgYnVmLndyaXRlVUludDgodGhpcy5pLCAwKTtcbiAgICB0aGlzLnIudG9CdWZmZXIoMzIpLmNvcHkoYnVmLCAxKTtcbiAgICB0aGlzLnMudG9CdWZmZXIoMzIpLmNvcHkoYnVmLCAzMyk7XG4gICAgcmV0dXJuIGJ1ZjtcbiAgfTtcblxuICBTaWduYXR1cmUucHJvdG90eXBlLnJlY292ZXJQdWJsaWNLZXlGcm9tQnVmZmVyID0gZnVuY3Rpb24gcmVjb3ZlclB1YmxpY0tleUZyb21CdWZmZXIoYnVmZmVyKSB7XG4gICAgcmV0dXJuIHRoaXMucmVjb3ZlclB1YmxpY0tleSgoMCwgX2hhc2gyLnNoYTI1NikoYnVmZmVyKSk7XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEByZXR1cm4ge1B1YmxpY0tleX1cbiAgICAqL1xuXG5cbiAgU2lnbmF0dXJlLnByb3RvdHlwZS5yZWNvdmVyUHVibGljS2V5ID0gZnVuY3Rpb24gcmVjb3ZlclB1YmxpY0tleShzaGEyNTZfYnVmZmVyKSB7XG4gICAgdmFyIFEgPSB2b2lkIDA7XG4gICAgdmFyIGUgPSB2b2lkIDA7XG4gICAgdmFyIGkgPSB2b2lkIDA7XG4gICAgZSA9IF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoc2hhMjU2X2J1ZmZlcik7XG4gICAgaSA9IHRoaXMuaTtcbiAgICBpIC09IDI3O1xuICAgIGkgJj0gMzsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIFEgPSAoMCwgX2VjZHNhLnJlY292ZXJQdWJLZXkpKHNlY3AyNTZrMSwgZSwgdGhpcywgaSk7XG4gICAgcmV0dXJuIF9QdWJsaWNLZXkyLmRlZmF1bHQuZnJvbVBvaW50KFEpO1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBAcGFyYW0ge0J1ZmZlcn0gYnVmXG4gICAgICAgIEBwYXJhbSB7UHJpdmF0ZUtleX0gcHJpdmF0ZV9rZXlcbiAgICAgICAgQHJldHVybiB7U2lnbmF0dXJlfVxuICAgICovXG5cblxuICBTaWduYXR1cmUuc2lnbkJ1ZmZlciA9IGZ1bmN0aW9uIHNpZ25CdWZmZXIoYnVmLCBwcml2YXRlX2tleSkge1xuICAgIHZhciBfaGFzaCA9ICgwLCBfaGFzaDIuc2hhMjU2KShidWYpO1xuICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlclNoYTI1NihfaGFzaCwgcHJpdmF0ZV9rZXkpO1xuICB9O1xuXG4gIC8qKiBTaWduIGEgYnVmZmVyIG9mIGV4YWN0YWxseSAzMiBieXRlcyBpbiBzaXplIChzaGEyNTYodGV4dCkpXG4gICAgICAgIEBwYXJhbSB7QnVmZmVyfSBidWYgLSAzMiBieXRlcyBiaW5hcnlcbiAgICAgICAgQHBhcmFtIHtQcml2YXRlS2V5fSBwcml2YXRlX2tleVxuICAgICAgICBAcmV0dXJuIHtTaWduYXR1cmV9XG4gICAgKi9cblxuXG4gIFNpZ25hdHVyZS5zaWduQnVmZmVyU2hhMjU2ID0gZnVuY3Rpb24gc2lnbkJ1ZmZlclNoYTI1NihidWZfc2hhMjU2LCBwcml2YXRlX2tleSkge1xuICAgIGlmIChidWZfc2hhMjU2Lmxlbmd0aCAhPT0gMzIgfHwgIUJ1ZmZlci5pc0J1ZmZlcihidWZfc2hhMjU2KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdidWZfc2hhMjU2OiAzMiBieXRlIGJ1ZmZlciByZXF1cmVkJyk7XG4gICAgfVxuXG4gICAgdmFyIGRlciA9IHZvaWQgMDtcbiAgICB2YXIgZSA9IHZvaWQgMDtcbiAgICB2YXIgZWNzaWduYXR1cmUgPSB2b2lkIDA7XG4gICAgdmFyIGkgPSB2b2lkIDA7XG4gICAgdmFyIGxlblIgPSB2b2lkIDA7XG4gICAgdmFyIGxlblMgPSB2b2lkIDA7XG4gICAgdmFyIG5vbmNlID0gdm9pZCAwO1xuICAgIGkgPSBudWxsO1xuICAgIG5vbmNlID0gMDtcbiAgICBlID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcihidWZfc2hhMjU2KTtcblxuICAgIHZhciBsb29wID0gdHJ1ZTtcblxuICAgIHdoaWxlIChsb29wKSB7XG4gICAgICBlY3NpZ25hdHVyZSA9ICgwLCBfZWNkc2Euc2lnbikoc2VjcDI1NmsxLCBidWZfc2hhMjU2LCBwcml2YXRlX2tleS5kLCBub25jZSsrKTtcbiAgICAgIGRlciA9IGVjc2lnbmF0dXJlLnRvREVSKCk7XG4gICAgICBsZW5SID0gZGVyWzNdO1xuICAgICAgbGVuUyA9IGRlcls1ICsgbGVuUl07XG5cbiAgICAgIGlmIChsZW5SID09PSAzMiAmJiBsZW5TID09PSAzMikge1xuICAgICAgICBpID0gKDAsIF9lY2RzYS5jYWxjUHViS2V5UmVjb3ZlcnlQYXJhbSkoc2VjcDI1NmsxLCBlLCBlY3NpZ25hdHVyZSwgcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKS5RKTtcbiAgICAgICAgaSArPSA0OyAvLyBjb21wcmVzc2VkXG4gICAgICAgIGkgKz0gMjc7IC8vIGNvbXBhY3QgIC8vICAyNCBvciAyNyA6KCBmb3JjaW5nIG9kZC15IDJuZCBrZXkgY2FuZGlkYXRlKVxuICAgICAgICBsb29wID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAobm9uY2UgJSAxMCA9PT0gMCkge1xuICAgICAgICBjb25zb2xlLmxvZygnV0FSTjogJyArIG5vbmNlICsgJyBhdHRlbXB0cyB0byBmaW5kIGNhbm9uaWNhbCBzaWduYXR1cmUnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFNpZ25hdHVyZShlY3NpZ25hdHVyZS5yLCBlY3NpZ25hdHVyZS5zLCBpKTtcbiAgfTtcblxuICBTaWduYXR1cmUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24oc3RyaW5nLCBwcml2YXRlX2tleSkge1xuICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlcihCdWZmZXIuZnJvbShzdHJpbmcpLCBwcml2YXRlX2tleSk7XG4gIH07XG5cbiAgLyoqXG4gICAgICAgIEBwYXJhbSB7QnVmZmVyfSB1bi1oYXNoZWRcbiAgICAgICAgQHBhcmFtIHsuL1B1YmxpY0tleX1cbiAgICAgICAgQHJldHVybiB7Ym9vbGVhbn1cbiAgICAqL1xuXG5cbiAgU2lnbmF0dXJlLnByb3RvdHlwZS52ZXJpZnlCdWZmZXIgPSBmdW5jdGlvbiB2ZXJpZnlCdWZmZXIoYnVmLCBwdWJsaWNfa2V5KSB7XG4gICAgdmFyIF9oYXNoID0gKDAsIF9oYXNoMi5zaGEyNTYpKGJ1Zik7XG4gICAgcmV0dXJuIHRoaXMudmVyaWZ5SGFzaChfaGFzaCwgcHVibGljX2tleSk7XG4gIH07XG5cbiAgU2lnbmF0dXJlLnByb3RvdHlwZS52ZXJpZnlIYXNoID0gZnVuY3Rpb24gdmVyaWZ5SGFzaChoYXNoLCBwdWJsaWNfa2V5KSB7XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChoYXNoLmxlbmd0aCwgMzIsICdBIFNIQSAyNTYgc2hvdWxkIGJlIDMyIGJ5dGVzIGxvbmcsIGluc3RlYWQgZ290ICcgKyBoYXNoLmxlbmd0aCk7XG4gICAgcmV0dXJuICgwLCBfZWNkc2EudmVyaWZ5KShzZWNwMjU2azEsIGhhc2gsIHtcbiAgICAgIHI6IHRoaXMucixcbiAgICAgIHM6IHRoaXMuc1xuICAgIH0sIHB1YmxpY19rZXkuUSk7XG4gIH07XG5cbiAgLyogPEhFWD4gKi9cblxuICBTaWduYXR1cmUucHJvdG90eXBlLnRvQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uIHRvQnl0ZUJ1ZmZlcigpIHtcbiAgICB2YXIgYiA9IHZvaWQgMDtcbiAgICBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiKTtcbiAgICByZXR1cm4gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgfTtcblxuICBTaWduYXR1cmUuZnJvbUhleCA9IGZ1bmN0aW9uIGZyb21IZXgoaGV4KSB7XG4gICAgcmV0dXJuIFNpZ25hdHVyZS5mcm9tQnVmZmVyKEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpKTtcbiAgfTtcblxuICBTaWduYXR1cmUucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24gdG9IZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9CdWZmZXIoKS50b1N0cmluZygnaGV4Jyk7XG4gIH07XG5cbiAgU2lnbmF0dXJlLnNpZ25IZXggPSBmdW5jdGlvbiBzaWduSGV4KGhleCwgcHJpdmF0ZV9rZXkpIHtcbiAgICB2YXIgYnVmID0gdm9pZCAwO1xuICAgIGJ1ZiA9IEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpO1xuICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlcihidWYsIHByaXZhdGVfa2V5KTtcbiAgfTtcblxuICBTaWduYXR1cmUucHJvdG90eXBlLnZlcmlmeUhleCA9IGZ1bmN0aW9uIHZlcmlmeUhleChoZXgsIHB1YmxpY19rZXkpIHtcbiAgICB2YXIgYnVmID0gdm9pZCAwO1xuICAgIGJ1ZiA9IEJ1ZmZlci5mcm9tKGhleCwgJ2hleCcpO1xuICAgIHJldHVybiB0aGlzLnZlcmlmeUJ1ZmZlcihidWYsIHB1YmxpY19rZXkpO1xuICB9O1xuXG4gIHJldHVybiBTaWduYXR1cmU7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IFNpZ25hdHVyZTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHMuU2VyaWFsaXplclZhbGlkYXRpb24gPSBleHBvcnRzLnRlbXBsYXRlID0gZXhwb3J0cy5vcHMgPSBleHBvcnRzLnR5cGVzID0gZXhwb3J0cy5mcCA9IGV4cG9ydHMuU2VyaWFsaXplciA9IHVuZGVmaW5lZDtcblxudmFyIF9zZXJpYWxpemVyID0gcmVxdWlyZSgyNCk7XG5cbnZhciBfc2VyaWFsaXplcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zZXJpYWxpemVyKTtcblxudmFyIF9GYXN0UGFyc2VyID0gcmVxdWlyZSgyMCk7XG5cbnZhciBfRmFzdFBhcnNlcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9GYXN0UGFyc2VyKTtcblxudmFyIF90eXBlcyA9IHJlcXVpcmUoMjYpO1xuXG52YXIgX3R5cGVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3R5cGVzKTtcblxudmFyIF9vcGVyYXRpb25zID0gcmVxdWlyZSgyMyk7XG5cbnZhciBvcHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfb3BlcmF0aW9ucyk7XG5cbnZhciBfdGVtcGxhdGUgPSByZXF1aXJlKDI1KTtcblxudmFyIF90ZW1wbGF0ZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90ZW1wbGF0ZSk7XG5cbnZhciBfU2VyaWFsaXplclZhbGlkYXRpb24gPSByZXF1aXJlKDIxKTtcblxudmFyIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TZXJpYWxpemVyVmFsaWRhdGlvbik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKG9iaikgeyBpZiAob2JqICYmIG9iai5fX2VzTW9kdWxlKSB7IHJldHVybiBvYmo7IH0gZWxzZSB7IHZhciBuZXdPYmogPSB7fTsgaWYgKG9iaiAhPSBudWxsKSB7IGZvciAodmFyIGtleSBpbiBvYmopIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIG5ld09ialtrZXldID0gb2JqW2tleV07IH0gfSBuZXdPYmouZGVmYXVsdCA9IG9iajsgcmV0dXJuIG5ld09iajsgfSB9XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmV4cG9ydHMuU2VyaWFsaXplciA9IF9zZXJpYWxpemVyMi5kZWZhdWx0O1xuZXhwb3J0cy5mcCA9IF9GYXN0UGFyc2VyMi5kZWZhdWx0O1xuZXhwb3J0cy50eXBlcyA9IF90eXBlczIuZGVmYXVsdDtcbmV4cG9ydHMub3BzID0gb3BzO1xuZXhwb3J0cy50ZW1wbGF0ZSA9IF90ZW1wbGF0ZTIuZGVmYXVsdDtcbmV4cG9ydHMuU2VyaWFsaXplclZhbGlkYXRpb24gPSBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQ7IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoJy4uLy4uL2VjYy9zcmMvUHVibGljS2V5Jyk7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBGYXN0UGFyc2VyID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBGYXN0UGFyc2VyKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBGYXN0UGFyc2VyKTtcbiAgfVxuXG4gIEZhc3RQYXJzZXIuZml4ZWRfZGF0YSA9IGZ1bmN0aW9uIGZpeGVkX2RhdGEoYiwgbGVuLCBidWZmZXIpIHtcbiAgICBpZiAoIWIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGJ1ZmZlcikge1xuICAgICAgdmFyIGRhdGEgPSBidWZmZXIuc2xpY2UoMCwgbGVuKS50b1N0cmluZygnYmluYXJ5Jyk7XG4gICAgICBiLmFwcGVuZChkYXRhLCAnYmluYXJ5Jyk7XG4gICAgICB3aGlsZSAobGVuLS0gPiBkYXRhLmxlbmd0aCkge1xuICAgICAgICBiLndyaXRlVWludDgoMCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgbGVuKTtcbiAgICAgIGIuc2tpcChsZW4pO1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJfY29weS50b0JpbmFyeSgpLCAnYmluYXJ5Jyk7XG4gICAgfVxuICB9O1xuXG4gIEZhc3RQYXJzZXIucHVibGljX2tleSA9IGZ1bmN0aW9uIHB1YmxpY19rZXkoYiwgX3B1YmxpY19rZXkpIHtcbiAgICB2YXIgYnVmZmVyID0gdm9pZCAwO1xuICAgIGlmICghYikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoX3B1YmxpY19rZXkpIHtcbiAgICAgIGJ1ZmZlciA9IF9wdWJsaWNfa2V5LnRvQnVmZmVyKCk7XG4gICAgICBiLmFwcGVuZChidWZmZXIudG9TdHJpbmcoJ2JpbmFyeScpLCAnYmluYXJ5Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1ZmZlciA9IEZhc3RQYXJzZXIuZml4ZWRfZGF0YShiLCAzMyk7XG4gICAgICByZXR1cm4gX1B1YmxpY0tleTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1ZmZlcik7XG4gICAgfVxuICB9O1xuXG4gIEZhc3RQYXJzZXIucmlwZW1kMTYwID0gZnVuY3Rpb24gcmlwZW1kMTYwKGIsIF9yaXBlbWQpIHtcbiAgICBpZiAoIWIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKF9yaXBlbWQpIHtcbiAgICAgIEZhc3RQYXJzZXIuZml4ZWRfZGF0YShiLCAyMCwgX3JpcGVtZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBGYXN0UGFyc2VyLmZpeGVkX2RhdGEoYiwgMjApO1xuICAgIH1cbiAgfTtcblxuICBGYXN0UGFyc2VyLnNoYTI1NiA9IGZ1bmN0aW9uIHNoYTI1NihiLCBfc2hhKSB7XG4gICAgaWYgKCFiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChfc2hhKSB7XG4gICAgICBGYXN0UGFyc2VyLmZpeGVkX2RhdGEoYiwgMzIsIF9zaGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gRmFzdFBhcnNlci5maXhlZF9kYXRhKGIsIDMyKTtcbiAgICB9XG4gIH07XG5cbiAgRmFzdFBhcnNlci50aW1lX3BvaW50X3NlYyA9IGZ1bmN0aW9uIHRpbWVfcG9pbnRfc2VjKGIsIGVwb2NoKSB7XG4gICAgaWYgKGVwb2NoKSB7XG4gICAgICBlcG9jaCA9IE1hdGguY2VpbChlcG9jaCAvIDEwMDApO1xuICAgICAgYi53cml0ZUludDMyKGVwb2NoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXBvY2ggPSBiLnJlYWRJbnQzMigpOyAvLyBmYzo6dGltZV9wb2ludF9zZWNcbiAgICAgIHJldHVybiBuZXcgRGF0ZShlcG9jaCAqIDEwMDApO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gRmFzdFBhcnNlcjtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gRmFzdFBhcnNlcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG52YXIgX2J5dGVidWZmZXIgPSByZXF1aXJlKDM4KTtcblxudmFyIF9DaGFpblR5cGVzID0gcmVxdWlyZSgzKTtcblxudmFyIF9DaGFpblR5cGVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0NoYWluVHlwZXMpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgTUFYX1NBRkVfSU5UID0gOTAwNzE5OTI1NDc0MDk5MTtcbnZhciBNSU5fU0FGRV9JTlQgPSAtOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gICAgTW9zdCB2YWxpZGF0aW9ucyBhcmUgc2tpcHBlZCBhbmQgdGhlIHZhbHVlIHJldHVybmVkIHVuY2hhbmdlZCB3aGVuIGFuIGVtcHR5IHN0cmluZyxcbiAgICBudWxsLCBvciB1bmRlZmluZWQgaXMgZW5jb3VudGVyZWQgKGV4Y2VwdCBcInJlcXVpcmVkXCIpLlxuICAgIFZhbGlkYXRpb25zIHN1cHBvcnQgYSBzdHJpbmcgZm9ybWF0IGZvciBkZWFsaW5nIHdpdGggbGFyZ2UgbnVtYmVycy5cbiovXG52YXIgX215ID0ge1xuICBpc19lbXB0eTogZnVuY3Rpb24gaXNfZW1wdHkodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZDtcbiAgfSxcbiAgcmVxdWlyZWQ6IGZ1bmN0aW9uIHJlcXVpcmVkKHZhbHVlKSB7XG4gICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6ICcnO1xuXG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbHVlIHJlcXVpcmVkICcgKyBmaWVsZF9uYW1lICsgJyB8ICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICByZXF1aXJlX2xvbmc6IGZ1bmN0aW9uIHJlcXVpcmVfbG9uZyh2YWx1ZSkge1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnJztcblxuICAgIGlmICghX2J5dGVidWZmZXIuTG9uZy5pc0xvbmcodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvbmcgdmFsdWUgcmVxdWlyZWQgJyArIGZpZWxkX25hbWUgKyAnIHwgJyArIHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIHN0cmluZzogZnVuY3Rpb24gc3RyaW5nKHZhbHVlKSB7XG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc3RyaW5nIHJlcXVpcmVkOiAnICsgdmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgbnVtYmVyOiBmdW5jdGlvbiBudW1iZXIodmFsdWUpIHtcbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdudW1iZXIgcmVxdWlyZWQ6ICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICB3aG9sZV9udW1iZXI6IGZ1bmN0aW9uIHdob2xlX251bWJlcih2YWx1ZSkge1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAnJztcblxuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGlmICgvXFwuLy50ZXN0KHZhbHVlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd3aG9sZSBudW1iZXIgcmVxdWlyZWQgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICB1bnNpZ25lZDogZnVuY3Rpb24gdW5zaWduZWQodmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBpZiAoLy0vLnRlc3QodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc2lnbmVkIHJlcXVpcmVkICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgaXNfZGlnaXRzOiBmdW5jdGlvbiBpc19kaWdpdHModmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuICgvXlswLTldKyQvLnRlc3QodmFsdWUpXG4gICAgKTtcbiAgfSxcbiAgdG9fbnVtYmVyOiBmdW5jdGlvbiB0b19udW1iZXIodmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLm5vX292ZXJmbG93NTModmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHZhciBpbnRfdmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgIH0oKTtcbiAgICByZXR1cm4gaW50X3ZhbHVlO1xuICB9LFxuICB0b19sb25nOiBmdW5jdGlvbiB0b19sb25nKHZhbHVlKSB7XG4gICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6ICcnO1xuXG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKF9ieXRlYnVmZmVyLkxvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHRoaXMubm9fb3ZlcmZsb3c2NCh2YWx1ZSwgZmllbGRfbmFtZSk7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgdmFsdWUgPSAnJyArIHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBfYnl0ZWJ1ZmZlci5Mb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICB9LFxuICB0b191bG9uZzogZnVuY3Rpb24gdG9fdWxvbmcodmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBpZiAoX2J5dGVidWZmZXIuTG9uZy5pc0xvbmcodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhpcy5ub19vdmVyZmxvdzY0KHZhbHVlLCBmaWVsZF9uYW1lLCB0cnVlKTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICB2YWx1ZSA9ICcnICsgdmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9ieXRlYnVmZmVyLkxvbmcuZnJvbVN0cmluZyh2YWx1ZSwgdHJ1ZSk7XG4gIH0sXG4gIHRvX3N0cmluZzogZnVuY3Rpb24gdG9fc3RyaW5nKHZhbHVlKSB7XG4gICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6ICcnO1xuXG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgdGhpcy5ub19vdmVyZmxvdzUzKHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICAgIHJldHVybiAnJyArIHZhbHVlO1xuICAgIH1cblxuICAgIGlmIChfYnl0ZWJ1ZmZlci5Mb25nLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcigndW5zdXBwb3J0ZWQgdHlwZSAnICsgZmllbGRfbmFtZSArICc6ICgnICsgKHR5cGVvZiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YodmFsdWUpKSArICcpICcgKyB2YWx1ZSk7XG4gIH0sXG4gIHJlcXVpcmVfdGVzdDogZnVuY3Rpb24gcmVxdWlyZV90ZXN0KHJlZ2V4LCB2YWx1ZSkge1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAnJztcblxuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGlmICghcmVnZXgudGVzdCh2YWx1ZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5tYXRjaGVkICcgKyByZWdleCArICcgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICByZXF1aXJlX21hdGNoOiBmdW5jdGlvbiByZXF1aXJlX21hdGNoKHJlZ2V4LCB2YWx1ZSkge1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAnJztcblxuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHZhciBtYXRjaCA9IHZhbHVlLm1hdGNoKHJlZ2V4KTtcblxuICAgIGlmIChtYXRjaCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bm1hdGNoZWQgJyArIHJlZ2V4ICsgJyAnICsgZmllbGRfbmFtZSArICcgJyArIHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWF0Y2g7XG4gIH0sXG4gIHJlcXVpcmVfb2JqZWN0X2lkOiBmdW5jdGlvbiByZXF1aXJlX29iamVjdF9pZCh2YWx1ZSwgZmllbGRfbmFtZSkge1xuICAgIHJldHVybiB0aGlzLnJlcXVpcmVfbWF0Y2goL14oWzAtOV0rKVxcLihbMC05XSspXFwuKFswLTldKykkLywgdmFsdWUsIGZpZWxkX25hbWUpO1xuICB9LFxuXG5cbiAgLy8gRG9lcyBub3Qgc3VwcG9ydCBvdmVyIDUzIGJpdHNcbiAgcmVxdWlyZV9yYW5nZTogZnVuY3Rpb24gcmVxdWlyZV9yYW5nZShtaW4sIG1heCwgdmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogJyc7XG5cbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgbnVtID0gdGhpcy50b19udW1iZXIodmFsdWUpO1xuXG4gICAgaWYgKG51bSA8IG1pbiB8fCBudW0gPiBtYXgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb3V0IG9mIHJhbmdlICcgKyB2YWx1ZSArICcgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9LFxuICByZXF1aXJlX29iamVjdF90eXBlOiBmdW5jdGlvbiByZXF1aXJlX29iamVjdF90eXBlKCkge1xuICAgIHZhciByZXNlcnZlZF9zcGFjZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IDE7XG4gICAgdmFyIHR5cGUgPSBhcmd1bWVudHNbMV07XG4gICAgdmFyIHZhbHVlID0gYXJndW1lbnRzWzJdO1xuICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiAnJztcblxuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHZhciBvYmplY3RfdHlwZSA9IF9DaGFpblR5cGVzMi5kZWZhdWx0Lm9iamVjdF90eXBlW3R5cGVdO1xuXG4gICAgaWYgKCFvYmplY3RfdHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG9iamVjdCB0eXBlICcgKyB0eXBlICsgJyAnICsgZmllbGRfbmFtZSArICcgJyArIHZhbHVlKTtcbiAgICB9XG5cbiAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKHJlc2VydmVkX3NwYWNlcyArICcuJyArIG9iamVjdF90eXBlICsgJy5bMC05XSskJyk7XG5cbiAgICBpZiAoIXJlLnRlc3QodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGluZyAnICsgdHlwZSArICcgaW4gZm9ybWF0ICcgKyAocmVzZXJ2ZWRfc3BhY2VzICsgJy4nICsgb2JqZWN0X3R5cGUgKyAnLlswLTldKyAnKSArICgnaW5zdGVhZCBvZiAnICsgdmFsdWUgKyAnICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIGdldF9pbnN0YW5jZTogZnVuY3Rpb24gZ2V0X2luc3RhbmNlKHJlc2VydmVfc3BhY2VzLCB0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSkge1xuICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHRoaXMucmVxdWlyZV9vYmplY3RfdHlwZShyZXNlcnZlX3NwYWNlcywgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdCgnLicpWzJdKTtcbiAgfSxcbiAgcmVxdWlyZV9yZWxhdGl2ZV90eXBlOiBmdW5jdGlvbiByZXF1aXJlX3JlbGF0aXZlX3R5cGUodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMCwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgZ2V0X3JlbGF0aXZlX2luc3RhbmNlOiBmdW5jdGlvbiBnZXRfcmVsYXRpdmVfaW5zdGFuY2UodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMCwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdCgnLicpWzJdKTtcbiAgfSxcbiAgcmVxdWlyZV9wcm90b2NvbF90eXBlOiBmdW5jdGlvbiByZXF1aXJlX3Byb3RvY29sX3R5cGUodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMSwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgZ2V0X3Byb3RvY29sX2luc3RhbmNlOiBmdW5jdGlvbiBnZXRfcHJvdG9jb2xfaW5zdGFuY2UodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMSwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdCgnLicpWzJdKTtcbiAgfSxcbiAgZ2V0X3Byb3RvY29sX3R5cGU6IGZ1bmN0aW9uIGdldF9wcm90b2NvbF90eXBlKHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhpcy5yZXF1aXJlX29iamVjdF9pZCh2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgdmFyIHZhbHVlcyA9IHZhbHVlLnNwbGl0KCcuJyk7XG4gICAgcmV0dXJuIHRoaXMudG9fbnVtYmVyKHZhbHVlc1sxXSk7XG4gIH0sXG4gIGdldF9wcm90b2NvbF90eXBlX25hbWU6IGZ1bmN0aW9uIGdldF9wcm90b2NvbF90eXBlX25hbWUodmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgdHlwZV9pZCA9IHRoaXMuZ2V0X3Byb3RvY29sX3R5cGUodmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhfQ2hhaW5UeXBlczIuZGVmYXVsdC5vYmplY3RfdHlwZSlbdHlwZV9pZF07XG4gIH0sXG4gIHJlcXVpcmVfaW1wbGVtZW50YXRpb25fdHlwZTogZnVuY3Rpb24gcmVxdWlyZV9pbXBsZW1lbnRhdGlvbl90eXBlKHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgdGhpcy5yZXF1aXJlX29iamVjdF90eXBlKDIsIHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIGdldF9pbXBsZW1lbnRhdGlvbl9pbnN0YW5jZTogZnVuY3Rpb24gZ2V0X2ltcGxlbWVudGF0aW9uX2luc3RhbmNlKHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhpcy5yZXF1aXJlX29iamVjdF90eXBlKDIsIHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICByZXR1cm4gdGhpcy50b19udW1iZXIodmFsdWUuc3BsaXQoJy4nKVsyXSk7XG4gIH0sXG5cblxuICAvLyBzaWduZWQgLyB1bnNpZ25lZCBkZWNpbWFsXG4gIG5vX292ZXJmbG93NTM6IGZ1bmN0aW9uIG5vX292ZXJmbG93NTModmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgaWYgKHZhbHVlID4gTUFYX1NBRkVfSU5UIHx8IHZhbHVlIDwgTUlOX1NBRkVfSU5UKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignb3ZlcmZsb3cgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgdmFyIGludCA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG5cbiAgICAgIGlmIChpbnQgPiBNQVhfU0FGRV9JTlQgfHwgaW50IDwgTUlOX1NBRkVfSU5UKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignb3ZlcmZsb3cgJyArIGZpZWxkX25hbWUgKyAnICcgKyBpbnQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKF9ieXRlYnVmZmVyLkxvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgLy8gdHlwZW9mIHZhbHVlLnRvSW50KCkgaXMgJ251bWJlcidcbiAgICAgIHRoaXMubm9fb3ZlcmZsb3c1Myh2YWx1ZS50b0ludCgpLCBmaWVsZF9uYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3VwcG9ydGVkIHR5cGUgJyArIGZpZWxkX25hbWUgKyAnOiAoJyArICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHZhbHVlKSkgKyAnKSAnICsgdmFsdWUpO1xuICB9LFxuXG5cbiAgLy8gc2lnbmVkIC8gdW5zaWduZWQgd2hvbGUgbnVtYmVycyBvbmx5XG4gIG5vX292ZXJmbG93NjQ6IGZ1bmN0aW9uIG5vX292ZXJmbG93NjQodmFsdWUpIHtcbiAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG4gICAgdmFyIHVuc2lnbmVkID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBmYWxzZTtcblxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL0xvbmcuanMvaXNzdWVzLzIwXG4gICAgaWYgKF9ieXRlYnVmZmVyLkxvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEJpZ0ludGVnZXIjaXNCaWdJbnRlZ2VyIGh0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG9jb2luanMvYmlnaS9pc3N1ZXMvMjBcbiAgICBpZiAodmFsdWUudCAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5ub19vdmVyZmxvdzY0KHZhbHVlLnRvU3RyaW5nKCksIGZpZWxkX25hbWUsIHVuc2lnbmVkKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyByZW1vdmUgbGVhZGluZyB6ZXJvcywgd2lsbCBjYXVzZSBhIGZhbHNlIHBvc2l0aXZlXG4gICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoL14wKy8sICcnKTtcblxuICAgICAgLy8gcmVtb3ZlIHRyYWlsaW5nIHplcm9zXG4gICAgICB3aGlsZSAoLzAkLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZygwLCB2YWx1ZS5sZW5ndGggLSAxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKC9cXC4kLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgZG90XG4gICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKDAsIHZhbHVlLmxlbmd0aCAtIDEpO1xuICAgICAgfVxuXG4gICAgICBpZiAodmFsdWUgPT09ICcnKSB7XG4gICAgICAgIHZhbHVlID0gJzAnO1xuICAgICAgfVxuXG4gICAgICB2YXIgbG9uZ19zdHJpbmcgPSBfYnl0ZWJ1ZmZlci5Mb25nLmZyb21TdHJpbmcodmFsdWUsIHVuc2lnbmVkKS50b1N0cmluZygpO1xuXG4gICAgICBpZiAobG9uZ19zdHJpbmcgIT09IHZhbHVlLnRyaW0oKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ292ZXJmbG93ICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGlmICh2YWx1ZSA+IE1BWF9TQUZFX0lOVCB8fCB2YWx1ZSA8IE1JTl9TQUZFX0lOVCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ292ZXJmbG93ICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bnN1cHBvcnRlZCB0eXBlICcgKyBmaWVsZF9uYW1lICsgJzogKCcgKyAodHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZih2YWx1ZSkpICsgJykgJyArIHZhbHVlKTtcbiAgfVxufTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gX215O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG4vKiogRXhjZXB0aW9uIG5lc3RpbmcuICAqL1xudmFyIEVycm9yV2l0aENhdXNlID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBFcnJvcldpdGhDYXVzZShtZXNzYWdlLCBjYXVzZSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFcnJvcldpdGhDYXVzZSk7XG5cbiAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuXG4gICAgaWYgKHR5cGVvZiBjYXVzZSAhPT0gJ3VuZGVmaW5lZCcgJiYgY2F1c2UgIT09IG51bGwgPyBjYXVzZS5tZXNzYWdlIDogdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLm1lc3NhZ2UgPSAnY2F1c2VcXHQnICsgY2F1c2UubWVzc2FnZSArICdcXHQnICsgdGhpcy5tZXNzYWdlO1xuICAgIH1cblxuICAgIHZhciBzdGFjayA9ICcnOyAvLyAobmV3IEVycm9yKS5zdGFja1xuXG4gICAgaWYgKHR5cGVvZiBjYXVzZSAhPT0gJ3VuZGVmaW5lZCcgJiYgY2F1c2UgIT09IG51bGwgPyBjYXVzZS5zdGFjayA6IHVuZGVmaW5lZCkge1xuICAgICAgc3RhY2sgPSAnY2F1c2VkIGJ5XFxuXFx0JyArIGNhdXNlLnN0YWNrICsgJ1xcdCcgKyBzdGFjaztcbiAgICB9XG5cbiAgICB0aGlzLnN0YWNrID0gdGhpcy5tZXNzYWdlICsgJ1xcbicgKyBzdGFjaztcbiAgfVxuXG4gIEVycm9yV2l0aENhdXNlLnRocm93ID0gZnVuY3Rpb24gX3Rocm93KG1lc3NhZ2UsIGNhdXNlKSB7XG4gICAgdmFyIG1zZyA9IG1lc3NhZ2U7XG5cbiAgICBpZiAodHlwZW9mIGNhdXNlICE9PSAndW5kZWZpbmVkJyAmJiBjYXVzZSAhPT0gbnVsbCA/IGNhdXNlLm1lc3NhZ2UgOiB1bmRlZmluZWQpIHtcbiAgICAgIG1zZyArPSAnXFx0IGNhdXNlOiAnICsgY2F1c2UubWVzc2FnZSArICcgJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNhdXNlICE9PSAndW5kZWZpbmVkJyAmJiBjYXVzZSAhPT0gbnVsbCA/IGNhdXNlLnN0YWNrIDogdW5kZWZpbmVkKSB7XG4gICAgICBtc2cgKz0gJ1xcbiBzdGFjazogJyArIGNhdXNlLnN0YWNrICsgJyAnO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICB9O1xuXG4gIHJldHVybiBFcnJvcldpdGhDYXVzZTtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gRXJyb3JXaXRoQ2F1c2U7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLnN0ZWFsdGhfbWVtb19kYXRhID0gZXhwb3J0cy5nbG9iYWxfYmV0dGluZ19zdGF0aXN0aWNzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9wb3NpdGlvbiA9IGV4cG9ydHMuYmV0ID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldCA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXAgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X3J1bGVzID0gZXhwb3J0cy5ldmVudCA9IGV4cG9ydHMuZXZlbnRfZ3JvdXAgPSBleHBvcnRzLnNwb3J0ID0gZXhwb3J0cy5zaWduZWRfdHJhbnNhY3Rpb24gPSBleHBvcnRzLnRyYW5zYWN0aW9uID0gZXhwb3J0cy5iZXRfYWRqdXN0ZWQgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X3VwZGF0ZSA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlID0gZXhwb3J0cy50b3VybmFtZW50X2xlYXZlID0gZXhwb3J0cy50b3VybmFtZW50X3BheW91dCA9IGV4cG9ydHMucGF5b3V0X3R5cGUgPSBleHBvcnRzLmJldF9jYW5jZWxlZCA9IGV4cG9ydHMuYmV0X2NhbmNlbCA9IGV4cG9ydHMuYmV0X21hdGNoZWQgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX2NhbmNlbF91bm1hdGNoZWRfYmV0cyA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWQgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmUgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X3Jlc29sdXRpb25fdHlwZSA9IGV4cG9ydHMuYmV0X3BsYWNlID0gZXhwb3J0cy5iZXRfdHlwZSA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfY3JlYXRlID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGUgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZSA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfcnVsZXNfY3JlYXRlID0gZXhwb3J0cy5ldmVudF91cGRhdGUgPSBleHBvcnRzLmV2ZW50X2NyZWF0ZSA9IGV4cG9ydHMuZXZlbnRfZ3JvdXBfdXBkYXRlID0gZXhwb3J0cy5ldmVudF9ncm91cF9jcmVhdGUgPSBleHBvcnRzLnNwb3J0X3VwZGF0ZSA9IGV4cG9ydHMuc3BvcnRfY3JlYXRlID0gZXhwb3J0cy5hc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb24gPSBleHBvcnRzLmFzc2V0X3VwZGF0ZV9kaXZpZGVuZCA9IGV4cG9ydHMuZGl2aWRlbmRfYXNzZXRfb3B0aW9ucyA9IGV4cG9ydHMuZ2FtZV9tb3ZlID0gZXhwb3J0cy5yb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X3JldmVhbCA9IGV4cG9ydHMucm9ja19wYXBlcl9zY2lzc29yc190aHJvd19jb21taXQgPSBleHBvcnRzLnJvY2tfcGFwZXJfc2Npc3NvcnNfZ2VzdHVyZSA9IGV4cG9ydHMudG91cm5hbWVudF9qb2luID0gZXhwb3J0cy50b3VybmFtZW50X2NyZWF0ZSA9IGV4cG9ydHMudG91cm5hbWVudF9vcHRpb25zID0gZXhwb3J0cy5yb2NrX3BhcGVyX3NjaXNzb3JzX2dhbWVfb3B0aW9ucyA9IGV4cG9ydHMuZmJhX2Rpc3RyaWJ1dGUgPSBleHBvcnRzLmFzc2V0X2NsYWltX2ZlZXMgPSBleHBvcnRzLmFzc2V0X3NldHRsZV9jYW5jZWwgPSBleHBvcnRzLnRyYW5zZmVyX2Zyb21fYmxpbmQgPSBleHBvcnRzLmJsaW5kX3RyYW5zZmVyID0gZXhwb3J0cy5ibGluZF9pbnB1dCA9IGV4cG9ydHMudHJhbnNmZXJfdG9fYmxpbmQgPSBleHBvcnRzLmJsaW5kX291dHB1dCA9IGV4cG9ydHMuc3RlYWx0aF9jb25maXJtYXRpb24gPSBleHBvcnRzLm92ZXJyaWRlX3RyYW5zZmVyID0gZXhwb3J0cy5iYWxhbmNlX2NsYWltID0gZXhwb3J0cy5hc3NlcnQgPSBleHBvcnRzLmJsb2NrX2lkX3ByZWRpY2F0ZSA9IGV4cG9ydHMuYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUgPSBleHBvcnRzLmFjY291bnRfbmFtZV9lcV9saXRfcHJlZGljYXRlID0gZXhwb3J0cy5jdXN0b20gPSBleHBvcnRzLndvcmtlcl9jcmVhdGUgPSBleHBvcnRzLmJ1cm5fd29ya2VyX2luaXRpYWxpemVyID0gZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd29ya2VyX2luaXRpYWxpemVyID0gZXhwb3J0cy5yZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyID0gZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXcgPSBleHBvcnRzLnZlc3RpbmdfYmFsYW5jZV9jcmVhdGUgPSBleHBvcnRzLmNkZF92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplciA9IGV4cG9ydHMubGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVycyA9IGV4cG9ydHMuY2hhaW5fcGFyYW1ldGVycyA9IGV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGUgPSBleHBvcnRzLmNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlID0gZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbSA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGUgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlID0gZXhwb3J0cy5wcm9wb3NhbF9kZWxldGUgPSBleHBvcnRzLnByb3Bvc2FsX3VwZGF0ZSA9IGV4cG9ydHMucHJvcG9zYWxfY3JlYXRlID0gZXhwb3J0cy5vcF93cmFwcGVyID0gZXhwb3J0cy53aXRuZXNzX3VwZGF0ZSA9IGV4cG9ydHMud2l0bmVzc19jcmVhdGUgPSBleHBvcnRzLmFzc2V0X3B1Ymxpc2hfZmVlZCA9IGV4cG9ydHMucHJpY2VfZmVlZCA9IGV4cG9ydHMuYXNzZXRfZ2xvYmFsX3NldHRsZSA9IGV4cG9ydHMuYXNzZXRfc2V0dGxlID0gZXhwb3J0cy5hc3NldF9mdW5kX2ZlZV9wb29sID0gZXhwb3J0cy5hc3NldF9yZXNlcnZlID0gZXhwb3J0cy5hc3NldF9pc3N1ZSA9IHVuZGVmaW5lZDtcbmV4cG9ydHMuYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfYml0YXNzZXQgPSBleHBvcnRzLmFzc2V0X3VwZGF0ZSA9IGV4cG9ydHMuYXNzZXRfY3JlYXRlID0gZXhwb3J0cy5iaXRhc3NldF9vcHRpb25zID0gZXhwb3J0cy5hc3NldF9vcHRpb25zID0gZXhwb3J0cy5wcmljZSA9IGV4cG9ydHMuYWNjb3VudF90cmFuc2ZlciA9IGV4cG9ydHMuYWNjb3VudF91cGdyYWRlID0gZXhwb3J0cy5hY2NvdW50X3doaXRlbGlzdCA9IGV4cG9ydHMuYWNjb3VudF91cGRhdGUgPSBleHBvcnRzLmFjY291bnRfY3JlYXRlID0gZXhwb3J0cy5hY2NvdW50X29wdGlvbnMgPSBleHBvcnRzLmF1dGhvcml0eSA9IGV4cG9ydHMuZmlsbF9vcmRlciA9IGV4cG9ydHMuY2FsbF9vcmRlcl91cGRhdGUgPSBleHBvcnRzLmxpbWl0X29yZGVyX2NhbmNlbCA9IGV4cG9ydHMubGltaXRfb3JkZXJfY3JlYXRlID0gZXhwb3J0cy50cmFuc2ZlciA9IGV4cG9ydHMubWVtb19kYXRhID0gZXhwb3J0cy5zaWduZWRfYmxvY2tfaGVhZGVyID0gZXhwb3J0cy5ibG9ja19oZWFkZXIgPSBleHBvcnRzLnNpZ25lZF9ibG9jayA9IGV4cG9ydHMucHJvY2Vzc2VkX3RyYW5zYWN0aW9uID0gZXhwb3J0cy5hc3NldCA9IGV4cG9ydHMudm9pZF9yZXN1bHQgPSBleHBvcnRzLmZlZV9zY2hlZHVsZSA9IGV4cG9ydHMuYmV0X2FkanVzdGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudG91cm5hbWVudF9sZWF2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLnRvdXJuYW1lbnRfcGF5b3V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuZ2FtZV9tb3ZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudG91cm5hbWVudF9qb2luX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudG91cm5hbWVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXRfY2FuY2VsZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXRfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYmV0X21hdGNoZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXRfcGxhY2Vfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5ldmVudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5ldmVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5ldmVudF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5ldmVudF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5zcG9ydF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5zcG9ydF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb25fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfZGl2aWRlbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5mYmFfZGlzdHJpYnV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X2NsYWltX2ZlZXNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudHJhbnNmZXJfZnJvbV9ibGluZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJsaW5kX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5vdmVycmlkZV90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJhbGFuY2VfY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NlcnRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jdXN0b21fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53b3JrZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudmVzdGluZ19iYWxhbmNlX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5wcm9wb3NhbF9kZWxldGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5wcm9wb3NhbF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5wcm9wb3NhbF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndpdG5lc3NfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfcHVibGlzaF9mZWVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfZ2xvYmFsX3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9yZXNlcnZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfYml0YXNzZXRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hY2NvdW50X3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYWNjb3VudF91cGdyYWRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hY2NvdW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFjY291bnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuZmlsbF9vcmRlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmNhbGxfb3JkZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMubGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMubGltaXRfb3JkZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5vcGVyYXRpb24gPSB1bmRlZmluZWQ7XG5cbnZhciBfdHlwZXMgPSByZXF1aXJlKDI2KTtcblxudmFyIF90eXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90eXBlcyk7XG5cbnZhciBfc2VyaWFsaXplciA9IHJlcXVpcmUoMjQpO1xuXG52YXIgX3NlcmlhbGl6ZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc2VyaWFsaXplcik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciB1aW50OCA9IF90eXBlczIuZGVmYXVsdC51aW50OCxcbiAgICB1aW50MTYgPSBfdHlwZXMyLmRlZmF1bHQudWludDE2LFxuICAgIHVpbnQzMiA9IF90eXBlczIuZGVmYXVsdC51aW50MzIsXG4gICAgaW50NjQgPSBfdHlwZXMyLmRlZmF1bHQuaW50NjQsXG4gICAgdWludDY0ID0gX3R5cGVzMi5kZWZhdWx0LnVpbnQ2NCxcbiAgICBzdHJpbmcgPSBfdHlwZXMyLmRlZmF1bHQuc3RyaW5nLFxuICAgIGJ5dGVzID0gX3R5cGVzMi5kZWZhdWx0LmJ5dGVzLFxuICAgIGJvb2wgPSBfdHlwZXMyLmRlZmF1bHQuYm9vbCxcbiAgICBhcnJheSA9IF90eXBlczIuZGVmYXVsdC5hcnJheSxcbiAgICBwcm90b2NvbF9pZF90eXBlID0gX3R5cGVzMi5kZWZhdWx0LnByb3RvY29sX2lkX3R5cGUsXG4gICAgb2JqZWN0X2lkX3R5cGUgPSBfdHlwZXMyLmRlZmF1bHQub2JqZWN0X2lkX3R5cGUsXG4gICAgdm90ZV9pZCA9IF90eXBlczIuZGVmYXVsdC52b3RlX2lkLFxuICAgIGltcGxlbWVudGF0aW9uX2lkX3R5cGUgPSBfdHlwZXMyLmRlZmF1bHQuaW1wbGVtZW50YXRpb25faWRfdHlwZSxcbiAgICBzdGF0aWNfdmFyaWFudCA9IF90eXBlczIuZGVmYXVsdC5zdGF0aWNfdmFyaWFudCxcbiAgICBtYXAgPSBfdHlwZXMyLmRlZmF1bHQubWFwLFxuICAgIHNldCA9IF90eXBlczIuZGVmYXVsdC5zZXQsXG4gICAgcHVibGljX2tleSA9IF90eXBlczIuZGVmYXVsdC5wdWJsaWNfa2V5LFxuICAgIGFkZHJlc3MgPSBfdHlwZXMyLmRlZmF1bHQuYWRkcmVzcyxcbiAgICB0aW1lX3BvaW50X3NlYyA9IF90eXBlczIuZGVmYXVsdC50aW1lX3BvaW50X3NlYyxcbiAgICBvcHRpb25hbCA9IF90eXBlczIuZGVmYXVsdC5vcHRpb25hbCxcbiAgICB2YXJpYW50X29iamVjdCA9IF90eXBlczIuZGVmYXVsdC52YXJpYW50X29iamVjdCxcbiAgICBlbnVtZXJhdGlvbiA9IF90eXBlczIuZGVmYXVsdC5lbnVtZXJhdGlvbixcbiAgICBzaGEyNTYgPSBfdHlwZXMyLmRlZmF1bHQuc2hhMjU2O1xuXG5cbnZhciBmdXR1cmVfZXh0ZW5zaW9ucyA9IF90eXBlczIuZGVmYXVsdC52b2lkO1xuXG4vKlxuV2hlbiB1cGRhdGluZyBnZW5lcmF0ZWQgY29kZVxuUmVwbGFjZTogIG9wZXJhdGlvbiA9IHN0YXRpY192YXJpYW50IFtcbndpdGg6ICAgICBvcGVyYXRpb24uc3Rfb3BlcmF0aW9ucyA9IFtcblxuRGVsZXRlOlxucHVibGljX2tleSA9IG5ldyBTZXJpYWxpemVyKFxuICAgIFwicHVibGljX2tleVwiXG4gICAga2V5X2RhdGE6IGJ5dGVzIDMzXG4pO1xuKi9cblxuZnVuY3Rpb24gU2VyaWFsaXplcihvcGVyYXRpb25fbmFtZSwgc2VyaWxpemF0aW9uX3R5cGVzX29iamVjdCkge1xuICByZXR1cm4gbmV3IF9zZXJpYWxpemVyMi5kZWZhdWx0KG9wZXJhdGlvbl9uYW1lLCBzZXJpbGl6YXRpb25fdHlwZXNfb2JqZWN0KTtcbn1cbi8vIFBsYWNlLWhvbGRlciwgdGhlaXIgYXJlIGRlcGVuZGVuY2llcyBvbiBcIm9wZXJhdGlvblwiIC4uIFRoZSBmaW5hbCBsaXN0IG9mXG4vLyBvcGVyYXRpb25zIGlzIG5vdCBhdmlhbGJsZSB1bnRpbCB0aGUgdmVyeSBlbmQgb2YgdGhlIGdlbmVyYXRlZCBjb2RlLlxuLy8gU2VlOiBvcGVyYXRpb24uc3Rfb3BlcmF0aW9ucyA9IC4uLlxuLy8gbW9kdWxlLmV4cG9ydHNbXCJvcGVyYXRpb25cIl0gPSBvcGVyYXRpb247XG5cbnZhciBvcGVyYXRpb24gPSBzdGF0aWNfdmFyaWFudCgpO1xuXG4vLyBDdXN0b20tdHlwZXMgZm9sbG93IEdlbmVyYXRlZCBjb2RlOlxuXG4vLyAjIyAgR2VuZXJhdGVkIGNvZGUgZm9sbG93c1xuLy8gIyBwcm9ncmFtcy9qc19vcGVyYXRpb25fc2VyaWFsaXplciA+IG5wbSBpIC1nIGRlY2FmZmVpbmF0ZVxuLy8gIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxudmFyIHRyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd0cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0LFxuICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMlxufSk7XG5cbnZhciBsaW1pdF9vcmRlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2xpbWl0X29yZGVyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGxpbWl0X29yZGVyX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignbGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgY2FsbF9vcmRlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2NhbGxfb3JkZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgZmlsbF9vcmRlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignZmlsbF9vcmRlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnKTtcblxudmFyIGFjY291bnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdhY2NvdW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGJhc2ljX2ZlZTogdWludDY0LFxuICBwcmVtaXVtX2ZlZTogdWludDY0LFxuICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMlxufSk7XG5cbnZhciBhY2NvdW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IGludDY0LFxuICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMlxufSk7XG5cbnZhciBhY2NvdW50X3doaXRlbGlzdF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IGludDY0XG59KTtcblxudmFyIGFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF91cGdyYWRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgbWVtYmVyc2hpcF9hbm51YWxfZmVlOiB1aW50NjQsXG4gIG1lbWJlcnNoaXBfbGlmZXRpbWVfZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYWNjb3VudF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGFzc2V0X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgc3ltYm9sMzogdWludDY0LFxuICBzeW1ib2w0OiB1aW50NjQsXG4gIGxvbmdfc3ltYm9sOiB1aW50NjQsXG4gIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIGFzc2V0X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjQsXG4gIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIGFzc2V0X3VwZGF0ZV9iaXRhc3NldF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBhc3NldF9pc3N1ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgYXNzZXRfcmVzZXJ2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfcmVzZXJ2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGFzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBhc3NldF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBhc3NldF9wdWJsaXNoX2ZlZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3B1Ymxpc2hfZmVlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIHdpdG5lc3NfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd3aXRuZXNzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIHdpdG5lc3NfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd3aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogaW50NjRcbn0pO1xuXG52YXIgcHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdwcm9wb3NhbF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgcHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdwcm9wb3NhbF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgcHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdwcm9wb3NhbF9kZWxldGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjQsXG4gIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIHdpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCd3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdjb21taXR0ZWVfbWVtYmVyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIHZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3Zlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXdfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3Zlc3RpbmdfYmFsYW5jZV93aXRoZHJhd19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIHdvcmtlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3dvcmtlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBjdXN0b21fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2N1c3RvbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0LFxuICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMlxufSk7XG5cbnZhciBhc3NlcnRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2VydF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGJhbGFuY2VfY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2JhbGFuY2VfY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJyk7XG5cbnZhciBvdmVycmlkZV90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignb3ZlcnJpZGVfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgdHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zZmVyX3RvX2JsaW5kX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjQsXG4gIHByaWNlX3Blcl9vdXRwdXQ6IHVpbnQzMlxufSk7XG5cbnZhciBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmxpbmRfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NCxcbiAgcHJpY2VfcGVyX291dHB1dDogdWludDMyXG59KTtcblxudmFyIHRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBhc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycpO1xuXG52YXIgYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdmYmFfZGlzdHJpYnV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7fSk7XG5cbnZhciBhc3NldF91cGRhdGVfZGl2aWRlbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZV9kaXZpZGVuZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGFzc2V0X2RpdmlkZW5kX2Rpc3RyaWJ1dGlvbl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfZGl2aWRlbmRfZGlzdHJpYnV0aW9uX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZGlzdHJpYnV0aW9uX2Jhc2VfZmVlOiB1aW50NjQsXG4gIGRpc3RyaWJ1dGlvbl9mZWVfcGVyX2hvbGRlcjogdWludDMyXG59KTtcblxudmFyIHNwb3J0X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignc3BvcnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgc3BvcnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdzcG9ydF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBldmVudF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2V2ZW50X2dyb3VwX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGV2ZW50X2dyb3VwX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignZXZlbnRfZ3JvdXBfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgZXZlbnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdldmVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBldmVudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2V2ZW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X3J1bGVzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfcnVsZXNfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfcnVsZXNfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X2dyb3VwX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYmV0X3BsYWNlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXRfcGxhY2Vfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycpO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfY2FuY2VsX3VubWF0Y2hlZF9iZXRzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBiZXRfbWF0Y2hlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmV0X21hdGNoZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJyk7XG5cbnZhciBiZXRfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXRfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYmV0X2NhbmNlbGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXRfY2FuY2VsZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJyk7XG5cbnZhciB0b3VybmFtZW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcigndG91cm5hbWVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IGludDY0XG59KTtcblxudmFyIHRvdXJuYW1lbnRfam9pbl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcigndG91cm5hbWVudF9qb2luX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycsIHtcbiAgZmVlOiBpbnQ2NFxufSk7XG5cbnZhciBnYW1lX21vdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2dhbWVfbW92ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogaW50NjRcbn0pO1xuXG52YXIgdG91cm5hbWVudF9wYXlvdXRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ3RvdXJuYW1lbnRfcGF5b3V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycpO1xuXG52YXIgdG91cm5hbWVudF9sZWF2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcigndG91cm5hbWVudF9sZWF2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogaW50NjRcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzJywge1xuICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMnLCB7XG4gIGZlZTogdWludDY0XG59KTtcblxudmFyIGJldF9hZGp1c3RlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignYmV0X2FkanVzdGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycycpO1xuXG52YXIgZmVlX3BhcmFtZXRlcnMgPSBzdGF0aWNfdmFyaWFudChbdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBsaW1pdF9vcmRlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBsaW1pdF9vcmRlcl9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBjYWxsX29yZGVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGZpbGxfb3JkZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFjY291bnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X3VwZ3JhZGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9yZXNlcnZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfZnVuZF9mZWVfcG9vbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9wdWJsaXNoX2ZlZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRuZXNzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHdpdG5lc3NfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHdpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXdfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3b3JrZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYmFsYW5jZV9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIG92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgdHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgdG91cm5hbWVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB0b3VybmFtZW50X2pvaW5fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBnYW1lX21vdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF91cGRhdGVfZGl2aWRlbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb25fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB0b3VybmFtZW50X3BheW91dF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHRvdXJuYW1lbnRfbGVhdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBzcG9ydF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBzcG9ydF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBldmVudF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBldmVudF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBldmVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBldmVudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXRfcGxhY2Vfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXRfYWRqdXN0ZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXRfbWF0Y2hlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGJldF9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXRfY2FuY2VsZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBiZXR0aW5nX21hcmtldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXG4vLyBNaXNzaW5nIGV2ZW50X3VwZGF0ZV9zdGF0dXNcbl0pO1xuXG52YXIgZmVlX3NjaGVkdWxlID0gbmV3IFNlcmlhbGl6ZXIoJ2ZlZV9zY2hlZHVsZScsIHtcbiAgcGFyYW1ldGVyczogc2V0KGZlZV9wYXJhbWV0ZXJzKSxcbiAgc2NhbGU6IHVpbnQzMlxufSk7XG5cbnZhciB2b2lkX3Jlc3VsdCA9IG5ldyBTZXJpYWxpemVyKCd2b2lkX3Jlc3VsdCcpO1xuXG52YXIgYXNzZXQgPSBuZXcgU2VyaWFsaXplcignYXNzZXQnLCB7XG4gIGFtb3VudDogaW50NjQsXG4gIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpXG59KTtcblxudmFyIG9wZXJhdGlvbl9yZXN1bHQgPSBzdGF0aWNfdmFyaWFudChbdm9pZF9yZXN1bHQsIG9iamVjdF9pZF90eXBlLCBhc3NldF0pO1xuXG52YXIgcHJvY2Vzc2VkX3RyYW5zYWN0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ3Byb2Nlc3NlZF90cmFuc2FjdGlvbicsIHtcbiAgcmVmX2Jsb2NrX251bTogdWludDE2LFxuICByZWZfYmxvY2tfcHJlZml4OiB1aW50MzIsXG4gIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICBvcGVyYXRpb25zOiBhcnJheShvcGVyYXRpb24pLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICBzaWduYXR1cmVzOiBhcnJheShieXRlcyg2NSkpLFxuICBvcGVyYXRpb25fcmVzdWx0czogYXJyYXkob3BlcmF0aW9uX3Jlc3VsdClcbn0pO1xuXG52YXIgc2lnbmVkX2Jsb2NrID0gbmV3IFNlcmlhbGl6ZXIoJ3NpZ25lZF9ibG9jaycsIHtcbiAgcHJldmlvdXM6IGJ5dGVzKDIwKSxcbiAgdGltZXN0YW1wOiB0aW1lX3BvaW50X3NlYyxcbiAgd2l0bmVzczogcHJvdG9jb2xfaWRfdHlwZSgnd2l0bmVzcycpLFxuICBuZXh0X3NlY3JldF9oYXNoOiBieXRlcygyMCksXG4gIHByZXZpb3VzX3NlY3JldDogYnl0ZXMoMjApLFxuICB0cmFuc2FjdGlvbl9tZXJrbGVfcm9vdDogYnl0ZXMoMjApLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICB3aXRuZXNzX3NpZ25hdHVyZTogYnl0ZXMoNjUpLFxuICB0cmFuc2FjdGlvbnM6IGFycmF5KHByb2Nlc3NlZF90cmFuc2FjdGlvbilcbn0pO1xuXG52YXIgYmxvY2tfaGVhZGVyID0gbmV3IFNlcmlhbGl6ZXIoJ2Jsb2NrX2hlYWRlcicsIHtcbiAgcHJldmlvdXM6IGJ5dGVzKDIwKSxcbiAgdGltZXN0YW1wOiB0aW1lX3BvaW50X3NlYyxcbiAgd2l0bmVzczogcHJvdG9jb2xfaWRfdHlwZSgnd2l0bmVzcycpLFxuICBuZXh0X3NlY3JldF9oYXNoOiBieXRlcygyMCksXG4gIHByZXZpb3VzX3NlY3JldDogYnl0ZXMoMjApLFxuICB0cmFuc2FjdGlvbl9tZXJrbGVfcm9vdDogYnl0ZXMoMjApLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIHNpZ25lZF9ibG9ja19oZWFkZXIgPSBuZXcgU2VyaWFsaXplcignc2lnbmVkX2Jsb2NrX2hlYWRlcicsIHtcbiAgcHJldmlvdXM6IGJ5dGVzKDIwKSxcbiAgdGltZXN0YW1wOiB0aW1lX3BvaW50X3NlYyxcbiAgd2l0bmVzczogcHJvdG9jb2xfaWRfdHlwZSgnd2l0bmVzcycpLFxuICBuZXh0X3NlY3JldF9oYXNoOiBieXRlcygyMCksXG4gIHByZXZpb3VzX3NlY3JldDogYnl0ZXMoMjApLFxuICB0cmFuc2FjdGlvbl9tZXJrbGVfcm9vdDogYnl0ZXMoMjApLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICB3aXRuZXNzX3NpZ25hdHVyZTogYnl0ZXMoNjUpXG59KTtcblxudmFyIG1lbW9fZGF0YSA9IG5ldyBTZXJpYWxpemVyKCdtZW1vX2RhdGEnLCB7XG4gIGZyb206IHB1YmxpY19rZXksXG4gIHRvOiBwdWJsaWNfa2V5LFxuICBub25jZTogdWludDY0LFxuICBtZXNzYWdlOiBieXRlcygpXG59KTtcblxudmFyIHRyYW5zZmVyID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zZmVyJywge1xuICBmZWU6IGFzc2V0LFxuICBmcm9tOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHRvOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFtb3VudDogYXNzZXQsXG4gIG1lbW86IG9wdGlvbmFsKG1lbW9fZGF0YSksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgbGltaXRfb3JkZXJfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2xpbWl0X29yZGVyX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgc2VsbGVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFtb3VudF90b19zZWxsOiBhc3NldCxcbiAgbWluX3RvX3JlY2VpdmU6IGFzc2V0LFxuICBleHBpcmF0aW9uOiB0aW1lX3BvaW50X3NlYyxcbiAgZmlsbF9vcl9raWxsOiBib29sLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGxpbWl0X29yZGVyX2NhbmNlbCA9IG5ldyBTZXJpYWxpemVyKCdsaW1pdF9vcmRlcl9jYW5jZWwnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGZlZV9wYXlpbmdfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBvcmRlcjogcHJvdG9jb2xfaWRfdHlwZSgnbGltaXRfb3JkZXInKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBjYWxsX29yZGVyX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKCdjYWxsX29yZGVyX3VwZGF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZnVuZGluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGRlbHRhX2NvbGxhdGVyYWw6IGFzc2V0LFxuICBkZWx0YV9kZWJ0OiBhc3NldCxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBmaWxsX29yZGVyID0gbmV3IFNlcmlhbGl6ZXIoJ2ZpbGxfb3JkZXInLCB7XG4gIGZlZTogYXNzZXQsXG4gIG9yZGVyX2lkOiBvYmplY3RfaWRfdHlwZSxcbiAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBwYXlzOiBhc3NldCxcbiAgcmVjZWl2ZXM6IGFzc2V0XG59KTtcblxudmFyIGF1dGhvcml0eSA9IG5ldyBTZXJpYWxpemVyKCdhdXRob3JpdHknLCB7XG4gIHdlaWdodF90aHJlc2hvbGQ6IHVpbnQzMixcbiAgYWNjb3VudF9hdXRoczogbWFwKHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSwgdWludDE2KSxcbiAga2V5X2F1dGhzOiBtYXAocHVibGljX2tleSwgdWludDE2KSxcbiAgYWRkcmVzc19hdXRoczogbWFwKGFkZHJlc3MsIHVpbnQxNilcbn0pO1xuXG52YXIgYWNjb3VudF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoJ2FjY291bnRfb3B0aW9ucycsIHtcbiAgbWVtb19rZXk6IHB1YmxpY19rZXksXG4gIHZvdGluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIG51bV93aXRuZXNzOiB1aW50MTYsXG4gIG51bV9jb21taXR0ZWU6IHVpbnQxNixcbiAgdm90ZXM6IHNldCh2b3RlX2lkKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhY2NvdW50X2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKCdhY2NvdW50X2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgcmVnaXN0cmFyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHJlZmVycmVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHJlZmVycmVyX3BlcmNlbnQ6IHVpbnQxNixcbiAgbmFtZTogc3RyaW5nLFxuICBvd25lcjogYXV0aG9yaXR5LFxuICBhY3RpdmU6IGF1dGhvcml0eSxcbiAgb3B0aW9uczogYWNjb3VudF9vcHRpb25zLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFjY291bnRfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2FjY291bnRfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBhY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIG93bmVyOiBvcHRpb25hbChhdXRob3JpdHkpLFxuICBhY3RpdmU6IG9wdGlvbmFsKGF1dGhvcml0eSksXG4gIG5ld19vcHRpb25zOiBvcHRpb25hbChhY2NvdW50X29wdGlvbnMpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFjY291bnRfd2hpdGVsaXN0ID0gbmV3IFNlcmlhbGl6ZXIoJ2FjY291bnRfd2hpdGVsaXN0Jywge1xuICBmZWU6IGFzc2V0LFxuICBhdXRob3JpemluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFjY291bnRfdG9fbGlzdDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBuZXdfbGlzdGluZzogdWludDgsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYWNjb3VudF91cGdyYWRlID0gbmV3IFNlcmlhbGl6ZXIoJ2FjY291bnRfdXBncmFkZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgYWNjb3VudF90b191cGdyYWRlOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHVwZ3JhZGVfdG9fbGlmZXRpbWVfbWVtYmVyOiBib29sLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFjY291bnRfdHJhbnNmZXIgPSBuZXcgU2VyaWFsaXplcignYWNjb3VudF90cmFuc2ZlcicsIHtcbiAgZmVlOiBhc3NldCxcbiAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBuZXdfb3duZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBwcmljZSA9IG5ldyBTZXJpYWxpemVyKCdwcmljZScsIHtcbiAgYmFzZTogYXNzZXQsXG4gIHF1b3RlOiBhc3NldFxufSk7XG5cbnZhciBhc3NldF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X29wdGlvbnMnLCB7XG4gIG1heF9zdXBwbHk6IGludDY0LFxuICBtYXJrZXRfZmVlX3BlcmNlbnQ6IHVpbnQxNixcbiAgbWF4X21hcmtldF9mZWU6IGludDY0LFxuICBpc3N1ZXJfcGVybWlzc2lvbnM6IHVpbnQxNixcbiAgZmxhZ3M6IHVpbnQxNixcbiAgY29yZV9leGNoYW5nZV9yYXRlOiBwcmljZSxcbiAgd2hpdGVsaXN0X2F1dGhvcml0aWVzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgYmxhY2tsaXN0X2F1dGhvcml0aWVzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgd2hpdGVsaXN0X21hcmtldHM6IHNldChwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpKSxcbiAgYmxhY2tsaXN0X21hcmtldHM6IHNldChwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpKSxcbiAgZGVzY3JpcHRpb246IHN0cmluZyxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiaXRhc3NldF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoJ2JpdGFzc2V0X29wdGlvbnMnLCB7XG4gIGZlZWRfbGlmZXRpbWVfc2VjOiB1aW50MzIsXG4gIG1pbmltdW1fZmVlZHM6IHVpbnQ4LFxuICBmb3JjZV9zZXR0bGVtZW50X2RlbGF5X3NlYzogdWludDMyLFxuICBmb3JjZV9zZXR0bGVtZW50X29mZnNldF9wZXJjZW50OiB1aW50MTYsXG4gIG1heGltdW1fZm9yY2Vfc2V0dGxlbWVudF92b2x1bWU6IHVpbnQxNixcbiAgc2hvcnRfYmFja2luZ19hc3NldDogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfY3JlYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgc3ltYm9sOiBzdHJpbmcsXG4gIHByZWNpc2lvbjogdWludDgsXG4gIGNvbW1vbl9vcHRpb25zOiBhc3NldF9vcHRpb25zLFxuICBiaXRhc3NldF9vcHRzOiBvcHRpb25hbChiaXRhc3NldF9vcHRpb25zKSxcbiAgaXNfcHJlZGljdGlvbl9tYXJrZXQ6IGJvb2wsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgbmV3X2lzc3Vlcjogb3B0aW9uYWwocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgbmV3X29wdGlvbnM6IGFzc2V0X29wdGlvbnMsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2JpdGFzc2V0ID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZV9iaXRhc3NldCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgbmV3X29wdGlvbnM6IGJpdGFzc2V0X29wdGlvbnMsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2VycycsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgbmV3X2ZlZWRfcHJvZHVjZXJzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF9pc3N1ZSA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF9pc3N1ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX2lzc3VlOiBhc3NldCxcbiAgaXNzdWVfdG9fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBtZW1vOiBvcHRpb25hbChtZW1vX2RhdGEpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X3Jlc2VydmUgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfcmVzZXJ2ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgcGF5ZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50X3RvX3Jlc2VydmU6IGFzc2V0LFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X2Z1bmRfZmVlX3Bvb2wgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfZnVuZF9mZWVfcG9vbCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgZnJvbV9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpLFxuICBhbW91bnQ6IGludDY0LFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X3NldHRsZSA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF9zZXR0bGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGFjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50OiBhc3NldCxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF9nbG9iYWxfc2V0dGxlID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X2dsb2JhbF9zZXR0bGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGlzc3VlcjogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBhc3NldF90b19zZXR0bGU6IHByb3RvY29sX2lkX3R5cGUoJ2Fzc2V0JyksXG4gIHNldHRsZV9wcmljZTogcHJpY2UsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgcHJpY2VfZmVlZCA9IG5ldyBTZXJpYWxpemVyKCdwcmljZV9mZWVkJywge1xuICBzZXR0bGVtZW50X3ByaWNlOiBwcmljZSxcbiAgbWFpbnRlbmFuY2VfY29sbGF0ZXJhbF9yYXRpbzogdWludDE2LFxuICBtYXhpbXVtX3Nob3J0X3NxdWVlemVfcmF0aW86IHVpbnQxNixcbiAgY29yZV9leGNoYW5nZV9yYXRlOiBwcmljZVxufSk7XG5cbnZhciBhc3NldF9wdWJsaXNoX2ZlZWQgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfcHVibGlzaF9mZWVkJywge1xuICBmZWU6IGFzc2V0LFxuICBwdWJsaXNoZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYXNzZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2Fzc2V0JyksXG4gIGZlZWQ6IHByaWNlX2ZlZWQsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgd2l0bmVzc19jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignd2l0bmVzc19jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIHdpdG5lc3NfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICB1cmw6IHN0cmluZyxcbiAgYmxvY2tfc2lnbmluZ19rZXk6IHB1YmxpY19rZXksXG4gIGluaXRpYWxfc2VjcmV0OiBieXRlcygyMClcbn0pO1xuXG52YXIgd2l0bmVzc191cGRhdGUgPSBuZXcgU2VyaWFsaXplcignd2l0bmVzc191cGRhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIHdpdG5lc3M6IHByb3RvY29sX2lkX3R5cGUoJ3dpdG5lc3MnKSxcbiAgd2l0bmVzc19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIG5ld191cmw6IG9wdGlvbmFsKHN0cmluZyksXG4gIG5ld19zaWduaW5nX2tleTogb3B0aW9uYWwocHVibGljX2tleSksXG4gIG5ld19pbml0aWFsX3NlY3JldDogb3B0aW9uYWwoYnl0ZXMoMjApKVxufSk7XG5cbnZhciBvcF93cmFwcGVyID0gbmV3IFNlcmlhbGl6ZXIoJ29wX3dyYXBwZXInLCB7XG4gIG9wOiBvcGVyYXRpb25cbn0pO1xuXG52YXIgcHJvcG9zYWxfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ3Byb3Bvc2FsX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZmVlX3BheWluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGV4cGlyYXRpb25fdGltZTogdGltZV9wb2ludF9zZWMsXG4gIHByb3Bvc2VkX29wczogYXJyYXkob3Bfd3JhcHBlciksXG4gIHJldmlld19wZXJpb2Rfc2Vjb25kczogb3B0aW9uYWwodWludDMyKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBwcm9wb3NhbF91cGRhdGUgPSBuZXcgU2VyaWFsaXplcigncHJvcG9zYWxfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBmZWVfcGF5aW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgcHJvcG9zYWw6IHByb3RvY29sX2lkX3R5cGUoJ3Byb3Bvc2FsJyksXG4gIGFjdGl2ZV9hcHByb3ZhbHNfdG9fYWRkOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgYWN0aXZlX2FwcHJvdmFsc190b19yZW1vdmU6IHNldChwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JykpLFxuICBvd25lcl9hcHByb3ZhbHNfdG9fYWRkOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgb3duZXJfYXBwcm92YWxzX3RvX3JlbW92ZTogc2V0KHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSksXG4gIGtleV9hcHByb3ZhbHNfdG9fYWRkOiBzZXQocHVibGljX2tleSksXG4gIGtleV9hcHByb3ZhbHNfdG9fcmVtb3ZlOiBzZXQocHVibGljX2tleSksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgcHJvcG9zYWxfZGVsZXRlID0gbmV3IFNlcmlhbGl6ZXIoJ3Byb3Bvc2FsX2RlbGV0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZmVlX3BheWluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHVzaW5nX293bmVyX2F1dGhvcml0eTogYm9vbCxcbiAgcHJvcG9zYWw6IHByb3RvY29sX2lkX3R5cGUoJ3Byb3Bvc2FsJyksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIHdpdGhkcmF3X2Zyb21fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBhdXRob3JpemVkX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgd2l0aGRyYXdhbF9saW1pdDogYXNzZXQsXG4gIHdpdGhkcmF3YWxfcGVyaW9kX3NlYzogdWludDMyLFxuICBwZXJpb2RzX3VudGlsX2V4cGlyYXRpb246IHVpbnQzMixcbiAgcGVyaW9kX3N0YXJ0X3RpbWU6IHRpbWVfcG9pbnRfc2VjXG59KTtcblxudmFyIHdpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ3dpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICB3aXRoZHJhd19mcm9tX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYXV0aG9yaXplZF9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHBlcm1pc3Npb25fdG9fdXBkYXRlOiBwcm90b2NvbF9pZF90eXBlKCd3aXRoZHJhd19wZXJtaXNzaW9uJyksXG4gIHdpdGhkcmF3YWxfbGltaXQ6IGFzc2V0LFxuICB3aXRoZHJhd2FsX3BlcmlvZF9zZWM6IHVpbnQzMixcbiAgcGVyaW9kX3N0YXJ0X3RpbWU6IHRpbWVfcG9pbnRfc2VjLFxuICBwZXJpb2RzX3VudGlsX2V4cGlyYXRpb246IHVpbnQzMlxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltID0gbmV3IFNlcmlhbGl6ZXIoJ3dpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW0nLCB7XG4gIGZlZTogYXNzZXQsXG4gIHdpdGhkcmF3X3Blcm1pc3Npb246IHByb3RvY29sX2lkX3R5cGUoJ3dpdGhkcmF3X3Blcm1pc3Npb24nKSxcbiAgd2l0aGRyYXdfZnJvbV9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHdpdGhkcmF3X3RvX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50X3RvX3dpdGhkcmF3OiBhc3NldCxcbiAgbWVtbzogb3B0aW9uYWwobWVtb19kYXRhKVxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSA9IG5ldyBTZXJpYWxpemVyKCd3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgd2l0aGRyYXdfZnJvbV9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGF1dGhvcml6ZWRfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICB3aXRoZHJhd2FsX3Blcm1pc3Npb246IHByb3RvY29sX2lkX3R5cGUoJ3dpdGhkcmF3X3Blcm1pc3Npb24nKVxufSk7XG5cbnZhciBjb21taXR0ZWVfbWVtYmVyX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKCdjb21taXR0ZWVfbWVtYmVyX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgY29tbWl0dGVlX21lbWJlcl9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHVybDogc3RyaW5nXG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2NvbW1pdHRlZV9tZW1iZXJfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBjb21taXR0ZWVfbWVtYmVyOiBwcm90b2NvbF9pZF90eXBlKCdjb21taXR0ZWVfbWVtYmVyJyksXG4gIGNvbW1pdHRlZV9tZW1iZXJfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBuZXdfdXJsOiBvcHRpb25hbChzdHJpbmcpXG59KTtcblxudmFyIGNoYWluX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcignY2hhaW5fcGFyYW1ldGVycycsIHtcbiAgY3VycmVudF9mZWVzOiBmZWVfc2NoZWR1bGUsXG4gIGJsb2NrX2ludGVydmFsOiB1aW50OCxcbiAgbWFpbnRlbmFuY2VfaW50ZXJ2YWw6IHVpbnQzMixcbiAgbWFpbnRlbmFuY2Vfc2tpcF9zbG90czogdWludDgsXG4gIGNvbW1pdHRlZV9wcm9wb3NhbF9yZXZpZXdfcGVyaW9kOiB1aW50MzIsXG4gIG1heGltdW1fdHJhbnNhY3Rpb25fc2l6ZTogdWludDMyLFxuICBtYXhpbXVtX2Jsb2NrX3NpemU6IHVpbnQzMixcbiAgbWF4aW11bV90aW1lX3VudGlsX2V4cGlyYXRpb246IHVpbnQzMixcbiAgbWF4aW11bV9wcm9wb3NhbF9saWZldGltZTogdWludDMyLFxuICBtYXhpbXVtX2Fzc2V0X3doaXRlbGlzdF9hdXRob3JpdGllczogdWludDgsXG4gIG1heGltdW1fYXNzZXRfZmVlZF9wdWJsaXNoZXJzOiB1aW50OCxcbiAgbWF4aW11bV93aXRuZXNzX2NvdW50OiB1aW50MTYsXG4gIG1heGltdW1fY29tbWl0dGVlX2NvdW50OiB1aW50MTYsXG4gIG1heGltdW1fYXV0aG9yaXR5X21lbWJlcnNoaXA6IHVpbnQxNixcbiAgcmVzZXJ2ZV9wZXJjZW50X29mX2ZlZTogdWludDE2LFxuICBuZXR3b3JrX3BlcmNlbnRfb2ZfZmVlOiB1aW50MTYsXG4gIGxpZmV0aW1lX3JlZmVycmVyX3BlcmNlbnRfb2ZfZmVlOiB1aW50MTYsXG4gIGNhc2hiYWNrX3Zlc3RpbmdfcGVyaW9kX3NlY29uZHM6IHVpbnQzMixcbiAgY2FzaGJhY2tfdmVzdGluZ190aHJlc2hvbGQ6IGludDY0LFxuICBjb3VudF9ub25fbWVtYmVyX3ZvdGVzOiBib29sLFxuICBhbGxvd19ub25fbWVtYmVyX3doaXRlbGlzdHM6IGJvb2wsXG4gIHdpdG5lc3NfcGF5X3Blcl9ibG9jazogaW50NjQsXG4gIHdvcmtlcl9idWRnZXRfcGVyX2RheTogaW50NjQsXG4gIG1heF9wcmVkaWNhdGVfb3Bjb2RlOiB1aW50MTYsXG4gIGZlZV9saXF1aWRhdGlvbl90aHJlc2hvbGQ6IGludDY0LFxuICBhY2NvdW50c19wZXJfZmVlX3NjYWxlOiB1aW50MTYsXG4gIGFjY291bnRfZmVlX3NjYWxlX2JpdHNoaWZ0czogdWludDgsXG4gIG1heF9hdXRob3JpdHlfZGVwdGg6IHVpbnQ4LFxuICBtaW5fYmV0X211bHRpcGxpZXI6IHVpbnQzMixcbiAgbWF4X2JldF9tdWx0aXBsaWVyOiB1aW50MzIsXG4gIGJldHRpbmdfcmFrZV9mZWVfcGVyY2VudGFnZTogdWludDE2LFxuICBwZXJtaXR0ZWRfYmV0dGluZ19vZGRzX2luY3JlbWVudHM6IG1hcCh1aW50MzIsIHVpbnQzMiksXG4gIHdpdG5lc3Nfc2NoZWR1bGVfYWxnb3JpdGhtOiB1aW50OCxcbiAgbGl2ZV9iZXR0aW5nX2RlbGF5X3RpbWU6IHVpbnQxNixcbiAgbWluX3JvdW5kX2RlbGF5OiB1aW50MzIsXG4gIG1heF9yb3VuZF9kZWxheTogdWludDMyLFxuICBtaW5fdGltZV9wZXJfY29tbWl0X21vdmU6IHVpbnQzMixcbiAgbWF4X3RpbWVfcGVyX2NvbW1pdF9tb3ZlOiB1aW50MzIsXG4gIG1pbl90aW1lX3Blcl9yZXZlYWxfbW92ZTogdWludDMyLFxuICBtYXhfdGltZV9wZXJfcmV2ZWFsX21vdmU6IHVpbnQzMixcbiAgcmFrZV9mZWVfcGVyY2VudGFnZTogdWludDE2LFxuICBtYXhpbXVtX3JlZ2lzdHJhdGlvbl9kZWFkbGluZTogdWludDMyLFxuICBtYXhpbXVtX3BsYXllcnNfaW5fdG91cm5hbWVudDogdWludDE2LFxuICBtYXhpbXVtX3RvdXJuYW1lbnRfd2hpdGVsaXN0X2xlbmd0aDogdWludDE2LFxuICBtYXhpbXVtX3RvdXJuYW1lbnRfc3RhcnRfdGltZV9pbl9mdXR1cmU6IHVpbnQzMixcbiAgbWF4aW11bV90b3VybmFtZW50X3N0YXJ0X2RlbGF5OiB1aW50MzIsXG4gIG1heGltdW1fdG91cm5hbWVudF9udW1iZXJfb2Zfd2luczogdWludDE2LFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoJ2NvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzJywge1xuICBmZWU6IGFzc2V0LFxuICBuZXdfcGFyYW1ldGVyczogY2hhaW5fcGFyYW1ldGVyc1xufSk7XG5cbnZhciBsaW5lYXJfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXIgPSBuZXcgU2VyaWFsaXplcignbGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyJywge1xuICBiZWdpbl90aW1lc3RhbXA6IHRpbWVfcG9pbnRfc2VjLFxuICB2ZXN0aW5nX2NsaWZmX3NlY29uZHM6IHVpbnQzMixcbiAgdmVzdGluZ19kdXJhdGlvbl9zZWNvbmRzOiB1aW50MzJcbn0pO1xuXG52YXIgY2RkX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXIoJ2NkZF92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplcicsIHtcbiAgc3RhcnRfY2xhaW06IHRpbWVfcG9pbnRfc2VjLFxuICB2ZXN0aW5nX3NlY29uZHM6IHVpbnQzMlxufSk7XG5cbnZhciB2ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplciA9IHN0YXRpY192YXJpYW50KFtsaW5lYXJfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXIsIGNkZF92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplcl0pO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKCd2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBjcmVhdG9yOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIG93bmVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFtb3VudDogYXNzZXQsXG4gIHBvbGljeTogdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXJcbn0pO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3ID0gbmV3IFNlcmlhbGl6ZXIoJ3Zlc3RpbmdfYmFsYW5jZV93aXRoZHJhdycsIHtcbiAgZmVlOiBhc3NldCxcbiAgdmVzdGluZ19iYWxhbmNlOiBwcm90b2NvbF9pZF90eXBlKCd2ZXN0aW5nX2JhbGFuY2UnKSxcbiAgb3duZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50OiBhc3NldFxufSk7XG5cbnZhciByZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXIoJ3JlZnVuZF93b3JrZXJfaW5pdGlhbGl6ZXInKTtcblxudmFyIHZlc3RpbmdfYmFsYW5jZV93b3JrZXJfaW5pdGlhbGl6ZXIgPSBuZXcgU2VyaWFsaXplcigndmVzdGluZ19iYWxhbmNlX3dvcmtlcl9pbml0aWFsaXplcicsIHtcbiAgcGF5X3Zlc3RpbmdfcGVyaW9kX2RheXM6IHVpbnQxNlxufSk7XG5cbnZhciBidXJuX3dvcmtlcl9pbml0aWFsaXplciA9IG5ldyBTZXJpYWxpemVyKCdidXJuX3dvcmtlcl9pbml0aWFsaXplcicpO1xuXG52YXIgd29ya2VyX2luaXRpYWxpemVyID0gc3RhdGljX3ZhcmlhbnQoW3JlZnVuZF93b3JrZXJfaW5pdGlhbGl6ZXIsIHZlc3RpbmdfYmFsYW5jZV93b3JrZXJfaW5pdGlhbGl6ZXIsIGJ1cm5fd29ya2VyX2luaXRpYWxpemVyXSk7XG5cbnZhciB3b3JrZXJfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ3dvcmtlcl9jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIG93bmVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHdvcmtfYmVnaW5fZGF0ZTogdGltZV9wb2ludF9zZWMsXG4gIHdvcmtfZW5kX2RhdGU6IHRpbWVfcG9pbnRfc2VjLFxuICBkYWlseV9wYXk6IGludDY0LFxuICBuYW1lOiBzdHJpbmcsXG4gIHVybDogc3RyaW5nLFxuICBpbml0aWFsaXplcjogd29ya2VyX2luaXRpYWxpemVyXG59KTtcblxudmFyIGN1c3RvbSA9IG5ldyBTZXJpYWxpemVyKCdjdXN0b20nLCB7XG4gIGZlZTogYXNzZXQsXG4gIHBheWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHJlcXVpcmVkX2F1dGhzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgaWQ6IHVpbnQxNixcbiAgZGF0YTogYnl0ZXMoKVxufSk7XG5cbnZhciBhY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZSA9IG5ldyBTZXJpYWxpemVyKCdhY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZScsIHtcbiAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBuYW1lOiBzdHJpbmdcbn0pO1xuXG52YXIgYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUnLCB7XG4gIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpLFxuICBzeW1ib2w6IHN0cmluZ1xufSk7XG5cbnZhciBibG9ja19pZF9wcmVkaWNhdGUgPSBuZXcgU2VyaWFsaXplcignYmxvY2tfaWRfcHJlZGljYXRlJywge1xuICBpZDogYnl0ZXMoMjApXG59KTtcblxudmFyIHByZWRpY2F0ZSA9IHN0YXRpY192YXJpYW50KFthY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZSwgYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUsIGJsb2NrX2lkX3ByZWRpY2F0ZV0pO1xuXG52YXIgYXNzZXJ0ID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2VydCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgZmVlX3BheWluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHByZWRpY2F0ZXM6IGFycmF5KHByZWRpY2F0ZSksXG4gIHJlcXVpcmVkX2F1dGhzOiBzZXQocHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiYWxhbmNlX2NsYWltID0gbmV3IFNlcmlhbGl6ZXIoJ2JhbGFuY2VfY2xhaW0nLCB7XG4gIGZlZTogYXNzZXQsXG4gIGRlcG9zaXRfdG9fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBiYWxhbmNlX3RvX2NsYWltOiBwcm90b2NvbF9pZF90eXBlKCdiYWxhbmNlJyksXG4gIGJhbGFuY2Vfb3duZXJfa2V5OiBwdWJsaWNfa2V5LFxuICB0b3RhbF9jbGFpbWVkOiBhc3NldFxufSk7XG5cbnZhciBvdmVycmlkZV90cmFuc2ZlciA9IG5ldyBTZXJpYWxpemVyKCdvdmVycmlkZV90cmFuc2ZlcicsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGZyb206IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgdG86IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50OiBhc3NldCxcbiAgbWVtbzogb3B0aW9uYWwobWVtb19kYXRhKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBzdGVhbHRoX2NvbmZpcm1hdGlvbiA9IG5ldyBTZXJpYWxpemVyKCdzdGVhbHRoX2NvbmZpcm1hdGlvbicsIHtcbiAgb25lX3RpbWVfa2V5OiBwdWJsaWNfa2V5LFxuICB0bzogb3B0aW9uYWwocHVibGljX2tleSksXG4gIGVuY3J5cHRlZF9tZW1vOiBieXRlcygpXG59KTtcblxudmFyIGJsaW5kX291dHB1dCA9IG5ldyBTZXJpYWxpemVyKCdibGluZF9vdXRwdXQnLCB7XG4gIGNvbW1pdG1lbnQ6IGJ5dGVzKDMzKSxcbiAgcmFuZ2VfcHJvb2Y6IGJ5dGVzKCksXG4gIG93bmVyOiBhdXRob3JpdHksXG4gIHN0ZWFsdGhfbWVtbzogb3B0aW9uYWwoc3RlYWx0aF9jb25maXJtYXRpb24pXG59KTtcblxudmFyIHRyYW5zZmVyX3RvX2JsaW5kID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zZmVyX3RvX2JsaW5kJywge1xuICBmZWU6IGFzc2V0LFxuICBhbW91bnQ6IGFzc2V0LFxuICBmcm9tOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGJsaW5kaW5nX2ZhY3RvcjogYnl0ZXMoMzIpLFxuICBvdXRwdXRzOiBhcnJheShibGluZF9vdXRwdXQpXG59KTtcblxudmFyIGJsaW5kX2lucHV0ID0gbmV3IFNlcmlhbGl6ZXIoJ2JsaW5kX2lucHV0Jywge1xuICBjb21taXRtZW50OiBieXRlcygzMyksXG4gIG93bmVyOiBhdXRob3JpdHlcbn0pO1xuXG52YXIgYmxpbmRfdHJhbnNmZXIgPSBuZXcgU2VyaWFsaXplcignYmxpbmRfdHJhbnNmZXInLCB7XG4gIGZlZTogYXNzZXQsXG4gIGlucHV0czogYXJyYXkoYmxpbmRfaW5wdXQpLFxuICBvdXRwdXRzOiBhcnJheShibGluZF9vdXRwdXQpXG59KTtcblxudmFyIHRyYW5zZmVyX2Zyb21fYmxpbmQgPSBuZXcgU2VyaWFsaXplcigndHJhbnNmZXJfZnJvbV9ibGluZCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgYW1vdW50OiBhc3NldCxcbiAgdG86IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmxpbmRpbmdfZmFjdG9yOiBieXRlcygzMiksXG4gIGlucHV0czogYXJyYXkoYmxpbmRfaW5wdXQpXG59KTtcblxudmFyIGFzc2V0X3NldHRsZV9jYW5jZWwgPSBuZXcgU2VyaWFsaXplcignYXNzZXRfc2V0dGxlX2NhbmNlbCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgc2V0dGxlbWVudDogcHJvdG9jb2xfaWRfdHlwZSgnZm9yY2Vfc2V0dGxlbWVudCcpLFxuICBhY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFtb3VudDogYXNzZXQsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfY2xhaW1fZmVlcyA9IG5ldyBTZXJpYWxpemVyKCdhc3NldF9jbGFpbV9mZWVzJywge1xuICBmZWU6IGFzc2V0LFxuICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50X3RvX2NsYWltOiBhc3NldCxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBmYmFfZGlzdHJpYnV0ZSA9IG5ldyBTZXJpYWxpemVyKCdmYmFfZGlzdHJpYnV0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBmYmFfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2ZiYV9hY2N1bXVsYXRvcicpLFxuICBhbW91bnQ6IGludDY0XG59KTtcblxudmFyIHJvY2tfcGFwZXJfc2Npc3NvcnNfZ2FtZV9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoJ3JvY2tfcGFwZXJfc2Npc3NvcnNfZ2FtZV9vcHRpb25zJywge1xuICBpbnN1cmFuY2VfZW5hYmxlZDogYm9vbCxcbiAgdGltZV9wZXJfY29tbWl0X21vdmU6IHVpbnQzMixcbiAgdGltZV9wZXJfcmV2ZWFsX21vdmU6IHVpbnQzMixcbiAgbnVtYmVyX29mX2dlc3R1cmVzOiB1aW50OFxufSk7XG5cbnZhciBnYW1lX3NwZWNpZmljX2RldGFpbHMgPSBzdGF0aWNfdmFyaWFudChbcm9ja19wYXBlcl9zY2lzc29yc19nYW1lX29wdGlvbnNdKTtcblxudmFyIHRvdXJuYW1lbnRfb3B0aW9ucyA9IG5ldyBTZXJpYWxpemVyKCd0b3VybmFtZW50X29wdGlvbnMnLCB7XG4gIHR5cGVfb2ZfZ2FtZTogdWludDE2LFxuICByZWdpc3RyYXRpb25fZGVhZGxpbmU6IHRpbWVfcG9pbnRfc2VjLFxuICBudW1iZXJfb2ZfcGxheWVyczogdWludDMyLFxuICBidXlfaW46IGFzc2V0LFxuICB3aGl0ZWxpc3Q6IHNldChwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JykpLFxuICBzdGFydF90aW1lOiBvcHRpb25hbCh0aW1lX3BvaW50X3NlYyksXG4gIHN0YXJ0X2RlbGF5OiBvcHRpb25hbCh1aW50MzIpLFxuICByb3VuZF9kZWxheTogdWludDMyLFxuICBudW1iZXJfb2Zfd2luczogdWludDMyLFxuICBtZXRhOiB2YXJpYW50X29iamVjdCxcbiAgZ2FtZV9vcHRpb25zOiBnYW1lX3NwZWNpZmljX2RldGFpbHNcbn0pO1xuXG52YXIgdG91cm5hbWVudF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcigndG91cm5hbWVudF9jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGNyZWF0b3I6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgb3B0aW9uczogdG91cm5hbWVudF9vcHRpb25zLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIHRvdXJuYW1lbnRfam9pbiA9IG5ldyBTZXJpYWxpemVyKCd0b3VybmFtZW50X2pvaW4nLCB7XG4gIGZlZTogYXNzZXQsXG4gIHBheWVyX2FjY291bnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgcGxheWVyX2FjY291bnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgdG91cm5hbWVudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgndG91cm5hbWVudCcpLFxuICBidXlfaW46IGFzc2V0LFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIHJvY2tfcGFwZXJfc2Npc3NvcnNfZ2VzdHVyZSA9IGVudW1lcmF0aW9uKFsncm9jaycsICdwYXBlcicsICdzY2lzc29ycycsICdzcG9jaycsICdsaXphcmQnXSk7XG5cbnZhciByb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X2NvbW1pdCA9IG5ldyBTZXJpYWxpemVyKCdyb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X2NvbW1pdCcsIHtcbiAgbm9uY2UxOiB1aW50NjQsXG4gIHRocm93X2hhc2g6IHNoYTI1NlxufSk7XG5cbnZhciByb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X3JldmVhbCA9IG5ldyBTZXJpYWxpemVyKCdyb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X3JldmVhbCcsIHtcbiAgbm9uY2UyOiB1aW50NjQsXG4gIGdlc3R1cmU6IHJvY2tfcGFwZXJfc2Npc3NvcnNfZ2VzdHVyZVxufSk7XG5cbnZhciBnYW1lX3NwZWNpZmljX21vdmVzID0gc3RhdGljX3ZhcmlhbnQoW3JvY2tfcGFwZXJfc2Npc3NvcnNfdGhyb3dfY29tbWl0LCByb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X3JldmVhbF0pO1xuXG52YXIgZ2FtZV9tb3ZlID0gbmV3IFNlcmlhbGl6ZXIoJ2dhbWVfbW92ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZ2FtZV9pZDogcHJvdG9jb2xfaWRfdHlwZSgnZ2FtZScpLFxuICBwbGF5ZXJfYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBtb3ZlOiBnYW1lX3NwZWNpZmljX21vdmVzLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGRpdmlkZW5kX2Fzc2V0X29wdGlvbnMgPSBuZXcgU2VyaWFsaXplcignZGl2aWRlbmRfYXNzZXRfb3B0aW9ucycsIHtcbiAgbmV4dF9wYXlvdXRfdGltZTogb3B0aW9uYWwodGltZV9wb2ludF9zZWMpLFxuICBwYXlvdXRfaW50ZXJ2YWw6IG9wdGlvbmFsKHVpbnQzMiksXG4gIG1pbmltdW1fZmVlX3BlcmNlbnRhZ2U6IHVpbnQ2NCxcbiAgbWluaW11bV9kaXN0cmlidXRpb25faW50ZXJ2YWw6IG9wdGlvbmFsKHVpbnQzMiksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2RpdmlkZW5kID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X3VwZGF0ZV9kaXZpZGVuZCcsIHtcbiAgZmVlOiBhc3NldCxcbiAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgbmV3X29wdGlvbnM6IGRpdmlkZW5kX2Fzc2V0X29wdGlvbnMsXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfZGl2aWRlbmRfZGlzdHJpYnV0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ2Fzc2V0X2RpdmlkZW5kX2Rpc3RyaWJ1dGlvbicsIHtcbiAgZmVlOiBhc3NldCxcbiAgZGl2aWRlbmRfYXNzZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2Fzc2V0JyksXG4gIGFjY291bnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYW1vdW50czogc2V0KGFzc2V0KSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBzcG9ydF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignc3BvcnRfY3JlYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBuYW1lOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIHNwb3J0X3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKCdzcG9ydF91cGRhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIHNwb3J0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdzcG9ydCcpLFxuICBuZXdfbmFtZTogb3B0aW9uYWwobWFwKHN0cmluZywgc3RyaW5nKSksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgZXZlbnRfZ3JvdXBfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2V2ZW50X2dyb3VwX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgbmFtZTogbWFwKHN0cmluZywgc3RyaW5nKSxcbiAgc3BvcnRfaWQ6IG9iamVjdF9pZF90eXBlLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGV2ZW50X2dyb3VwX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKCdldmVudF9ncm91cF91cGRhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIG5ld19zcG9ydF9pZDogb3B0aW9uYWwocHJvdG9jb2xfaWRfdHlwZSgnc3BvcnQnKSksXG4gIG5ld19uYW1lOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgZXZlbnRfZ3JvdXBfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2V2ZW50X2dyb3VwJyksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgZXZlbnRfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2V2ZW50X2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgbmFtZTogbWFwKHN0cmluZywgc3RyaW5nKSxcbiAgc2Vhc29uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBzdGFydF90aW1lOiBvcHRpb25hbCh0aW1lX3BvaW50X3NlYyksXG4gIGV2ZW50X2dyb3VwX2lkOiBvYmplY3RfaWRfdHlwZSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBldmVudF91cGRhdGUgPSBuZXcgU2VyaWFsaXplcignZXZlbnRfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBldmVudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnZXZlbnQnKSxcbiAgbmV3X2V2ZW50X2dyb3VwX2lkOiBvcHRpb25hbChwcm90b2NvbF9pZF90eXBlKCdldmVudF9ncm91cCcpKSxcbiAgbmV3X25hbWU6IG9wdGlvbmFsKG1hcChzdHJpbmcsIHN0cmluZykpLFxuICBuZXdfc2Vhc29uOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgbmV3X3N0YXJ0X3RpbWU6IG9wdGlvbmFsKHRpbWVfcG9pbnRfc2VjKSxcbiAgaXNfbGl2ZV9tYXJrZXQ6IG9wdGlvbmFsKGJvb2wpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X3J1bGVzX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIG5hbWU6IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIGRlc2NyaXB0aW9uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ydWxlc191cGRhdGUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIG5ld19uYW1lOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgbmV3X2Rlc2NyaXB0aW9uOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSxcbiAgYmV0dGluZ19tYXJrZXRfcnVsZXNfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0X3J1bGVzJylcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X2dyb3VwX2NyZWF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgZGVzY3JpcHRpb246IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIGV2ZW50X2lkOiBvYmplY3RfaWRfdHlwZSxcbiAgcnVsZXNfaWQ6IG9iamVjdF9pZF90eXBlLFxuICBhc3NldF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfY3JlYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBncm91cF9pZDogb2JqZWN0X2lkX3R5cGUsXG4gIGRlc2NyaXB0aW9uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBwYXlvdXRfY29uZGl0aW9uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldF90eXBlID0gZW51bWVyYXRpb24oWydiYWNrJywgJ2xheSddKTtcblxudmFyIGJldF9wbGFjZSA9IG5ldyBTZXJpYWxpemVyKCdiZXRfcGxhY2UnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGJldHRvcl9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBiZXR0aW5nX21hcmtldF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXQnKSxcbiAgYW1vdW50X3RvX2JldDogYXNzZXQsXG4gIGJhY2tlcl9tdWx0aXBsaWVyOiB1aW50MzIsXG4gIGJhY2tfb3JfbGF5OiBiZXRfdHlwZSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9yZXNvbHV0aW9uX3R5cGUgPSBlbnVtZXJhdGlvbihbJ3dpbicsICdub3Rfd2luJywgJ2NhbmNlbCcsICdCRVRUSU5HX01BUktFVF9SRVNPTFVUSU9OX0NPVU5UJ10pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZSA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlJywge1xuICBmZWU6IGFzc2V0LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfZ3JvdXAnKSxcbiAgcmVzb2x1dGlvbnM6IG1hcChwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldCcpLCBiZXR0aW5nX21hcmtldF9yZXNvbHV0aW9uX3R5cGUpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkJywge1xuICBiZXR0b3JfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmV0dGluZ19tYXJrZXRfZ3JvdXBfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0X2dyb3VwJyksXG4gIHJlc29sdXRpb25zOiBtYXAocHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXQnKSwgYmV0dGluZ19tYXJrZXRfcmVzb2x1dGlvbl90eXBlKSxcbiAgd2lubmluZ3M6IGludDY0LFxuICBmZWVzX3BhaWQ6IGludDY0LFxuICBmZWU6IGFzc2V0XG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X2dyb3VwX2NhbmNlbF91bm1hdGNoZWRfYmV0cyA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHMnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGJldHRpbmdfbWFya2V0X2dyb3VwX2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldF9ncm91cCcpLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGJldF9tYXRjaGVkID0gbmV3IFNlcmlhbGl6ZXIoJ2JldF9tYXRjaGVkJywge1xuICBiZXR0b3JfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmV0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgYmV0dGluZ19tYXJrZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0JyksXG4gIGFtb3VudF9iZXQ6IGFzc2V0LFxuICBmZWVzX3BhaWQ6IGludDY0LFxuICBiYWNrZXJfbXVsdGlwbGllcjogdWludDMyLFxuICBndWFyYW50ZWVkX3dpbm5pbmdzX3JldHVybmVkOiBpbnQ2NFxufSk7XG5cbnZhciBiZXRfY2FuY2VsID0gbmV3IFNlcmlhbGl6ZXIoJ2JldF9jYW5jZWwnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGJldHRvcl9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICBiZXRfdG9fY2FuY2VsOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXRfY2FuY2VsZWQgPSBuZXcgU2VyaWFsaXplcignYmV0X2NhbmNlbGVkJywge1xuICBiZXR0b3JfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmV0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgc3Rha2VfcmV0dXJuZWQ6IGFzc2V0LFxuICB1bnVzZWRfZmVlc19yZXR1cm5lZDogYXNzZXRcbn0pO1xuXG52YXIgcGF5b3V0X3R5cGUgPSBlbnVtZXJhdGlvbihbJ3ByaXplX2F3YXJkJywgJ2J1eWluX3JlZnVuZCcsICdyYWtlX2ZlZSddKTtcblxudmFyIHRvdXJuYW1lbnRfcGF5b3V0ID0gbmV3IFNlcmlhbGl6ZXIoJ3RvdXJuYW1lbnRfcGF5b3V0Jywge1xuICBmZWU6IGFzc2V0LFxuICBwYXlvdXRfYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYWNjb3VudCcpLFxuICB0b3VybmFtZW50X2lkOiBwcm90b2NvbF9pZF90eXBlKCd0b3VybmFtZW50JyksXG4gIHBheW91dF9hbW91bnQ6IGFzc2V0LFxuICB0eXBlOiBwYXlvdXRfdHlwZSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciB0b3VybmFtZW50X2xlYXZlID0gbmV3IFNlcmlhbGl6ZXIoJ3RvdXJuYW1lbnRfbGVhdmUnLCB7XG4gIGZlZTogYXNzZXQsXG4gIGNhbmNlbGluZ19hY2NvdW50X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHBsYXllcl9hY2NvdW50X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIHRvdXJuYW1lbnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ3RvdXJuYW1lbnQnKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGUgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlJywge1xuICBmZWU6IGFzc2V0LFxuICBiZXR0aW5nX21hcmtldF9ncm91cF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfZ3JvdXAnKSxcbiAgbmV3X2Rlc2NyaXB0aW9uOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgbmV3X3J1bGVzX2lkOiBvcHRpb25hbChwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldF9ydWxlcycpKSxcbiAgZnJlZXplOiBvcHRpb25hbChib29sKSxcbiAgZGVsYXlfYmV0czogb3B0aW9uYWwoYm9vbCksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X3VwZGF0ZScsIHtcbiAgZmVlOiBhc3NldCxcbiAgYmV0dGluZ19tYXJrZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0JyksXG4gIG5ld19ncm91cF9pZDogb3B0aW9uYWwocHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfZ3JvdXAnKSksXG4gIG5ld19kZXNjcmlwdGlvbjogb3B0aW9uYWwobWFwKHN0cmluZywgc3RyaW5nKSksXG4gIG5ld19wYXlvdXRfY29uZGl0aW9uOiBvcHRpb25hbChtYXAoc3RyaW5nLCBzdHJpbmcpKSxcbiAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiZXRfYWRqdXN0ZWQgPSBuZXcgU2VyaWFsaXplcignYmV0X2FkanVzdGVkJywge1xuICBiZXR0b3JfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2FjY291bnQnKSxcbiAgYmV0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgc3Rha2VfcmV0dXJuZWQ6IGFzc2V0XG59KTtcblxub3BlcmF0aW9uLnN0X29wZXJhdGlvbnMgPSBbdHJhbnNmZXIsIGxpbWl0X29yZGVyX2NyZWF0ZSwgbGltaXRfb3JkZXJfY2FuY2VsLCBjYWxsX29yZGVyX3VwZGF0ZSwgZmlsbF9vcmRlciwgYWNjb3VudF9jcmVhdGUsIGFjY291bnRfdXBkYXRlLCBhY2NvdW50X3doaXRlbGlzdCwgYWNjb3VudF91cGdyYWRlLCBhY2NvdW50X3RyYW5zZmVyLCBhc3NldF9jcmVhdGUsIGFzc2V0X3VwZGF0ZSwgYXNzZXRfdXBkYXRlX2JpdGFzc2V0LCBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnMsIGFzc2V0X2lzc3VlLCBhc3NldF9yZXNlcnZlLCBhc3NldF9mdW5kX2ZlZV9wb29sLCBhc3NldF9zZXR0bGUsIGFzc2V0X2dsb2JhbF9zZXR0bGUsIGFzc2V0X3B1Ymxpc2hfZmVlZCwgd2l0bmVzc19jcmVhdGUsIHdpdG5lc3NfdXBkYXRlLCBwcm9wb3NhbF9jcmVhdGUsIHByb3Bvc2FsX3VwZGF0ZSwgcHJvcG9zYWxfZGVsZXRlLCB3aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZSwgd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGUsIHdpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW0sIHdpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlLCBjb21taXR0ZWVfbWVtYmVyX2NyZWF0ZSwgY29tbWl0dGVlX21lbWJlcl91cGRhdGUsIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzLCB2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlLCB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXcsIHdvcmtlcl9jcmVhdGUsIGN1c3RvbSwgYXNzZXJ0LCBiYWxhbmNlX2NsYWltLCBvdmVycmlkZV90cmFuc2ZlciwgdHJhbnNmZXJfdG9fYmxpbmQsIGJsaW5kX3RyYW5zZmVyLCB0cmFuc2Zlcl9mcm9tX2JsaW5kLCBhc3NldF9zZXR0bGVfY2FuY2VsLCBhc3NldF9jbGFpbV9mZWVzLCBmYmFfZGlzdHJpYnV0ZSwgdG91cm5hbWVudF9jcmVhdGUsIHRvdXJuYW1lbnRfam9pbiwgZ2FtZV9tb3ZlLCBhc3NldF91cGRhdGVfZGl2aWRlbmQsIGFzc2V0X2RpdmlkZW5kX2Rpc3RyaWJ1dGlvbiwgdG91cm5hbWVudF9wYXlvdXQsIHRvdXJuYW1lbnRfbGVhdmUsIHNwb3J0X2NyZWF0ZSwgc3BvcnRfdXBkYXRlLCBldmVudF9ncm91cF9jcmVhdGUsIGV2ZW50X2dyb3VwX3VwZGF0ZSwgZXZlbnRfY3JlYXRlLCBldmVudF91cGRhdGUsIGJldHRpbmdfbWFya2V0X3J1bGVzX2NyZWF0ZSwgYmV0dGluZ19tYXJrZXRfcnVsZXNfdXBkYXRlLCBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGUsIGJldHRpbmdfbWFya2V0X2NyZWF0ZSwgYmV0X3BsYWNlLCBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlLCBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlZCwgYmV0X2FkanVzdGVkLCBiZXR0aW5nX21hcmtldF9ncm91cF9jYW5jZWxfdW5tYXRjaGVkX2JldHMsIGJldF9tYXRjaGVkLCBiZXRfY2FuY2VsLCBiZXRfY2FuY2VsZWQsIGJldHRpbmdfbWFya2V0X2dyb3VwX3VwZGF0ZSwgYmV0dGluZ19tYXJrZXRfdXBkYXRlXTtcblxudmFyIHRyYW5zYWN0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ3RyYW5zYWN0aW9uJywge1xuICByZWZfYmxvY2tfbnVtOiB1aW50MTYsXG4gIHJlZl9ibG9ja19wcmVmaXg6IHVpbnQzMixcbiAgZXhwaXJhdGlvbjogdGltZV9wb2ludF9zZWMsXG4gIG9wZXJhdGlvbnM6IGFycmF5KG9wZXJhdGlvbiksXG4gIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgc2lnbmVkX3RyYW5zYWN0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ3NpZ25lZF90cmFuc2FjdGlvbicsIHtcbiAgcmVmX2Jsb2NrX251bTogdWludDE2LFxuICByZWZfYmxvY2tfcHJlZml4OiB1aW50MzIsXG4gIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICBvcGVyYXRpb25zOiBhcnJheShvcGVyYXRpb24pLFxuICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICBzaWduYXR1cmVzOiBhcnJheShieXRlcyg2NSkpXG59KTtcbi8vICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gIyAgR2VuZXJhdGVkIGNvZGUgZW5kXG4vLyAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gQmV0dGluZyBPYmplY3RzXG5cbnZhciBzcG9ydCA9IG5ldyBTZXJpYWxpemVyKCdzcG9ydCcsIHtcbiAgaWQ6IHByb3RvY29sX2lkX3R5cGUoJ3Nwb3J0JyksXG4gIG5hbWU6IG1hcChzdHJpbmcsIHN0cmluZylcbn0pO1xuXG52YXIgZXZlbnRfZ3JvdXAgPSBuZXcgU2VyaWFsaXplcignZXZlbnRfZ3JvdXAnLCB7XG4gIGlkOiBwcm90b2NvbF9pZF90eXBlKCdldmVudF9ncm91cCcpLFxuICBuYW1lOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBzcG9ydF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnc3BvcnQnKVxufSk7XG5cbnZhciBldmVudF9zdGF0dXMgPSBlbnVtZXJhdGlvbihbJ3VwY29taW5nJywgJ2luX3Byb2dyZXNzJywgJ2Zyb3plbicsICdmaW5pc2hlZCcsICdjb21wbGV0ZWQnLCAnY2FuY2VsZWQnLCAnU1RBVFVTX0NPVU5UJ10pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfc3RhdHVzID0gZW51bWVyYXRpb24oWyd1bnJlc29sdmVkJywgJ2Zyb3plbicsICdncmFkZWQnLCAnY2FuY2VsZWQnLCAnc2V0dGxlZCddKTtcblxudmFyIGJldHRpbmdfbWFya2V0X2dyb3VwX3N0YXR1cyA9IGVudW1lcmF0aW9uKFsndXBjb21pbmcnLCAnaW5fcGxheScsICdjbG9zZWQnLCAnZ3JhZGVkJywgJ3JlLWdyYWRpbmcnLCAnc2V0dGxlZCcsICdmcm96ZW4nLCAnY2FuY2VsZWQnXSk7XG5cbnZhciBldmVudCA9IG5ldyBTZXJpYWxpemVyKCdldmVudCcsIHtcbiAgaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2V2ZW50JyksXG4gIG5hbWU6IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIHNlYXNvbjogbWFwKHN0cmluZywgc3RyaW5nKSxcbiAgc3RhcnRfdGltZTogb3B0aW9uYWwodGltZV9wb2ludF9zZWMpLFxuICBldmVudF9ncm91cF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnZXZlbnRfZ3JvdXAnKSxcbiAgaXNfbGl2ZV9tYXJrZXQ6IGJvb2wsXG4gIHN0YXR1czogZXZlbnRfc3RhdHVzLFxuICBzY29yZXM6IGFycmF5KHN0cmluZylcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXRfcnVsZXMgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXRfcnVsZXMnLCB7XG4gIGlkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldF9ydWxlcycpLFxuICBuYW1lOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBkZXNjcmlwdGlvbjogbWFwKHN0cmluZywgc3RyaW5nKVxufSk7XG5cbnZhciBiZXR0aW5nX21hcmtldF9ncm91cCA9IG5ldyBTZXJpYWxpemVyKCdiZXR0aW5nX21hcmtldF9ncm91cCcsIHtcbiAgaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0X2dyb3VwJyksXG4gIGRlc2NyaXB0aW9uOiBtYXAoc3RyaW5nLCBzdHJpbmcpLFxuICBldmVudF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnZXZlbnQnKSxcbiAgcnVsZXNfaWQ6IHByb3RvY29sX2lkX3R5cGUoJ2JldHRpbmdfbWFya2V0X3J1bGVzJyksXG4gIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdhc3NldCcpLFxuICB0b3RhbF9tYXRjaGVkX2JldHNfYW1vdW50OiB1aW50NjQsXG4gIGZyb3plbjogYm9vbCxcbiAgZGVsYXlfYmV0czogYm9vbCxcbiAgc3RhdHVzOiBiZXR0aW5nX21hcmtldF9ncm91cF9zdGF0dXNcbn0pO1xuXG52YXIgYmV0dGluZ19tYXJrZXQgPSBuZXcgU2VyaWFsaXplcignYmV0dGluZ19tYXJrZXQnLCB7XG4gIGlkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldCcpLFxuICBncm91cF9pZDogcHJvdG9jb2xfaWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfZ3JvdXAnKSxcbiAgZGVzY3JpcHRpb246IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIHBheW91dF9jb25kaXRpb246IG1hcChzdHJpbmcsIHN0cmluZyksXG4gIHN0YXR1czogYmV0dGluZ19tYXJrZXRfc3RhdHVzXG59KTtcblxudmFyIGJldCA9IG5ldyBTZXJpYWxpemVyKCdiZXQnLCB7XG4gIGlkOiBwcm90b2NvbF9pZF90eXBlKCdiZXQnKSxcbiAgYmV0dG9yX2lkOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGJldHRpbmdfbWFya2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldCcpLFxuICBhbW91bnRfdG9fYmV0OiBhc3NldCxcbiAgYmFja2VyX211bHRpcGxpZXI6IHVpbnQzMixcbiAgYmFja19vcl9sYXk6IGJldF90eXBlXG59KTtcblxudmFyIGJldHRpbmdfbWFya2V0X3Bvc2l0aW9uID0gbmV3IFNlcmlhbGl6ZXIoJ2JldHRpbmdfbWFya2V0X3Bvc2l0aW9uJywge1xuICBpZDogaW1wbGVtZW50YXRpb25faWRfdHlwZSgnYmV0dGluZ19tYXJrZXRfcG9zaXRpb24nKSxcbiAgYmV0dG9yX2lkOiBwcm90b2NvbF9pZF90eXBlKCdhY2NvdW50JyksXG4gIGJldHRpbmdfbWFya2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKCdiZXR0aW5nX21hcmtldCcpLFxuICBwYXlfaWZfcGF5b3V0X2NvbmRpdGlvbjogaW50NjQsXG4gIHBheV9pZl9ub3RfcGF5b3V0X2NvbmRpdGlvbjogaW50NjQsXG4gIHBheV9pZl9jYW5jZWxlZDogaW50NjQsXG4gIHBheV9pZl9ub3RfY2FuY2VsZWQ6IGludDY0LFxuICBmZWVzX2NvbGxlY3RlZDogaW50NjRcbn0pO1xuXG52YXIgZ2xvYmFsX2JldHRpbmdfc3RhdGlzdGljcyA9IG5ldyBTZXJpYWxpemVyKCdnbG9iYWxfYmV0dGluZ19zdGF0aXN0aWNzJywge1xuICBpZDogaW1wbGVtZW50YXRpb25faWRfdHlwZSgnZ2xvYmFsX2JldHRpbmdfc3RhdGlzdGljcycpLFxuICBudW1iZXJfb2ZfYWN0aXZlX2V2ZW50czogdWludDMyLFxuICB0b3RhbF9hbW91bnRfc3Rha2VkOiBtYXAocHJvdG9jb2xfaWRfdHlwZSgnYXNzZXQnKSwgaW50NjQpXG59KTtcblxuLy8gZW9mIEJldHRpbmcgT2JqZWN0c1xuXG4vLyBDdXN0b20gVHlwZXNcblxudmFyIHN0ZWFsdGhfbWVtb19kYXRhID0gbmV3IFNlcmlhbGl6ZXIoJ3N0ZWFsdGhfbWVtb19kYXRhJywge1xuICBmcm9tOiBvcHRpb25hbChwdWJsaWNfa2V5KSxcbiAgYW1vdW50OiBhc3NldCxcbiAgYmxpbmRpbmdfZmFjdG9yOiBieXRlcygzMiksXG4gIGNvbW1pdG1lbnQ6IGJ5dGVzKDMzKSxcbiAgY2hlY2s6IHVpbnQzMlxufSk7XG4vLyB2YXIgc3RlYWx0aF9jb25maXJtYXRpb24gPSBuZXcgU2VyaWFsaXplcihcbi8vICAgICBcInN0ZWFsdGhfY29uZmlybWF0aW9uXCIsIHtcbi8vICAgICBvbmVfdGltZV9rZXk6IHB1YmxpY19rZXksXG4vLyAgICAgdG86IG9wdGlvbmFsKCBwdWJsaWNfa2V5ICksXG4vLyAgICAgZW5jcnlwdGVkX21lbW86IHN0ZWFsdGhfbWVtb19kYXRhXG4vLyB9KVxuXG5leHBvcnRzLm9wZXJhdGlvbiA9IG9wZXJhdGlvbjtcbmV4cG9ydHMudHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5saW1pdF9vcmRlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbGltaXRfb3JkZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMubGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGxpbWl0X29yZGVyX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmNhbGxfb3JkZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGNhbGxfb3JkZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuZmlsbF9vcmRlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBmaWxsX29yZGVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYWNjb3VudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYWNjb3VudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hY2NvdW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhY2NvdW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFjY291bnRfd2hpdGVsaXN0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFjY291bnRfd2hpdGVsaXN0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYWNjb3VudF91cGdyYWRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFjY291bnRfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYWNjb3VudF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hc3NldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFzc2V0X3VwZGF0ZV9iaXRhc3NldF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2Vyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hc3NldF9pc3N1ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF9pc3N1ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X3Jlc2VydmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfcmVzZXJ2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfZnVuZF9mZWVfcG9vbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hc3NldF9nbG9iYWxfc2V0dGxlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5hc3NldF9wdWJsaXNoX2ZlZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfcHVibGlzaF9mZWVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMud2l0bmVzc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gd2l0bmVzc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy53aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSB3aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnByb3Bvc2FsX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBwcm9wb3NhbF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5wcm9wb3NhbF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gcHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMucHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHByb3Bvc2FsX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHdpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHdpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdmVzdGluZ19iYWxhbmNlX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnZlc3RpbmdfYmFsYW5jZV93aXRoZHJhd19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXdfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy53b3JrZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHdvcmtlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5jdXN0b21fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFzc2VydF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJhbGFuY2VfY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmFsYW5jZV9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLm92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMudHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5ibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdHJhbnNmZXJfZnJvbV9ibGluZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X3NldHRsZV9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfc2V0dGxlX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X2NsYWltX2ZlZXNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYXNzZXRfdXBkYXRlX2RpdmlkZW5kX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGFzc2V0X3VwZGF0ZV9kaXZpZGVuZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmFzc2V0X2RpdmlkZW5kX2Rpc3RyaWJ1dGlvbl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBhc3NldF9kaXZpZGVuZF9kaXN0cmlidXRpb25fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5zcG9ydF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gc3BvcnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuc3BvcnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHNwb3J0X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmV2ZW50X2dyb3VwX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBldmVudF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5ldmVudF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXZlbnRfZ3JvdXBfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuZXZlbnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV2ZW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmV2ZW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBldmVudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmV0dGluZ19tYXJrZXRfcnVsZXNfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfcnVsZXNfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBiZXR0aW5nX21hcmtldF9ncm91cF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmV0dGluZ19tYXJrZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0X3BsYWNlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldF9wbGFjZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldHRpbmdfbWFya2V0X2dyb3VwX3Jlc29sdmVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfY2FuY2VsX3VubWF0Y2hlZF9iZXRzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldHRpbmdfbWFya2V0X2dyb3VwX2NhbmNlbF91bm1hdGNoZWRfYmV0c19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldF9tYXRjaGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldF9tYXRjaGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0X2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBiZXRfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0X2NhbmNlbGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldF9jYW5jZWxlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnRvdXJuYW1lbnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHRvdXJuYW1lbnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMudG91cm5hbWVudF9qb2luX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IHRvdXJuYW1lbnRfam9pbl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmdhbWVfbW92ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBnYW1lX21vdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy50b3VybmFtZW50X3BheW91dF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSB0b3VybmFtZW50X3BheW91dF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLnRvdXJuYW1lbnRfbGVhdmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gdG91cm5hbWVudF9sZWF2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X2dyb3VwX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBiZXR0aW5nX21hcmtldF9ncm91cF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gYmV0dGluZ19tYXJrZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycztcbmV4cG9ydHMuYmV0X2FkanVzdGVkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGJldF9hZGp1c3RlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnM7XG5leHBvcnRzLmZlZV9zY2hlZHVsZSA9IGZlZV9zY2hlZHVsZTtcbmV4cG9ydHMudm9pZF9yZXN1bHQgPSB2b2lkX3Jlc3VsdDtcbmV4cG9ydHMuYXNzZXQgPSBhc3NldDtcbmV4cG9ydHMucHJvY2Vzc2VkX3RyYW5zYWN0aW9uID0gcHJvY2Vzc2VkX3RyYW5zYWN0aW9uO1xuZXhwb3J0cy5zaWduZWRfYmxvY2sgPSBzaWduZWRfYmxvY2s7XG5leHBvcnRzLmJsb2NrX2hlYWRlciA9IGJsb2NrX2hlYWRlcjtcbmV4cG9ydHMuc2lnbmVkX2Jsb2NrX2hlYWRlciA9IHNpZ25lZF9ibG9ja19oZWFkZXI7XG5leHBvcnRzLm1lbW9fZGF0YSA9IG1lbW9fZGF0YTtcbmV4cG9ydHMudHJhbnNmZXIgPSB0cmFuc2ZlcjtcbmV4cG9ydHMubGltaXRfb3JkZXJfY3JlYXRlID0gbGltaXRfb3JkZXJfY3JlYXRlO1xuZXhwb3J0cy5saW1pdF9vcmRlcl9jYW5jZWwgPSBsaW1pdF9vcmRlcl9jYW5jZWw7XG5leHBvcnRzLmNhbGxfb3JkZXJfdXBkYXRlID0gY2FsbF9vcmRlcl91cGRhdGU7XG5leHBvcnRzLmZpbGxfb3JkZXIgPSBmaWxsX29yZGVyO1xuZXhwb3J0cy5hdXRob3JpdHkgPSBhdXRob3JpdHk7XG5leHBvcnRzLmFjY291bnRfb3B0aW9ucyA9IGFjY291bnRfb3B0aW9ucztcbmV4cG9ydHMuYWNjb3VudF9jcmVhdGUgPSBhY2NvdW50X2NyZWF0ZTtcbmV4cG9ydHMuYWNjb3VudF91cGRhdGUgPSBhY2NvdW50X3VwZGF0ZTtcbmV4cG9ydHMuYWNjb3VudF93aGl0ZWxpc3QgPSBhY2NvdW50X3doaXRlbGlzdDtcbmV4cG9ydHMuYWNjb3VudF91cGdyYWRlID0gYWNjb3VudF91cGdyYWRlO1xuZXhwb3J0cy5hY2NvdW50X3RyYW5zZmVyID0gYWNjb3VudF90cmFuc2ZlcjtcbmV4cG9ydHMucHJpY2UgPSBwcmljZTtcbmV4cG9ydHMuYXNzZXRfb3B0aW9ucyA9IGFzc2V0X29wdGlvbnM7XG5leHBvcnRzLmJpdGFzc2V0X29wdGlvbnMgPSBiaXRhc3NldF9vcHRpb25zO1xuZXhwb3J0cy5hc3NldF9jcmVhdGUgPSBhc3NldF9jcmVhdGU7XG5leHBvcnRzLmFzc2V0X3VwZGF0ZSA9IGFzc2V0X3VwZGF0ZTtcbmV4cG9ydHMuYXNzZXRfdXBkYXRlX2JpdGFzc2V0ID0gYXNzZXRfdXBkYXRlX2JpdGFzc2V0O1xuZXhwb3J0cy5hc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnMgPSBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnM7XG5leHBvcnRzLmFzc2V0X2lzc3VlID0gYXNzZXRfaXNzdWU7XG5leHBvcnRzLmFzc2V0X3Jlc2VydmUgPSBhc3NldF9yZXNlcnZlO1xuZXhwb3J0cy5hc3NldF9mdW5kX2ZlZV9wb29sID0gYXNzZXRfZnVuZF9mZWVfcG9vbDtcbmV4cG9ydHMuYXNzZXRfc2V0dGxlID0gYXNzZXRfc2V0dGxlO1xuZXhwb3J0cy5hc3NldF9nbG9iYWxfc2V0dGxlID0gYXNzZXRfZ2xvYmFsX3NldHRsZTtcbmV4cG9ydHMucHJpY2VfZmVlZCA9IHByaWNlX2ZlZWQ7XG5leHBvcnRzLmFzc2V0X3B1Ymxpc2hfZmVlZCA9IGFzc2V0X3B1Ymxpc2hfZmVlZDtcbmV4cG9ydHMud2l0bmVzc19jcmVhdGUgPSB3aXRuZXNzX2NyZWF0ZTtcbmV4cG9ydHMud2l0bmVzc191cGRhdGUgPSB3aXRuZXNzX3VwZGF0ZTtcbmV4cG9ydHMub3Bfd3JhcHBlciA9IG9wX3dyYXBwZXI7XG5leHBvcnRzLnByb3Bvc2FsX2NyZWF0ZSA9IHByb3Bvc2FsX2NyZWF0ZTtcbmV4cG9ydHMucHJvcG9zYWxfdXBkYXRlID0gcHJvcG9zYWxfdXBkYXRlO1xuZXhwb3J0cy5wcm9wb3NhbF9kZWxldGUgPSBwcm9wb3NhbF9kZWxldGU7XG5leHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlID0gd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGU7XG5leHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlID0gd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGU7XG5leHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW0gPSB3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltO1xuZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSA9IHdpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlO1xuZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX2NyZWF0ZSA9IGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlO1xuZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZSA9IGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlO1xuZXhwb3J0cy5jaGFpbl9wYXJhbWV0ZXJzID0gY2hhaW5fcGFyYW1ldGVycztcbmV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnMgPSBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVycztcbmV4cG9ydHMubGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gbGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyO1xuZXhwb3J0cy5jZGRfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXIgPSBjZGRfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXI7XG5leHBvcnRzLnZlc3RpbmdfYmFsYW5jZV9jcmVhdGUgPSB2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlO1xuZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXcgPSB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXc7XG5leHBvcnRzLnJlZnVuZF93b3JrZXJfaW5pdGlhbGl6ZXIgPSByZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyO1xuZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd29ya2VyX2luaXRpYWxpemVyID0gdmVzdGluZ19iYWxhbmNlX3dvcmtlcl9pbml0aWFsaXplcjtcbmV4cG9ydHMuYnVybl93b3JrZXJfaW5pdGlhbGl6ZXIgPSBidXJuX3dvcmtlcl9pbml0aWFsaXplcjtcbmV4cG9ydHMud29ya2VyX2NyZWF0ZSA9IHdvcmtlcl9jcmVhdGU7XG5leHBvcnRzLmN1c3RvbSA9IGN1c3RvbTtcbmV4cG9ydHMuYWNjb3VudF9uYW1lX2VxX2xpdF9wcmVkaWNhdGUgPSBhY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZTtcbmV4cG9ydHMuYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUgPSBhc3NldF9zeW1ib2xfZXFfbGl0X3ByZWRpY2F0ZTtcbmV4cG9ydHMuYmxvY2tfaWRfcHJlZGljYXRlID0gYmxvY2tfaWRfcHJlZGljYXRlO1xuZXhwb3J0cy5hc3NlcnQgPSBhc3NlcnQ7XG5leHBvcnRzLmJhbGFuY2VfY2xhaW0gPSBiYWxhbmNlX2NsYWltO1xuZXhwb3J0cy5vdmVycmlkZV90cmFuc2ZlciA9IG92ZXJyaWRlX3RyYW5zZmVyO1xuZXhwb3J0cy5zdGVhbHRoX2NvbmZpcm1hdGlvbiA9IHN0ZWFsdGhfY29uZmlybWF0aW9uO1xuZXhwb3J0cy5ibGluZF9vdXRwdXQgPSBibGluZF9vdXRwdXQ7XG5leHBvcnRzLnRyYW5zZmVyX3RvX2JsaW5kID0gdHJhbnNmZXJfdG9fYmxpbmQ7XG5leHBvcnRzLmJsaW5kX2lucHV0ID0gYmxpbmRfaW5wdXQ7XG5leHBvcnRzLmJsaW5kX3RyYW5zZmVyID0gYmxpbmRfdHJhbnNmZXI7XG5leHBvcnRzLnRyYW5zZmVyX2Zyb21fYmxpbmQgPSB0cmFuc2Zlcl9mcm9tX2JsaW5kO1xuZXhwb3J0cy5hc3NldF9zZXR0bGVfY2FuY2VsID0gYXNzZXRfc2V0dGxlX2NhbmNlbDtcbmV4cG9ydHMuYXNzZXRfY2xhaW1fZmVlcyA9IGFzc2V0X2NsYWltX2ZlZXM7XG5leHBvcnRzLmZiYV9kaXN0cmlidXRlID0gZmJhX2Rpc3RyaWJ1dGU7XG5leHBvcnRzLnJvY2tfcGFwZXJfc2Npc3NvcnNfZ2FtZV9vcHRpb25zID0gcm9ja19wYXBlcl9zY2lzc29yc19nYW1lX29wdGlvbnM7XG5leHBvcnRzLnRvdXJuYW1lbnRfb3B0aW9ucyA9IHRvdXJuYW1lbnRfb3B0aW9ucztcbmV4cG9ydHMudG91cm5hbWVudF9jcmVhdGUgPSB0b3VybmFtZW50X2NyZWF0ZTtcbmV4cG9ydHMudG91cm5hbWVudF9qb2luID0gdG91cm5hbWVudF9qb2luO1xuZXhwb3J0cy5yb2NrX3BhcGVyX3NjaXNzb3JzX2dlc3R1cmUgPSByb2NrX3BhcGVyX3NjaXNzb3JzX2dlc3R1cmU7XG5leHBvcnRzLnJvY2tfcGFwZXJfc2Npc3NvcnNfdGhyb3dfY29tbWl0ID0gcm9ja19wYXBlcl9zY2lzc29yc190aHJvd19jb21taXQ7XG5leHBvcnRzLnJvY2tfcGFwZXJfc2Npc3NvcnNfdGhyb3dfcmV2ZWFsID0gcm9ja19wYXBlcl9zY2lzc29yc190aHJvd19yZXZlYWw7XG5leHBvcnRzLmdhbWVfbW92ZSA9IGdhbWVfbW92ZTtcbmV4cG9ydHMuZGl2aWRlbmRfYXNzZXRfb3B0aW9ucyA9IGRpdmlkZW5kX2Fzc2V0X29wdGlvbnM7XG5leHBvcnRzLmFzc2V0X3VwZGF0ZV9kaXZpZGVuZCA9IGFzc2V0X3VwZGF0ZV9kaXZpZGVuZDtcbmV4cG9ydHMuYXNzZXRfZGl2aWRlbmRfZGlzdHJpYnV0aW9uID0gYXNzZXRfZGl2aWRlbmRfZGlzdHJpYnV0aW9uO1xuZXhwb3J0cy5zcG9ydF9jcmVhdGUgPSBzcG9ydF9jcmVhdGU7XG5leHBvcnRzLnNwb3J0X3VwZGF0ZSA9IHNwb3J0X3VwZGF0ZTtcbmV4cG9ydHMuZXZlbnRfZ3JvdXBfY3JlYXRlID0gZXZlbnRfZ3JvdXBfY3JlYXRlO1xuZXhwb3J0cy5ldmVudF9ncm91cF91cGRhdGUgPSBldmVudF9ncm91cF91cGRhdGU7XG5leHBvcnRzLmV2ZW50X2NyZWF0ZSA9IGV2ZW50X2NyZWF0ZTtcbmV4cG9ydHMuZXZlbnRfdXBkYXRlID0gZXZlbnRfdXBkYXRlO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGUgPSBiZXR0aW5nX21hcmtldF9ydWxlc19jcmVhdGU7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZSA9IGJldHRpbmdfbWFya2V0X3J1bGVzX3VwZGF0ZTtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfY3JlYXRlID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfY3JlYXRlO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9jcmVhdGUgPSBiZXR0aW5nX21hcmtldF9jcmVhdGU7XG5leHBvcnRzLmJldF90eXBlID0gYmV0X3R5cGU7XG5leHBvcnRzLmJldF9wbGFjZSA9IGJldF9wbGFjZTtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfcmVzb2x1dGlvbl90eXBlID0gYmV0dGluZ19tYXJrZXRfcmVzb2x1dGlvbl90eXBlO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZTtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfcmVzb2x2ZWQgPSBiZXR0aW5nX21hcmtldF9ncm91cF9yZXNvbHZlZDtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfY2FuY2VsX3VubWF0Y2hlZF9iZXRzID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfY2FuY2VsX3VubWF0Y2hlZF9iZXRzO1xuZXhwb3J0cy5iZXRfbWF0Y2hlZCA9IGJldF9tYXRjaGVkO1xuZXhwb3J0cy5iZXRfY2FuY2VsID0gYmV0X2NhbmNlbDtcbmV4cG9ydHMuYmV0X2NhbmNlbGVkID0gYmV0X2NhbmNlbGVkO1xuZXhwb3J0cy5wYXlvdXRfdHlwZSA9IHBheW91dF90eXBlO1xuZXhwb3J0cy50b3VybmFtZW50X3BheW91dCA9IHRvdXJuYW1lbnRfcGF5b3V0O1xuZXhwb3J0cy50b3VybmFtZW50X2xlYXZlID0gdG91cm5hbWVudF9sZWF2ZTtcbmV4cG9ydHMuYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlID0gYmV0dGluZ19tYXJrZXRfZ3JvdXBfdXBkYXRlO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF91cGRhdGUgPSBiZXR0aW5nX21hcmtldF91cGRhdGU7XG5leHBvcnRzLmJldF9hZGp1c3RlZCA9IGJldF9hZGp1c3RlZDtcbmV4cG9ydHMudHJhbnNhY3Rpb24gPSB0cmFuc2FjdGlvbjtcbmV4cG9ydHMuc2lnbmVkX3RyYW5zYWN0aW9uID0gc2lnbmVkX3RyYW5zYWN0aW9uO1xuZXhwb3J0cy5zcG9ydCA9IHNwb3J0O1xuZXhwb3J0cy5ldmVudF9ncm91cCA9IGV2ZW50X2dyb3VwO1xuZXhwb3J0cy5ldmVudCA9IGV2ZW50O1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ydWxlcyA9IGJldHRpbmdfbWFya2V0X3J1bGVzO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldF9ncm91cCA9IGJldHRpbmdfbWFya2V0X2dyb3VwO1xuZXhwb3J0cy5iZXR0aW5nX21hcmtldCA9IGJldHRpbmdfbWFya2V0O1xuZXhwb3J0cy5iZXQgPSBiZXQ7XG5leHBvcnRzLmJldHRpbmdfbWFya2V0X3Bvc2l0aW9uID0gYmV0dGluZ19tYXJrZXRfcG9zaXRpb247XG5leHBvcnRzLmdsb2JhbF9iZXR0aW5nX3N0YXRpc3RpY3MgPSBnbG9iYWxfYmV0dGluZ19zdGF0aXN0aWNzO1xuZXhwb3J0cy5zdGVhbHRoX21lbW9fZGF0YSA9IHN0ZWFsdGhfbWVtb19kYXRhOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9ieXRlYnVmZmVyID0gcmVxdWlyZSgnYnl0ZWJ1ZmZlcicpO1xuXG52YXIgX2J5dGVidWZmZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYnl0ZWJ1ZmZlcik7XG5cbnZhciBfZXJyb3Jfd2l0aF9jYXVzZSA9IHJlcXVpcmUoJy4vZXJyb3Jfd2l0aF9jYXVzZScpO1xuXG52YXIgX2Vycm9yX3dpdGhfY2F1c2UyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZXJyb3Jfd2l0aF9jYXVzZSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBIRVhfRFVNUCA9IHByb2Nlc3MuZW52Lm5wbV9jb25maWdfX2dyYXBoZW5lX3NlcmlhbGl6ZXJfaGV4X2R1bXA7XG5cbnZhciBTZXJpYWxpemVyID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTZXJpYWxpemVyKG9wZXJhdGlvbl9uYW1lLCB0eXBlcykge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTZXJpYWxpemVyKTtcblxuICAgIHRoaXMub3BlcmF0aW9uX25hbWUgPSBvcGVyYXRpb25fbmFtZTtcbiAgICB0aGlzLnR5cGVzID0gdHlwZXM7XG5cbiAgICBpZiAodGhpcy50eXBlcykge1xuICAgICAgdGhpcy5rZXlzID0gT2JqZWN0LmtleXModGhpcy50eXBlcyk7XG4gICAgfVxuXG4gICAgU2VyaWFsaXplci5wcmludERlYnVnID0gdHJ1ZTtcbiAgfVxuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLmZyb21CeXRlQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICB2YXIgZmllbGQgPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBpdGVyYWJsZSA9IHRoaXMua2V5cztcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVyYWJsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBmaWVsZCA9IGl0ZXJhYmxlW2ldO1xuICAgICAgICB2YXIgdHlwZSA9IHRoaXMudHlwZXNbZmllbGRdO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKEhFWF9EVU1QKSB7XG4gICAgICAgICAgICBpZiAodHlwZS5vcGVyYXRpb25fbmFtZSkge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHR5cGUub3BlcmF0aW9uX25hbWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdmFyIG8xID0gYi5vZmZzZXQ7XG4gICAgICAgICAgICAgIHR5cGUuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgICAgICAgIHZhciBvMiA9IGIub2Zmc2V0O1xuICAgICAgICAgICAgICBiLm9mZnNldCA9IG8xO1xuICAgICAgICAgICAgICAvLyBiLnJlc2V0KClcbiAgICAgICAgICAgICAgdmFyIF9iID0gYi5jb3B5KG8xLCBvMik7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IodGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgJ1xcdCcsIF9iLnRvSGV4KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIG9iamVjdFtmaWVsZF0gPSB0eXBlLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKFNlcmlhbGl6ZXIucHJpbnREZWJ1Zykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgcmVhZGluZyAnICsgdGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgJyBpbiBkYXRhOicpO1xuICAgICAgICAgICAgYi5wcmludERlYnVnKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBfZXJyb3Jfd2l0aF9jYXVzZTIuZGVmYXVsdC50aHJvdyh0aGlzLm9wZXJhdGlvbl9uYW1lICsgJy4nICsgZmllbGQsIGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9O1xuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLmFwcGVuZEJ5dGVCdWZmZXIgPSBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgIHZhciBmaWVsZCA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy5rZXlzO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZpZWxkID0gaXRlcmFibGVbaV07XG4gICAgICAgIHZhciB0eXBlID0gdGhpcy50eXBlc1tmaWVsZF07XG4gICAgICAgIHR5cGUuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3RbZmllbGRdKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgX2Vycm9yX3dpdGhfY2F1c2UyLmRlZmF1bHQudGhyb3codGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgJyA9ICcgKyBKU09OLnN0cmluZ2lmeShvYmplY3RbZmllbGRdKSwgZXJyb3IpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBjaXJjdWxhciByZWZcbiAgICAgICAgX2Vycm9yX3dpdGhfY2F1c2UyLmRlZmF1bHQudGhyb3codGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgJyA9ICcgKyBvYmplY3RbZmllbGRdLCBlcnJvcik7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KHNlcmlhbGl6ZWRfb2JqZWN0KSB7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIHZhciBmaWVsZCA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy5rZXlzO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZpZWxkID0gaXRlcmFibGVbaV07XG4gICAgICAgIHZhciB0eXBlID0gdGhpcy50eXBlc1tmaWVsZF07XG4gICAgICAgIHZhciB2YWx1ZSA9IHNlcmlhbGl6ZWRfb2JqZWN0W2ZpZWxkXTtcbiAgICAgICAgLy8gREVCVUcgdmFsdWUgPSB2YWx1ZS5yZXNvbHZlIGlmIHZhbHVlLnJlc29sdmVcbiAgICAgICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiB2YWx1ZScsZmllbGQsdmFsdWUpXG4gICAgICAgIHZhciBvYmplY3QgPSB0eXBlLmZyb21PYmplY3QodmFsdWUpO1xuICAgICAgICByZXN1bHRbZmllbGRdID0gb2JqZWN0O1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBfZXJyb3Jfd2l0aF9jYXVzZTIuZGVmYXVsdC50aHJvdyh0aGlzLm9wZXJhdGlvbl9uYW1lICsgJy4nICsgZmllbGQsIGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8qKlxuICAgICAgICBAYXJnIHtib29sZWFufSBbZGVidWcudXNlX2RlZmF1bHQgPSBmYWxzZV0gLSBtb3JlIHRlbXBsYXRlIGZyaWVuZGx5XG4gICAgICAgIEBhcmcge2Jvb2xlYW59IFtkZWJ1Zy5hbm5vdGF0ZSA9IGZhbHNlXSAtIGFkZCB1c2VyLWZyaWVuZGx5IGluZm9ybWF0aW9uXG4gICAgKi9cblxuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QoKSB7XG4gICAgdmFyIHNlcmlhbGl6ZWRfb2JqZWN0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB7fTtcbiAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHsgdXNlX2RlZmF1bHQ6IGZhbHNlLCBhbm5vdGF0ZTogZmFsc2UgfTtcblxuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICB2YXIgZmllbGQgPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlmICghdGhpcy50eXBlcykge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICB2YXIgaXRlcmFibGUgPSB0aGlzLmtleXM7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaXRlcmFibGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZmllbGQgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgdmFyIHR5cGUgPSB0aGlzLnR5cGVzW2ZpZWxkXTtcbiAgICAgICAgdmFyIG9iamVjdCA9IHR5cGUudG9PYmplY3QodHlwZW9mIHNlcmlhbGl6ZWRfb2JqZWN0ICE9PSAndW5kZWZpbmVkJyAmJiBzZXJpYWxpemVkX29iamVjdCAhPT0gbnVsbCA/IHNlcmlhbGl6ZWRfb2JqZWN0W2ZpZWxkXSA6IHVuZGVmaW5lZCwgZGVidWcpO1xuICAgICAgICByZXN1bHRbZmllbGRdID0gb2JqZWN0O1xuXG4gICAgICAgIGlmIChIRVhfRFVNUCkge1xuICAgICAgICAgIHZhciBiID0gbmV3IF9ieXRlYnVmZmVyMi5kZWZhdWx0KF9ieXRlYnVmZmVyMi5kZWZhdWx0LkRFRkFVTFRfQ0FQQUNJVFksIF9ieXRlYnVmZmVyMi5kZWZhdWx0LkxJVFRMRV9FTkRJQU4pO1xuICAgICAgICAgIHR5cGUuYXBwZW5kQnl0ZUJ1ZmZlcihiLCB0eXBlb2Ygc2VyaWFsaXplZF9vYmplY3QgIT09ICd1bmRlZmluZWQnICYmIHNlcmlhbGl6ZWRfb2JqZWN0ICE9PSBudWxsID8gc2VyaWFsaXplZF9vYmplY3RbZmllbGRdIDogdW5kZWZpbmVkKTtcbiAgICAgICAgICBiID0gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKHRoaXMub3BlcmF0aW9uX25hbWUgKyAnLicgKyBmaWVsZCwgYi50b0hleCgpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBfZXJyb3Jfd2l0aF9jYXVzZTIuZGVmYXVsdC50aHJvdyh0aGlzLm9wZXJhdGlvbl9uYW1lICsgJy4nICsgZmllbGQsIGVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8qKiBTb3J0IGJ5IHRoZSBmaXJzdCBlbGVtZW50IGluIGEgb3BlcmF0aW9uICovXG5cblxuICBTZXJpYWxpemVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG4gICAgdmFyIGZpcnN0X2tleSA9IHRoaXMua2V5c1swXTtcbiAgICB2YXIgZmlyc3RfdHlwZSA9IHRoaXMudHlwZXNbZmlyc3Rfa2V5XTtcblxuICAgIHZhciB2YWxBID0gYVtmaXJzdF9rZXldO1xuICAgIHZhciB2YWxCID0gYltmaXJzdF9rZXldO1xuXG4gICAgaWYgKGZpcnN0X3R5cGUuY29tcGFyZSkge1xuICAgICAgcmV0dXJuIGZpcnN0X3R5cGUuY29tcGFyZSh2YWxBLCB2YWxCKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbEEgPT09ICdudW1iZXInICYmIHR5cGVvZiB2YWxCID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIHZhbEEgLSB2YWxCO1xuICAgIH1cblxuICAgIHZhciBlbmNvZGluZyA9IHZvaWQgMDtcblxuICAgIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsQSkgJiYgQnVmZmVyLmlzQnVmZmVyKHZhbEIpKSB7XG4gICAgICAvLyBBIGJpbmFyeSBzdHJpbmcgY29tcGFyZSBkb2VzIG5vdCB3b3JrLiAgSWYgbG9jYWxlQ29tcGFyZSBpcyB3ZWxsIHN1cHBvcnRlZCB0aGF0IGNvdWxkXG4gICAgICAvLyByZXBsYWNlIEhFWC4gIFBlcmZvcm1hbmFuY2UgaXMgdmVyeSBnb29kIHNvIGNvbXBhcmluZyBIRVggd29ya3MuXG4gICAgICBlbmNvZGluZyA9ICdoZXgnO1xuICAgIH1cblxuICAgIHZhciBzdHJBID0gdmFsQS50b1N0cmluZyhlbmNvZGluZyk7XG4gICAgdmFyIHN0ckIgPSB2YWxCLnRvU3RyaW5nKGVuY29kaW5nKTtcblxuICAgIHZhciByZXN1bHQgPSAwO1xuXG4gICAgaWYgKHN0ckEgPiBzdHJCKSB7XG4gICAgICByZXN1bHQgPSAxO1xuICAgIH1cblxuICAgIGlmIChzdHJBIDwgc3RyQikge1xuICAgICAgcmVzdWx0ID0gLTE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyA8aGVscGVyX2Z1bmN0aW9ucz5cblxuICBTZXJpYWxpemVyLnByb3RvdHlwZS5mcm9tSGV4ID0gZnVuY3Rpb24gZnJvbUhleChoZXgpIHtcbiAgICB2YXIgYiA9IF9ieXRlYnVmZmVyMi5kZWZhdWx0LmZyb21IZXgoaGV4LCBfYnl0ZWJ1ZmZlcjIuZGVmYXVsdC5MSVRUTEVfRU5ESUFOKTtcbiAgICByZXR1cm4gdGhpcy5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgfTtcblxuICBTZXJpYWxpemVyLnByb3RvdHlwZS5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICB2YXIgYiA9IF9ieXRlYnVmZmVyMi5kZWZhdWx0LmZyb21CaW5hcnkoYnVmZmVyLnRvU3RyaW5nKCdiaW5hcnknKSwgX2J5dGVidWZmZXIyLmRlZmF1bHQuTElUVExFX0VORElBTik7XG4gICAgcmV0dXJuIHRoaXMuZnJvbUJ5dGVCdWZmZXIoYik7XG4gIH07XG5cbiAgU2VyaWFsaXplci5wcm90b3R5cGUudG9IZXggPSBmdW5jdGlvbiB0b0hleChvYmplY3QpIHtcbiAgICAvLyByZXR1cm4gdGhpcy50b0J1ZmZlcihvYmplY3QpLnRvU3RyaW5nKFwiaGV4XCIpXG4gICAgdmFyIGIgPSB0aGlzLnRvQnl0ZUJ1ZmZlcihvYmplY3QpO1xuICAgIHJldHVybiBiLnRvSGV4KCk7XG4gIH07XG5cbiAgU2VyaWFsaXplci5wcm90b3R5cGUudG9CeXRlQnVmZmVyID0gZnVuY3Rpb24gdG9CeXRlQnVmZmVyKG9iamVjdCkge1xuICAgIHZhciBiID0gbmV3IF9ieXRlYnVmZmVyMi5kZWZhdWx0KF9ieXRlYnVmZmVyMi5kZWZhdWx0LkRFRkFVTFRfQ0FQQUNJVFksIF9ieXRlYnVmZmVyMi5kZWZhdWx0LkxJVFRMRV9FTkRJQU4pO1xuICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpO1xuICAgIHJldHVybiBiLmNvcHkoMCwgYi5vZmZzZXQpO1xuICB9O1xuXG4gIFNlcmlhbGl6ZXIucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gdG9CdWZmZXIob2JqZWN0KSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHRoaXMudG9CeXRlQnVmZmVyKG9iamVjdCkudG9CaW5hcnkoKSwgJ2JpbmFyeScpO1xuICB9O1xuXG4gIHJldHVybiBTZXJpYWxpemVyO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBTZXJpYWxpemVyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLmRlZmF1bHQgPSB0ZW1wbGF0ZTtcbi8qKiBDb25zb2xlIHByaW50IGFueSB0cmFuc2FjdGlvbiBvYmplY3Qgd2l0aCB6ZXJvIGRlZmF1bHQgdmFsdWVzLiAqL1xuZnVuY3Rpb24gdGVtcGxhdGUob3ApIHtcbiAgdmFyIG9iamVjdCA9IG9wLnRvT2JqZWN0KHVuZGVmaW5lZCwgeyB1c2VfZGVmYXVsdDogdHJ1ZSwgYW5ub3RhdGU6IHRydWUgfSk7XG5cbiAgLy8gdmlzdWFsICh3aXRoIGRlc2NyaXB0aW9ucylcbiAgY29uc29sZS5lcnJvcihKU09OLnN0cmluZ2lmeShvYmplY3QsIG51bGwsIDQpKTtcblxuICAvLyB1c2FibGUgaW4gYSBjb3B5LXBhc3RlXG5cbiAgb2JqZWN0ID0gb3AudG9PYmplY3QodW5kZWZpbmVkLCB7IHVzZV9kZWZhdWx0OiB0cnVlLCBhbm5vdGF0ZTogZmFsc2UgfSk7XG5cbiAgLy8gY29weS1wYXN0ZSBvbmUtbGluZWVyXG4gIGNvbnNvbGUuZXJyb3IoSlNPTi5zdHJpbmdpZnkob2JqZWN0KSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9OyAvLyBMb3ctbGV2ZWwgdHlwZXMgdGhhdCBtYWtlIHVwIG9wZXJhdGlvbnNcblxudmFyIF9wZWVycGxheXNqc1dzID0gcmVxdWlyZSgncGVlcnBsYXlzanMtd3MnKTtcblxudmFyIF9TZXJpYWxpemVyVmFsaWRhdGlvbiA9IHJlcXVpcmUoJy4vU2VyaWFsaXplclZhbGlkYXRpb24nKTtcblxudmFyIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TZXJpYWxpemVyVmFsaWRhdGlvbik7XG5cbnZhciBfRmFzdFBhcnNlciA9IHJlcXVpcmUoJy4vRmFzdFBhcnNlcicpO1xuXG52YXIgX0Zhc3RQYXJzZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfRmFzdFBhcnNlcik7XG5cbnZhciBfQ2hhaW5UeXBlcyA9IHJlcXVpcmUoJy4uLy4uL2NoYWluL3NyYy9DaGFpblR5cGVzJyk7XG5cbnZhciBfQ2hhaW5UeXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpblR5cGVzKTtcblxudmFyIF9PYmplY3RJZCA9IHJlcXVpcmUoJy4uLy4uL2NoYWluL3NyYy9PYmplY3RJZCcpO1xuXG52YXIgX09iamVjdElkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX09iamVjdElkKTtcblxudmFyIF9lY2MgPSByZXF1aXJlKCcuLi8uLi9lY2MnKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIE1JTl9TSUdORURfMzIgPSAtMSAqIE1hdGgucG93KDIsIDMxKTtcbnZhciBNQVhfU0lHTkVEXzMyID0gTWF0aC5wb3coMiwgMzEpIC0gMTtcblxudmFyIEhFWF9EVU1QID0gcHJvY2Vzcy5lbnYubnBtX2NvbmZpZ19fZ3JhcGhlbmVfc2VyaWFsaXplcl9oZXhfZHVtcDtcblxudmFyIHN0ckNtcCA9IGZ1bmN0aW9uIHN0ckNtcChhLCBiKSB7XG4gIHZhciByZXN1bHQgPSAwO1xuXG4gIGlmIChhID4gYikge1xuICAgIHJlc3VsdCA9IDE7XG4gIH1cblxuICBpZiAoYSA8IGIpIHtcbiAgICByZXN1bHQgPSAtMTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG52YXIgZmlyc3RFbCA9IGZ1bmN0aW9uIGZpcnN0RWwoZWwpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoZWwpID8gZWxbMF0gOiBlbDtcbn07XG5cbnZhciBzb3J0T3BlcmF0aW9uID0gZnVuY3Rpb24gc29ydE9wZXJhdGlvbihhcnJheSwgc3Rfb3BlcmF0aW9uKSB7XG4gIGlmICghc3Rfb3BlcmF0aW9uLm5vc29ydCkge1xuICAgIC8vIElmIHRoZSBvcGVyYXRpb24gaGFzIGl0cyBvd24gY29tcGFyZSBmdW5jdGlvbi5cbiAgICBpZiAoc3Rfb3BlcmF0aW9uLmNvbXBhcmUpIHtcbiAgICAgIHJldHVybiBhcnJheS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBzdF9vcGVyYXRpb24uY29tcGFyZShmaXJzdEVsKGEpLCBmaXJzdEVsKGIpKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBhcnJheS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICB2YXIgYUZpcnN0ID0gZmlyc3RFbChhKTtcbiAgICAgIHZhciBiRmlyc3QgPSBmaXJzdEVsKGIpO1xuXG4gICAgICAvLyBJZiBib3RoIG9mIHRoZSBmaXJzdCBlbGVtZW50cyBhcmUgbnVtYmVycy5cbiAgICAgIGlmICh0eXBlb2YgYUZpcnN0ID09PSAnbnVtYmVyJyAmJiB0eXBlb2YgYkZpcnN0ID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gYUZpcnN0IC0gYkZpcnN0O1xuICAgICAgfVxuXG4gICAgICAvLyBJZiB0aGV5IGFyZSBib3RoIGJ1ZmZlcnMuXG4gICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKGFGaXJzdCkgJiYgQnVmZmVyLmlzQnVmZmVyKGJGaXJzdCkpIHtcbiAgICAgICAgcmV0dXJuIHN0ckNtcChhRmlyc3QudG9TdHJpbmcoJ2hleCcpLCBiRmlyc3QudG9TdHJpbmcoJ2hleCcpKTtcbiAgICAgIH1cblxuICAgICAgLy8gT3RoZXJ3aXNlXG4gICAgICByZXR1cm4gc3RyQ21wKGFGaXJzdC50b1N0cmluZygpLCBiRmlyc3QudG9TdHJpbmcoKSk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gYXJyYXk7XG59O1xuXG52YXIgVHlwZXMgPSB7fTtcblxuVHlwZXMudWludDggPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIGIucmVhZFVpbnQ4KCk7XG4gIH0sXG4gIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZiwgb2JqZWN0LCAndWludDggJyArIG9iamVjdCk7XG4gICAgYi53cml0ZVVpbnQ4KG9iamVjdCk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZiwgb2JqZWN0LCAndWludDggJyArIG9iamVjdCk7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmYsIG9iamVjdCwgJ3VpbnQ4ICcgKyBvYmplY3QpO1xuICAgIHJldHVybiBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMudWludDE2ID0ge1xuICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHJldHVybiBiLnJlYWRVaW50MTYoKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZSgwLCAweGZmZmYsIG9iamVjdCwgJ3VpbnQxNiAnICsgb2JqZWN0KTtcbiAgICBiLndyaXRlVWludDE2KG9iamVjdCk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmLCBvYmplY3QsICd1aW50MTYgJyArIG9iamVjdCk7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmZmZiwgb2JqZWN0LCAndWludDE2ICcgKyBvYmplY3QpO1xuICAgIHJldHVybiBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMudWludDMyID0ge1xuICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHJldHVybiBiLnJlYWRVaW50MzIoKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZSgwLCAweGZmZmZmZmZmLCBvYmplY3QsICd1aW50MzIgJyArIG9iamVjdCk7XG4gICAgYi53cml0ZVVpbnQzMihvYmplY3QpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmZmZmZmZmYsIG9iamVjdCwgJ3VpbnQzMiAnICsgb2JqZWN0KTtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmZmZmZiwgb2JqZWN0LCAndWludDMyICcgKyBvYmplY3QpO1xuICAgIHJldHVybiBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMudmFyaW50MzIgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIGIucmVhZFZhcmludDMyKCk7XG4gIH0sXG4gIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoTUlOX1NJR05FRF8zMiwgTUFYX1NJR05FRF8zMiwgb2JqZWN0LCAndWludDMyICcgKyBvYmplY3QpO1xuICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKE1JTl9TSUdORURfMzIsIE1BWF9TSUdORURfMzIsIG9iamVjdCwgJ3VpbnQzMiAnICsgb2JqZWN0KTtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoTUlOX1NJR05FRF8zMiwgTUFYX1NJR05FRF8zMiwgb2JqZWN0LCAndWludDMyICcgKyBvYmplY3QpO1xuICAgIHJldHVybiBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMuaW50NjQgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIGIucmVhZEludDY0KCk7XG4gIH0sXG4gIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgYi53cml0ZUludDY0KF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC50b19sb25nKG9iamVjdCkpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgIHJldHVybiBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudG9fbG9uZyhvYmplY3QpO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuICcwJztcbiAgICB9XG5cbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICByZXR1cm4gX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnRvX2xvbmcob2JqZWN0KS50b1N0cmluZygpO1xuICB9XG59O1xuXG5UeXBlcy51aW50NjQgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIGIucmVhZFVpbnQ2NCgpO1xuICB9LFxuICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgIGIud3JpdGVVaW50NjQoX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnRvX3Vsb25nKF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC51bnNpZ25lZChvYmplY3QpKSk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC50b191bG9uZyhfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudW5zaWduZWQob2JqZWN0KSk7XG4gIH0sXG4gIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gJzAnO1xuICAgIH1cblxuICAgIHJldHVybiBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudG9fdWxvbmcob2JqZWN0KS50b1N0cmluZygpO1xuICB9XG59O1xuXG5UeXBlcy5zdHJpbmcgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgdmFyIGJfY29weSA9IHZvaWQgMDtcbiAgICB2YXIgbGVuID0gYi5yZWFkVmFyaW50MzIoKTtcbiAgICBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgbGVuKTtcbiAgICBiLnNraXAobGVuKTtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oYl9jb3B5LnRvQmluYXJ5KCksICdiaW5hcnknKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICBiLndyaXRlVmFyaW50MzIob2JqZWN0Lmxlbmd0aCk7XG4gICAgYi5hcHBlbmQob2JqZWN0LnRvU3RyaW5nKCdiaW5hcnknKSwgJ2JpbmFyeScpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShvYmplY3QpO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIHJldHVybiBvYmplY3QudG9TdHJpbmcoKTtcbiAgfVxufTtcblxuVHlwZXMuYnl0ZXMgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICB2YXIgYnl0ZXMgPSB7XG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgIGlmIChzaXplID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIF9iX2NvcHkgPSB2b2lkIDA7XG4gICAgICAgIHZhciBsZW4gPSBiLnJlYWRWYXJpbnQzMigpO1xuICAgICAgICBfYl9jb3B5ID0gYi5jb3B5KGIub2Zmc2V0LCBiLm9mZnNldCArIGxlbik7XG4gICAgICAgIGIuc2tpcChsZW4pO1xuICAgICAgICByZXR1cm4gQnVmZmVyLmZyb20oX2JfY29weS50b0JpbmFyeSgpLCAnYmluYXJ5Jyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgc2l6ZSk7XG4gICAgICBiLnNraXAoc2l6ZSk7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20oYl9jb3B5LnRvQmluYXJ5KCksICdiaW5hcnknKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgICAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG9iamVjdCA9IEJ1ZmZlci5mcm9tKG9iamVjdCwgJ2hleCcpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QubGVuZ3RoKTtcbiAgICAgIH1cblxuICAgICAgYi5hcHBlbmQob2JqZWN0LnRvU3RyaW5nKCdiaW5hcnknKSwgJ2JpbmFyeScpO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKG9iamVjdCwgJ2hleCcpO1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBuZXcgQXJyYXkoc2l6ZSkuam9pbignMDAnKTtcbiAgICAgIH1cblxuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGJ5dGVzO1xufTtcblxuVHlwZXMuYm9vbCA9IHtcbiAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICByZXR1cm4gYi5yZWFkVWludDgoKSA9PT0gMTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAvLyBzdXBwb3J0cyBib29sZWFuIG9yIGludGVnZXJcbiAgICBiLndyaXRlVWludDgoSlNPTi5wYXJzZShvYmplY3QpID8gMSA6IDApO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiAhIUpTT04ucGFyc2Uob2JqZWN0KTtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gISFKU09OLnBhcnNlKG9iamVjdCk7XG4gIH1cbn07XG5cblR5cGVzLnZvaWQgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJyh2b2lkKSB1bmRlZmluZWQgdHlwZScpO1xuICB9LFxuICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignKHZvaWQpIHVuZGVmaW5lZCB0eXBlJyk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3QoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCcodm9pZCkgdW5kZWZpbmVkIHR5cGUnKTtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCcodm9pZCkgdW5kZWZpbmVkIHR5cGUnKTtcbiAgfVxufTtcblxuVHlwZXMuYXJyYXkgPSBmdW5jdGlvbiAoc3Rfb3BlcmF0aW9uKSB7XG4gIHZhciBhcnJheSA9IHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgdmFyIHNpemUgPSBiLnJlYWRWYXJpbnQzMigpO1xuXG4gICAgICBpZiAoSEVYX0RVTVApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ3ZhcmludDMyIHNpemUgPSAnICsgc2l6ZS50b1N0cmluZygxNikpO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBzaXplID4gMCA/IGkgPCBzaXplIDogaSA+IHNpemU7IHNpemUgPiAwID8gaSsrIDogaSsrKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzb3J0T3BlcmF0aW9uKHJlc3VsdCwgc3Rfb3BlcmF0aW9uKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuICAgICAgYi53cml0ZVZhcmludDMyKG9iamVjdC5sZW5ndGgpO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gb2JqZWN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBvID0gb2JqZWN0W2ldO1xuICAgICAgICBzdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gb2JqZWN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBvID0gb2JqZWN0W2ldO1xuICAgICAgICByZXN1bHQucHVzaChzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFtzdF9vcGVyYXRpb24udG9PYmplY3Qob2JqZWN0LCBkZWJ1ZyldO1xuICAgICAgfVxuXG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBvYmplY3RbaV07XG4gICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi50b09iamVjdChvLCBkZWJ1ZykpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gYXJyYXk7XG59O1xuXG5UeXBlcy50aW1lX3BvaW50X3NlYyA9IHtcbiAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICByZXR1cm4gYi5yZWFkVWludDMyKCk7XG4gIH0sXG4gIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgIT09ICdudW1iZXInKSB7XG4gICAgICBvYmplY3QgPSBUeXBlcy50aW1lX3BvaW50X3NlYy5mcm9tT2JqZWN0KG9iamVjdCk7XG4gICAgfVxuXG4gICAgYi53cml0ZVVpbnQzMihvYmplY3QpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIGlmIChvYmplY3QuZ2V0VGltZSkge1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3Iob2JqZWN0LmdldFRpbWUoKSAvIDEwMDApO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGRhdGUgdHlwZTogJyArIG9iamVjdCk7XG4gICAgfVxuXG4gICAgLy8gaWYodHlwZW9mIG9iamVjdCA9PT0gXCJzdHJpbmdcIiAmJiAhL1okLy50ZXN0KG9iamVjdCkpXG4gICAgLy8gICAgIG9iamVjdCA9IG9iamVjdCArIFwiWlwiXG5cbiAgICByZXR1cm4gTWF0aC5mbG9vcihuZXcgRGF0ZShvYmplY3QpLmdldFRpbWUoKSAvIDEwMDApO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIG5ldyBEYXRlKDApLnRvSVNPU3RyaW5nKCkuc3BsaXQoJy4nKVswXTtcbiAgICB9XG5cbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICBpZiAob2JqZWN0LmdldFRpbWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QudG9JU09TdHJpbmcoKS5zcGxpdCgnLicpWzBdO1xuICAgIH1cblxuICAgIHZhciBpbnQgPSBwYXJzZUludChvYmplY3QsIDEwKTtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZSgwLCAweGZmZmZmZmZmLCBpbnQsICd1aW50MzIgJyArIG9iamVjdCk7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGludCAqIDEwMDApLnRvSVNPU3RyaW5nKCkuc3BsaXQoJy4nKVswXTtcbiAgfVxufTtcblxuVHlwZXMuc2V0ID0gZnVuY3Rpb24gKHN0X29wZXJhdGlvbikge1xuICB2YXIgc2V0X29iamVjdCA9IHtcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24gdmFsaWRhdGUoYXJyYXkpIHtcbiAgICAgIHZhciBkdXBfbWFwID0ge307XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhcnJheS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2YXIgbyA9IGFycmF5W2ldO1xuICAgICAgICB2YXIgcmVmID0gdHlwZW9mIG8gPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKG8pO1xuXG4gICAgICAgIGlmIChbJ3N0cmluZycsICdudW1iZXInXS5pbmRleE9mKHJlZikgPj0gMCkge1xuICAgICAgICAgIGlmIChkdXBfbWFwW29dICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZHVwbGljYXRlIChzZXQpJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZHVwX21hcFtvXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNvcnRPcGVyYXRpb24oYXJyYXksIHN0X29wZXJhdGlvbik7XG4gICAgfSxcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgdmFyIHNpemUgPSBiLnJlYWRWYXJpbnQzMigpO1xuXG4gICAgICBpZiAoSEVYX0RVTVApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ3ZhcmludDMyIHNpemUgPSAnICsgc2l6ZS50b1N0cmluZygxNikpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgc2l6ZSA+IDAgPyBpIDwgc2l6ZSA6IGkgPiBzaXplOyBzaXplID4gMCA/IGkrKyA6IGkrKykge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSgpKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICBvYmplY3QgPSBbXTtcbiAgICAgIH1cblxuICAgICAgYi53cml0ZVZhcmludDMyKG9iamVjdC5sZW5ndGgpO1xuICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy52YWxpZGF0ZShvYmplY3QpO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gaXRlcmFibGUubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgbyk7XG4gICAgICB9XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgaWYgKCFvYmplY3QpIHtcbiAgICAgICAgb2JqZWN0ID0gW107XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICB2YXIgbyA9IG9iamVjdFtpXTtcbiAgICAgICAgICByZXN1bHQucHVzaChzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSgpKTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gW3N0X29wZXJhdGlvbi50b09iamVjdChvYmplY3QsIGRlYnVnKV07XG4gICAgICB9XG5cbiAgICAgIGlmICghb2JqZWN0KSB7XG4gICAgICAgIG9iamVjdCA9IFtdO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBvYmplY3RbaV07XG4gICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi50b09iamVjdChvLCBkZWJ1ZykpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZShyZXN1bHQpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gc2V0X29iamVjdDtcbn07XG5cblR5cGVzLmZpeGVkX2FycmF5ID0gZnVuY3Rpb24gKGNvdW50LCBzdF9vcGVyYXRpb24pIHtcbiAgdmFyIGZpeGVkX2FycmF5ID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICB2YXIgcmVzdWx0cyA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgcmVmID0gY291bnQ7IGkgPCByZWY7IGkrKykge1xuICAgICAgICByZXN1bHRzLnB1c2goc3Rfb3BlcmF0aW9uLmZyb21CeXRlQnVmZmVyKGIpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNvcnRPcGVyYXRpb24ocmVzdWx0cywgc3Rfb3BlcmF0aW9uKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBpZiAoY291bnQgIT09IDApIHtcbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBpID0gMCwgcmVmID0gY291bnQ7IGkgPCByZWY7IGkrKykge1xuICAgICAgICBzdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3RbaV0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIGlmIChjb3VudCAhPT0gMCkge1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlc3VsdHMgPSBbXTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIHJlZiA9IGNvdW50OyBpIDwgcmVmOyBpKyspIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKHN0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG9iamVjdFtpXSkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QsIGRlYnVnKSB7XG4gICAgICBpZiAoZGVidWcgPT0gbnVsbCkge1xuICAgICAgICBkZWJ1ZyA9IHt9O1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVzdWx0cyA9IHZvaWQgMDtcblxuICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlc3VsdHMgPSBbXTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcmVmID0gY291bnQ7IGkgPCByZWY7IGkrKykge1xuICAgICAgICAgIHJlc3VsdHMucHVzaChzdF9vcGVyYXRpb24udG9PYmplY3QodW5kZWZpbmVkLCBkZWJ1ZykpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb3VudCAhPT0gMCkge1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgcmVzdWx0cyA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBfaSA9IDAsIF9yZWYgPSBjb3VudDsgX2kgPCBfcmVmOyBfaSsrKSB7XG4gICAgICAgIHJlc3VsdHMucHVzaChzdF9vcGVyYXRpb24udG9PYmplY3Qob2JqZWN0W19pXSwgZGVidWcpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBmaXhlZF9hcnJheTtcbn07XG5cbi8qIFN1cHBvcnRzIGluc3RhbmNlIG51bWJlcnMgKDExKSBvciBvYmplY3QgdHlwZXMgKDEuMi4xMSkuICBPYmplY3QgdHlwZVxuVmFsaWRhdGlvbiBpcyBlbmZvcmNlZCB3aGVuIGFuIG9iamVjdCB0eXBlIGlzIHVzZWQuICovXG5UeXBlcy5pZF90eXBlID0gZnVuY3Rpb24gKHJlc2VydmVkX3NwYWNlcywgb2JqZWN0X3R5cGUpIHtcbiAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKHJlc2VydmVkX3NwYWNlcywgJ3Jlc2VydmVkX3NwYWNlcycpO1xuICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0X3R5cGUsICdvYmplY3RfdHlwZScpO1xuXG4gIHZhciBpZF90eXBlX29iamVjdCA9IHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgcmV0dXJuIGIucmVhZFZhcmludDMyKCk7XG4gICAgfSxcbiAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG5cbiAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgICAgfVxuXG4gICAgICAvLyBjb252ZXJ0IDEuMi5uIGludG8ganVzdCBuXG4gICAgICBpZiAoL15bMC05XStcXC5bMC05XStcXC5bMC05XSskLy50ZXN0KG9iamVjdCkpIHtcbiAgICAgICAgb2JqZWN0ID0gX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LmdldF9pbnN0YW5jZShyZXNlcnZlZF9zcGFjZXMsIG9iamVjdF90eXBlLCBvYmplY3QpO1xuICAgICAgfVxuXG4gICAgICBiLndyaXRlVmFyaW50MzIoX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnRvX251bWJlcihvYmplY3QpKTtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgICAgaWYgKG9iamVjdC5yZXNvbHZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgb2JqZWN0ID0gb2JqZWN0LnJlc29sdmU7XG4gICAgICB9XG5cbiAgICAgIGlmIChfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQuaXNfZGlnaXRzKG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC50b19udW1iZXIob2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5nZXRfaW5zdGFuY2UocmVzZXJ2ZWRfc3BhY2VzLCBvYmplY3RfdHlwZSwgb2JqZWN0KTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgIHZhciBvYmplY3RfdHlwZV9pZCA9IF9DaGFpblR5cGVzMi5kZWZhdWx0Lm9iamVjdF90eXBlW29iamVjdF90eXBlXTtcblxuICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiByZXNlcnZlZF9zcGFjZXMgKyAnLicgKyBvYmplY3RfdHlwZV9pZCArICcuMCc7XG4gICAgICB9XG5cbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgICBpZiAob2JqZWN0LnJlc29sdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBvYmplY3QgPSBvYmplY3QucmVzb2x2ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKC9eWzAtOV0rXFwuWzAtOV0rXFwuWzAtOV0rJC8udGVzdChvYmplY3QpKSB7XG4gICAgICAgIG9iamVjdCA9IF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5nZXRfaW5zdGFuY2UocmVzZXJ2ZWRfc3BhY2VzLCBvYmplY3RfdHlwZSwgb2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc2VydmVkX3NwYWNlcyArICcuJyArIG9iamVjdF90eXBlX2lkICsgJy4nICsgb2JqZWN0O1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gaWRfdHlwZV9vYmplY3Q7XG59O1xuXG5UeXBlcy5wcm90b2NvbF9pZF90eXBlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG5hbWUsICduYW1lJyk7XG4gIHJldHVybiBUeXBlcy5pZF90eXBlKF9DaGFpblR5cGVzMi5kZWZhdWx0LnJlc2VydmVkX3NwYWNlcy5wcm90b2NvbF9pZHMsIG5hbWUpO1xufTtcblxuVHlwZXMuaW1wbGVtZW50YXRpb25faWRfdHlwZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHZhciByZXN1bHQgPSBUeXBlcy5pZF90eXBlKF9DaGFpblR5cGVzMi5kZWZhdWx0LnJlc2VydmVkX3NwYWNlcy5pbXBsZW1lbnRhdGlvbl9pZHMsIG5hbWUpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuVHlwZXMub2JqZWN0X2lkX3R5cGUgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIF9PYmplY3RJZDIuZGVmYXVsdC5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBvYmplY3QgPSBvYmplY3QucmVzb2x2ZTtcbiAgICB9XG5cbiAgICBvYmplY3QgPSBfT2JqZWN0SWQyLmRlZmF1bHQuZnJvbVN0cmluZyhvYmplY3QpO1xuICAgIG9iamVjdC5hcHBlbmRCeXRlQnVmZmVyKGIpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgaWYgKG9iamVjdC5yZXNvbHZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgIH1cblxuICAgIHJldHVybiBfT2JqZWN0SWQyLmRlZmF1bHQuZnJvbVN0cmluZyhvYmplY3QpO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuICcwLjAuMCc7XG4gICAgfVxuXG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG5cbiAgICBpZiAob2JqZWN0LnJlc29sdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb2JqZWN0ID0gb2JqZWN0LnJlc29sdmU7XG4gICAgfVxuXG4gICAgb2JqZWN0ID0gX09iamVjdElkMi5kZWZhdWx0LmZyb21TdHJpbmcob2JqZWN0KTtcbiAgICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCk7XG4gIH1cbn07XG5cblR5cGVzLnZvdGVfaWQgPSB7XG4gIFRZUEU6IDB4MDAwMDAwZmYsXG4gIElEOiAweGZmZmZmZjAwLFxuICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHZhciB2YWx1ZSA9IGIucmVhZFVpbnQzMigpO1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiB2YWx1ZSAmIHRoaXMuVFlQRSwgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgaWQ6IHZhbHVlICYgdGhpcy5JRCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgfTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgIGlmIChvYmplY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvYmplY3QgPSBUeXBlcy52b3RlX2lkLmZyb21PYmplY3Qob2JqZWN0KTtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWUgPSBvYmplY3QuaWQgPDwgOCB8IG9iamVjdC50eXBlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgYi53cml0ZVVpbnQzMih2YWx1ZSk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCwgJyh0eXBlIHZvdGVfaWQpJyk7XG5cbiAgICBpZiAoKHR5cGVvZiBvYmplY3QgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKG9iamVjdCkpID09PSAnb2JqZWN0Jykge1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdC50eXBlLCAndHlwZScpO1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdC5pZCwgJ2lkJyk7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3Rlc3QoL15bMC05XSs6WzAtOV0rJC8sIG9iamVjdCwgJ3ZvdGVfaWQgZm9ybWF0ICcgKyBvYmplY3QpO1xuXG4gICAgdmFyIF9vYmplY3Qkc3BsaXQgPSBvYmplY3Quc3BsaXQoJzonKSxcbiAgICAgICAgdHlwZSA9IF9vYmplY3Qkc3BsaXRbMF0sXG4gICAgICAgIGlkID0gX29iamVjdCRzcGxpdFsxXTtcblxuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmYsIHR5cGUsICd2b3RlIHR5cGUgJyArIG9iamVjdCk7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmZmYsIGlkLCAndm90ZSBpZCAnICsgb2JqZWN0KTtcbiAgICByZXR1cm4geyB0eXBlOiB0eXBlLCBpZDogaWQgfTtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAnMDowJztcbiAgICB9XG5cbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcblxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnc3RyaW5nJykge1xuICAgICAgb2JqZWN0ID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KG9iamVjdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iamVjdC50eXBlICsgJzonICsgb2JqZWN0LmlkO1xuICB9LFxuICBjb21wYXJlOiBmdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgICBpZiAoKHR5cGVvZiBhID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihhKSkgIT09ICdvYmplY3QnKSB7XG4gICAgICBhID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KGEpO1xuICAgIH1cblxuICAgIGlmICgodHlwZW9mIGIgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKGIpKSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIGIgPSBUeXBlcy52b3RlX2lkLmZyb21PYmplY3QoYik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnNlSW50KGEuaWQsIDEwKSAtIHBhcnNlSW50KGIuaWQsIDEwKTtcbiAgfVxufTtcblxuVHlwZXMub3B0aW9uYWwgPSBmdW5jdGlvbiAoc3Rfb3BlcmF0aW9uKSB7XG4gIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChzdF9vcGVyYXRpb24sICdzdF9vcGVyYXRpb24nKTtcbiAgcmV0dXJuIHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgaWYgKCEoYi5yZWFkVWludDgoKSA9PT0gMSkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0ICE9PSBudWxsICYmIG9iamVjdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGIud3JpdGVVaW50OCgxKTtcbiAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGIud3JpdGVVaW50OCgwKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG9iamVjdCk7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAvLyB0b09iamVjdCBpcyBvbmx5IG51bGwgc2F2ZSBpZiB1c2VfZGVmYXVsdCBpcyB0cnVlXG4gICAgICB2YXIgcmVzdWx0X29iamVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KG9iamVjdCwgZGVidWcpO1xuICAgICAgfSgpO1xuXG4gICAgICBpZiAoZGVidWcuYW5ub3RhdGUpIHtcbiAgICAgICAgaWYgKCh0eXBlb2YgcmVzdWx0X29iamVjdCA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YocmVzdWx0X29iamVjdCkpID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHJlc3VsdF9vYmplY3QuX19vcHRpb25hbCA9ICdwYXJlbnQgaXMgb3B0aW9uYWwnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdF9vYmplY3QgPSB7IF9fb3B0aW9uYWw6IHJlc3VsdF9vYmplY3QgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0X29iamVjdDtcbiAgICB9XG4gIH07XG59O1xuXG5UeXBlcy5zdGF0aWNfdmFyaWFudCA9IGZ1bmN0aW9uIChfc3Rfb3BlcmF0aW9ucykge1xuICB2YXIgc3RhdGljX3ZhcmlhbnQgPSB7XG4gICAgbm9zb3J0OiB0cnVlLFxuICAgIHN0X29wZXJhdGlvbnM6IF9zdF9vcGVyYXRpb25zLFxuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICB2YXIgdHlwZV9pZCA9IGIucmVhZFZhcmludDMyKCk7XG4gICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuXG4gICAgICBpZiAoSEVYX0RVTVApIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignc3RhdGljX3ZhcmlhbnQgaWQgMHgnICsgdHlwZV9pZC50b1N0cmluZygxNikgKyAnICgnICsgdHlwZV9pZCArICcpJyk7XG4gICAgICB9XG5cbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChzdF9vcGVyYXRpb24sICdvcGVyYXRpb24gJyArIHR5cGVfaWQpO1xuICAgICAgcmV0dXJuIFt0eXBlX2lkLCBzdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYildO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgdmFyIHR5cGVfaWQgPSBvYmplY3RbMF07XG4gICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKHN0X29wZXJhdGlvbiwgJ29wZXJhdGlvbiAnICsgdHlwZV9pZCk7XG4gICAgICBiLndyaXRlVmFyaW50MzIodHlwZV9pZCk7XG4gICAgICBzdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3RbMV0pO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgdmFyIHR5cGVfaWQgPSBvYmplY3RbMF07XG4gICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuXG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQoc3Rfb3BlcmF0aW9uLCAnb3BlcmF0aW9uICcgKyB0eXBlX2lkKTtcbiAgICAgIHJldHVybiBbdHlwZV9pZCwgc3Rfb3BlcmF0aW9uLmZyb21PYmplY3Qob2JqZWN0WzFdKV07XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFswLCB0aGlzLnN0X29wZXJhdGlvbnNbMF0udG9PYmplY3QodW5kZWZpbmVkLCBkZWJ1ZyldO1xuICAgICAgfVxuXG4gICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgIHZhciB0eXBlX2lkID0gb2JqZWN0WzBdO1xuICAgICAgdmFyIHN0X29wZXJhdGlvbiA9IHRoaXMuc3Rfb3BlcmF0aW9uc1t0eXBlX2lkXTtcbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChzdF9vcGVyYXRpb24sICdvcGVyYXRpb24gJyArIHR5cGVfaWQpO1xuICAgICAgcmV0dXJuIFt0eXBlX2lkLCBzdF9vcGVyYXRpb24udG9PYmplY3Qob2JqZWN0WzFdLCBkZWJ1ZyldO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gc3RhdGljX3ZhcmlhbnQ7XG59O1xuXG5UeXBlcy5tYXAgPSBmdW5jdGlvbiAoa2V5X3N0X29wZXJhdGlvbiwgdmFsdWVfc3Rfb3BlcmF0aW9uKSB7XG4gIHZhciBtYXBfb2JqZWN0ID0ge1xuICAgIHZhbGlkYXRlOiBmdW5jdGlvbiB2YWxpZGF0ZShhcnJheSkge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFycmF5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGluZyBhcnJheScpO1xuICAgICAgfVxuXG4gICAgICB2YXIgZHVwX21hcCA9IHt9O1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBhcnJheVtpXTtcbiAgICAgICAgdmFyIHJlZiA9IHZvaWQgMDtcblxuICAgICAgICBpZiAoIShvLmxlbmd0aCA9PT0gMikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGluZyB0d28gZWxlbWVudHMnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlZiA9IF90eXBlb2Yob1swXSk7XG5cbiAgICAgICAgaWYgKHJlZiAmJiBbJ251bWJlcicsICdzdHJpbmcnXS5pbmRleE9mKHJlZikgPj0gMCkge1xuICAgICAgICAgIGlmIChkdXBfbWFwW29bMF1dICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZHVwbGljYXRlIChtYXApJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZHVwX21hcFtvWzBdXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNvcnRPcGVyYXRpb24oYXJyYXksIGtleV9zdF9vcGVyYXRpb24pO1xuICAgIH0sXG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIHZhciBlbmQgPSBiLnJlYWRWYXJpbnQzMigpO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgZW5kID4gMCA/IGkgPCBlbmQgOiBpID4gZW5kOyBlbmQgPiAwID8gaSsrIDogaSsrKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKFtrZXlfc3Rfb3BlcmF0aW9uLmZyb21CeXRlQnVmZmVyKGIpLCB2YWx1ZV9zdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYildKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGUocmVzdWx0KTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICB0aGlzLnZhbGlkYXRlKG9iamVjdCk7XG4gICAgICBiLndyaXRlVmFyaW50MzIob2JqZWN0Lmxlbmd0aCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBvYmplY3RbaV07XG4gICAgICAgIGtleV9zdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvWzBdKTtcbiAgICAgICAgdmFsdWVfc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb1sxXSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmplY3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIG8gPSBvYmplY3RbaV07XG4gICAgICAgIHJlc3VsdC5wdXNoKFtrZXlfc3Rfb3BlcmF0aW9uLmZyb21PYmplY3Qob1swXSksIHZhbHVlX3N0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG9bMV0pXSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlKHJlc3VsdCk7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFtba2V5X3N0X29wZXJhdGlvbi50b09iamVjdCh1bmRlZmluZWQsIGRlYnVnKSwgdmFsdWVfc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KHVuZGVmaW5lZCwgZGVidWcpXV07XG4gICAgICB9XG5cbiAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgb2JqZWN0ID0gdGhpcy52YWxpZGF0ZShvYmplY3QpO1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gb2JqZWN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHZhciBvID0gb2JqZWN0W2ldO1xuICAgICAgICByZXN1bHQucHVzaChba2V5X3N0X29wZXJhdGlvbi50b09iamVjdChvWzBdLCBkZWJ1ZyksIHZhbHVlX3N0X29wZXJhdGlvbi50b09iamVjdChvWzFdLCBkZWJ1ZyldKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIG1hcF9vYmplY3Q7XG59O1xuXG5UeXBlcy5wdWJsaWNfa2V5ID0ge1xuICB0b1B1YmxpYzogZnVuY3Rpb24gdG9QdWJsaWMob2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdC5yZXNvbHZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgIH1cblxuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBfZWNjLlB1YmxpY0tleSkge1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICB2YXIgcmVzdWx0ID0gb2JqZWN0O1xuXG4gICAgaWYgKCFvYmplY3QpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmICghb2JqZWN0LlEpIHtcbiAgICAgIHJlc3VsdCA9IF9lY2MuUHVibGljS2V5LmZyb21TdHJpbmdPclRocm93KG9iamVjdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcbiAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICByZXR1cm4gX0Zhc3RQYXJzZXIyLmRlZmF1bHQucHVibGljX2tleShiKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICBfRmFzdFBhcnNlcjIuZGVmYXVsdC5wdWJsaWNfa2V5KGIsIFR5cGVzLnB1YmxpY19rZXkudG9QdWJsaWMob2JqZWN0KSk7XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG5cbiAgICBpZiAob2JqZWN0LlEpIHtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgcmV0dXJuIFR5cGVzLnB1YmxpY19rZXkudG9QdWJsaWMob2JqZWN0KTtcbiAgfSxcbiAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBfcGVlcnBsYXlzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeCArICc4NTlneGZuWHlVcmlNZ1VlVGhoMWZXdjNvcWNwTEZ5SGEzVGZGWUM0UEsySHFoVG9WTSc7XG4gICAgfVxuXG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgcmV0dXJuIG9iamVjdC50b1N0cmluZygpO1xuICB9LFxuICBjb21wYXJlOiBmdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgICByZXR1cm4gc3RyQ21wKGEudG9BZGRyZXNzU3RyaW5nKCksIGIudG9BZGRyZXNzU3RyaW5nKCkpO1xuICB9XG59O1xuXG5UeXBlcy5hZGRyZXNzID0ge1xuICBfdG9fYWRkcmVzczogZnVuY3Rpb24gX3RvX2FkZHJlc3Mob2JqZWN0KSB7XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG5cbiAgICBpZiAob2JqZWN0LmFkZHkpIHtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgcmV0dXJuIF9lY2MuQWRkcmVzcy5mcm9tU3RyaW5nKG9iamVjdCk7XG4gIH0sXG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgcmV0dXJuIG5ldyBfZWNjLkFkZHJlc3MoX0Zhc3RQYXJzZXIyLmRlZmF1bHQucmlwZW1kMTYwKGIpKTtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICBfRmFzdFBhcnNlcjIuZGVmYXVsdC5yaXBlbWQxNjAoYiwgVHlwZXMuYWRkcmVzcy5fdG9fYWRkcmVzcyhvYmplY3QpLnRvQnVmZmVyKCkpO1xuICB9LFxuICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBUeXBlcy5hZGRyZXNzLl90b19hZGRyZXNzKG9iamVjdCk7XG4gIH0sXG4gIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gX3BlZXJwbGF5c2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXggKyAnNjY0S21IeFN1UXlEc2Z3bzRXRUp2V3B6ZzFRS2RnNjdTJztcbiAgICB9XG5cbiAgICByZXR1cm4gVHlwZXMuYWRkcmVzcy5fdG9fYWRkcmVzcyhvYmplY3QpLnRvU3RyaW5nKCk7XG4gIH0sXG4gIGNvbXBhcmU6IGZ1bmN0aW9uIGNvbXBhcmUoYSwgYikge1xuICAgIHJldHVybiBzdHJDbXAoYS50b1N0cmluZygpLCBiLnRvU3RyaW5nKCkpO1xuICB9XG59O1xuXG5UeXBlcy52YXJpYW50ID0ge1xuICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgIHZhciB0eXBlID0gYi5yZWFkVWludDgoKTtcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIFR5cGVzLmludDY0LmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gVHlwZXMudWludDY0LmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXR1cm4gYi5yZWFkRG91YmxlKCk7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJldHVybiBUeXBlcy5ib29sLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgY2FzZSA1OlxuICAgICAgICByZXR1cm4gVHlwZXMuc3RyaW5nLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgY2FzZSA2OlxuICAgICAgICByZXR1cm4gVHlwZXMuYXJyYXkoVHlwZXMudmFyaWFudCkuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICBjYXNlIDc6XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gVHlwZXMudmFyaWFudF9vYmplY3QuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgfVxuICB9LFxuICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnbnVtYmVyJykge1xuICAgICAgaWYgKE51bWJlci5pc0ludGVnZXIob2JqZWN0KSkge1xuICAgICAgICBpZiAob2JqZWN0ID49IDApIHtcbiAgICAgICAgICBiLndyaXRlVWludDgoMik7XG4gICAgICAgICAgVHlwZXMudWludDY0LmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBiLndyaXRlVWludDgoMSk7XG4gICAgICAgICAgVHlwZXMuaW50NjQuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBiLndyaXRlVWludDgoMyk7XG4gICAgICAgIGIud3JpdGVEb3VibGUoTnVtYmVyLnBhcnNlRmxvYXQob2JqZWN0KSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnYm9vbGVhbicpIHtcbiAgICAgIGIud3JpdGVVaW50OCg0KTtcbiAgICAgIFR5cGVzLmJvb2wuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9iamVjdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGIud3JpdGVVaW50OCg1KTtcbiAgICAgIFR5cGVzLnN0cmluZy5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCk7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG9iamVjdCkpIHtcbiAgICAgIGIud3JpdGVVaW50OCg2KTtcbiAgICAgIFR5cGVzLmFycmF5KFR5cGVzLnZhcmlhbnQpLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYi53cml0ZVVpbnQ4KDcpO1xuICAgICAgVHlwZXMudmFyaWFudF9vYmplY3QuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpO1xuICAgIH1cbiAgfSxcbiAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShvYmplY3QpO1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2Uob2JqZWN0KTtcbiAgfVxufTtcblxuVHlwZXMudmFyaWFudF9vYmplY3QgPSB7XG4gIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgdmFyIGNvdW50ID0gYi5yZWFkVmFyaW50MzIoKTtcbiAgICB2YXIgcmVzdWx0ID0ge307XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcbiAgICAgIHZhciBrZXkgPSBUeXBlcy5zdHJpbmcuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICByZXN1bHRba2V5XSA9IFR5cGVzLnZhcmlhbnQuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcbiAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdCk7XG5cbiAgICBiLndyaXRlVmFyaW50MzIoa2V5cy5sZW5ndGgpOyAvLyBudW1iZXIgb2Yga2V5L3ZhbHVlIHBhaXJzXG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0ga2V5cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICBUeXBlcy5zdHJpbmcuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBrZXkpO1xuICAgICAgVHlwZXMudmFyaWFudC5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdFtrZXldKTtcbiAgICB9XG4gIH0sXG4gIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIG5ld09iamVjdCA9IHt9O1xuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGtleXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgbmV3T2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3T2JqZWN0O1xuICB9LFxuICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgdmFyIG5ld09iamVjdCA9IHt9O1xuXG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGtleXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgbmV3T2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3T2JqZWN0O1xuICB9XG59O1xuXG5UeXBlcy5lbnVtZXJhdGlvbiA9IGZ1bmN0aW9uICh2YWx1ZXMpIHtcbiAgdmFyIGVudW1lcmF0aW9uID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICByZXR1cm4gdmFsdWVzW2IucmVhZFZhcmludDMyWmlnWmFnKCldO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgIGIud3JpdGVWYXJpbnQzMlppZ1phZyh2YWx1ZXMuaW5kZXhPZihvYmplY3QpKTtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGVudW1lcmF0aW9uO1xufTtcblxuVHlwZXMuc2hhMjU2ID0gVHlwZXMuYnl0ZXMoMzIpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBUeXBlcztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOyIsIid1c2Ugc3RyaWN0JztcblxuLy8gY29tcGFyZSBhbmQgaXNCdWZmZXIgdGFrZW4gZnJvbSBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9ibG9iLzY4MGU5ZTVlNDg4ZjIyYWFjMjc1OTlhNTdkYzg0NGE2MzE1OTI4ZGQvaW5kZXguanNcbi8vIG9yaWdpbmFsIG5vdGljZTpcblxuLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG4gIGlmIChhID09PSBiKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICB2YXIgeCA9IGEubGVuZ3RoO1xuICB2YXIgeSA9IGIubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldO1xuICAgICAgeSA9IGJbaV07XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgaWYgKHkgPCB4KSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5mdW5jdGlvbiBpc0J1ZmZlcihiKSB7XG4gIGlmIChnbG9iYWwuQnVmZmVyICYmIHR5cGVvZiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIoYik7XG4gIH1cbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcik7XG59XG5cbi8vIGJhc2VkIG9uIG5vZGUgYXNzZXJ0LCBvcmlnaW5hbCBub3RpY2U6XG5cbi8vIGh0dHA6Ly93aWtpLmNvbW1vbmpzLm9yZy93aWtpL1VuaXRfVGVzdGluZy8xLjBcbi8vXG4vLyBUSElTIElTIE5PVCBURVNURUQgTk9SIExJS0VMWSBUTyBXT1JLIE9VVFNJREUgVjghXG4vL1xuLy8gT3JpZ2luYWxseSBmcm9tIG5hcndoYWwuanMgKGh0dHA6Ly9uYXJ3aGFsanMub3JnKVxuLy8gQ29weXJpZ2h0IChjKSAyMDA5IFRob21hcyBSb2JpbnNvbiA8Mjgwbm9ydGguY29tPlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICdTb2Z0d2FyZScpLCB0b1xuLy8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAnQVMgSVMnLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU5cbi8vIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT05cbi8vIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwvJyk7XG52YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBwU2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgZnVuY3Rpb25zSGF2ZU5hbWVzID0gKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbygpIHt9Lm5hbWUgPT09ICdmb28nO1xufSgpKTtcbmZ1bmN0aW9uIHBUb1N0cmluZyAob2JqKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKTtcbn1cbmZ1bmN0aW9uIGlzVmlldyhhcnJidWYpIHtcbiAgaWYgKGlzQnVmZmVyKGFycmJ1ZikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBnbG9iYWwuQXJyYXlCdWZmZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlci5pc1ZpZXcgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQXJyYXlCdWZmZXIuaXNWaWV3KGFycmJ1Zik7XG4gIH1cbiAgaWYgKCFhcnJidWYpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGFycmJ1ZiBpbnN0YW5jZW9mIERhdGFWaWV3KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGFycmJ1Zi5idWZmZXIgJiYgYXJyYnVmLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuLy8gMS4gVGhlIGFzc2VydCBtb2R1bGUgcHJvdmlkZXMgZnVuY3Rpb25zIHRoYXQgdGhyb3dcbi8vIEFzc2VydGlvbkVycm9yJ3Mgd2hlbiBwYXJ0aWN1bGFyIGNvbmRpdGlvbnMgYXJlIG5vdCBtZXQuIFRoZVxuLy8gYXNzZXJ0IG1vZHVsZSBtdXN0IGNvbmZvcm0gdG8gdGhlIGZvbGxvd2luZyBpbnRlcmZhY2UuXG5cbnZhciBhc3NlcnQgPSBtb2R1bGUuZXhwb3J0cyA9IG9rO1xuXG4vLyAyLiBUaGUgQXNzZXJ0aW9uRXJyb3IgaXMgZGVmaW5lZCBpbiBhc3NlcnQuXG4vLyBuZXcgYXNzZXJ0LkFzc2VydGlvbkVycm9yKHsgbWVzc2FnZTogbWVzc2FnZSxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YWw6IGFjdHVhbCxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQgfSlcblxudmFyIHJlZ2V4ID0gL1xccypmdW5jdGlvblxccysoW15cXChcXHNdKilcXHMqLztcbi8vIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9samhhcmIvZnVuY3Rpb24ucHJvdG90eXBlLm5hbWUvYmxvYi9hZGVlZWVjOGJmY2M2MDY4YjE4N2Q3ZDlmYjNkNWJiMWQzYTMwODk5L2ltcGxlbWVudGF0aW9uLmpzXG5mdW5jdGlvbiBnZXROYW1lKGZ1bmMpIHtcbiAgaWYgKCF1dGlsLmlzRnVuY3Rpb24oZnVuYykpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGZ1bmN0aW9uc0hhdmVOYW1lcykge1xuICAgIHJldHVybiBmdW5jLm5hbWU7XG4gIH1cbiAgdmFyIHN0ciA9IGZ1bmMudG9TdHJpbmcoKTtcbiAgdmFyIG1hdGNoID0gc3RyLm1hdGNoKHJlZ2V4KTtcbiAgcmV0dXJuIG1hdGNoICYmIG1hdGNoWzFdO1xufVxuYXNzZXJ0LkFzc2VydGlvbkVycm9yID0gZnVuY3Rpb24gQXNzZXJ0aW9uRXJyb3Iob3B0aW9ucykge1xuICB0aGlzLm5hbWUgPSAnQXNzZXJ0aW9uRXJyb3InO1xuICB0aGlzLmFjdHVhbCA9IG9wdGlvbnMuYWN0dWFsO1xuICB0aGlzLmV4cGVjdGVkID0gb3B0aW9ucy5leHBlY3RlZDtcbiAgdGhpcy5vcGVyYXRvciA9IG9wdGlvbnMub3BlcmF0b3I7XG4gIGlmIChvcHRpb25zLm1lc3NhZ2UpIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBvcHRpb25zLm1lc3NhZ2U7XG4gICAgdGhpcy5nZW5lcmF0ZWRNZXNzYWdlID0gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5tZXNzYWdlID0gZ2V0TWVzc2FnZSh0aGlzKTtcbiAgICB0aGlzLmdlbmVyYXRlZE1lc3NhZ2UgPSB0cnVlO1xuICB9XG4gIHZhciBzdGFja1N0YXJ0RnVuY3Rpb24gPSBvcHRpb25zLnN0YWNrU3RhcnRGdW5jdGlvbiB8fCBmYWlsO1xuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICB9IGVsc2Uge1xuICAgIC8vIG5vbiB2OCBicm93c2VycyBzbyB3ZSBjYW4gaGF2ZSBhIHN0YWNrdHJhY2VcbiAgICB2YXIgZXJyID0gbmV3IEVycm9yKCk7XG4gICAgaWYgKGVyci5zdGFjaykge1xuICAgICAgdmFyIG91dCA9IGVyci5zdGFjaztcblxuICAgICAgLy8gdHJ5IHRvIHN0cmlwIHVzZWxlc3MgZnJhbWVzXG4gICAgICB2YXIgZm5fbmFtZSA9IGdldE5hbWUoc3RhY2tTdGFydEZ1bmN0aW9uKTtcbiAgICAgIHZhciBpZHggPSBvdXQuaW5kZXhPZignXFxuJyArIGZuX25hbWUpO1xuICAgICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICAgIC8vIG9uY2Ugd2UgaGF2ZSBsb2NhdGVkIHRoZSBmdW5jdGlvbiBmcmFtZVxuICAgICAgICAvLyB3ZSBuZWVkIHRvIHN0cmlwIG91dCBldmVyeXRoaW5nIGJlZm9yZSBpdCAoYW5kIGl0cyBsaW5lKVxuICAgICAgICB2YXIgbmV4dF9saW5lID0gb3V0LmluZGV4T2YoJ1xcbicsIGlkeCArIDEpO1xuICAgICAgICBvdXQgPSBvdXQuc3Vic3RyaW5nKG5leHRfbGluZSArIDEpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnN0YWNrID0gb3V0O1xuICAgIH1cbiAgfVxufTtcblxuLy8gYXNzZXJ0LkFzc2VydGlvbkVycm9yIGluc3RhbmNlb2YgRXJyb3JcbnV0aWwuaW5oZXJpdHMoYXNzZXJ0LkFzc2VydGlvbkVycm9yLCBFcnJvcik7XG5cbmZ1bmN0aW9uIHRydW5jYXRlKHMsIG4pIHtcbiAgaWYgKHR5cGVvZiBzID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBzLmxlbmd0aCA8IG4gPyBzIDogcy5zbGljZSgwLCBuKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcztcbiAgfVxufVxuZnVuY3Rpb24gaW5zcGVjdChzb21ldGhpbmcpIHtcbiAgaWYgKGZ1bmN0aW9uc0hhdmVOYW1lcyB8fCAhdXRpbC5pc0Z1bmN0aW9uKHNvbWV0aGluZykpIHtcbiAgICByZXR1cm4gdXRpbC5pbnNwZWN0KHNvbWV0aGluZyk7XG4gIH1cbiAgdmFyIHJhd25hbWUgPSBnZXROYW1lKHNvbWV0aGluZyk7XG4gIHZhciBuYW1lID0gcmF3bmFtZSA/ICc6ICcgKyByYXduYW1lIDogJyc7XG4gIHJldHVybiAnW0Z1bmN0aW9uJyArICBuYW1lICsgJ10nO1xufVxuZnVuY3Rpb24gZ2V0TWVzc2FnZShzZWxmKSB7XG4gIHJldHVybiB0cnVuY2F0ZShpbnNwZWN0KHNlbGYuYWN0dWFsKSwgMTI4KSArICcgJyArXG4gICAgICAgICBzZWxmLm9wZXJhdG9yICsgJyAnICtcbiAgICAgICAgIHRydW5jYXRlKGluc3BlY3Qoc2VsZi5leHBlY3RlZCksIDEyOCk7XG59XG5cbi8vIEF0IHByZXNlbnQgb25seSB0aGUgdGhyZWUga2V5cyBtZW50aW9uZWQgYWJvdmUgYXJlIHVzZWQgYW5kXG4vLyB1bmRlcnN0b29kIGJ5IHRoZSBzcGVjLiBJbXBsZW1lbnRhdGlvbnMgb3Igc3ViIG1vZHVsZXMgY2FuIHBhc3Ncbi8vIG90aGVyIGtleXMgdG8gdGhlIEFzc2VydGlvbkVycm9yJ3MgY29uc3RydWN0b3IgLSB0aGV5IHdpbGwgYmVcbi8vIGlnbm9yZWQuXG5cbi8vIDMuIEFsbCBvZiB0aGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBtdXN0IHRocm93IGFuIEFzc2VydGlvbkVycm9yXG4vLyB3aGVuIGEgY29ycmVzcG9uZGluZyBjb25kaXRpb24gaXMgbm90IG1ldCwgd2l0aCBhIG1lc3NhZ2UgdGhhdFxuLy8gbWF5IGJlIHVuZGVmaW5lZCBpZiBub3QgcHJvdmlkZWQuICBBbGwgYXNzZXJ0aW9uIG1ldGhvZHMgcHJvdmlkZVxuLy8gYm90aCB0aGUgYWN0dWFsIGFuZCBleHBlY3RlZCB2YWx1ZXMgdG8gdGhlIGFzc2VydGlvbiBlcnJvciBmb3Jcbi8vIGRpc3BsYXkgcHVycG9zZXMuXG5cbmZ1bmN0aW9uIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgb3BlcmF0b3IsIHN0YWNrU3RhcnRGdW5jdGlvbikge1xuICB0aHJvdyBuZXcgYXNzZXJ0LkFzc2VydGlvbkVycm9yKHtcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIGFjdHVhbDogYWN0dWFsLFxuICAgIGV4cGVjdGVkOiBleHBlY3RlZCxcbiAgICBvcGVyYXRvcjogb3BlcmF0b3IsXG4gICAgc3RhY2tTdGFydEZ1bmN0aW9uOiBzdGFja1N0YXJ0RnVuY3Rpb25cbiAgfSk7XG59XG5cbi8vIEVYVEVOU0lPTiEgYWxsb3dzIGZvciB3ZWxsIGJlaGF2ZWQgZXJyb3JzIGRlZmluZWQgZWxzZXdoZXJlLlxuYXNzZXJ0LmZhaWwgPSBmYWlsO1xuXG4vLyA0LiBQdXJlIGFzc2VydGlvbiB0ZXN0cyB3aGV0aGVyIGEgdmFsdWUgaXMgdHJ1dGh5LCBhcyBkZXRlcm1pbmVkXG4vLyBieSAhIWd1YXJkLlxuLy8gYXNzZXJ0Lm9rKGd1YXJkLCBtZXNzYWdlX29wdCk7XG4vLyBUaGlzIHN0YXRlbWVudCBpcyBlcXVpdmFsZW50IHRvIGFzc2VydC5lcXVhbCh0cnVlLCAhIWd1YXJkLFxuLy8gbWVzc2FnZV9vcHQpOy4gVG8gdGVzdCBzdHJpY3RseSBmb3IgdGhlIHZhbHVlIHRydWUsIHVzZVxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKHRydWUsIGd1YXJkLCBtZXNzYWdlX29wdCk7LlxuXG5mdW5jdGlvbiBvayh2YWx1ZSwgbWVzc2FnZSkge1xuICBpZiAoIXZhbHVlKSBmYWlsKHZhbHVlLCB0cnVlLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQub2spO1xufVxuYXNzZXJ0Lm9rID0gb2s7XG5cbi8vIDUuIFRoZSBlcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgc2hhbGxvdywgY29lcmNpdmUgZXF1YWxpdHkgd2l0aFxuLy8gPT0uXG4vLyBhc3NlcnQuZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBlcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgIT0gZXhwZWN0ZWQpIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09JywgYXNzZXJ0LmVxdWFsKTtcbn07XG5cbi8vIDYuIFRoZSBub24tZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIGZvciB3aGV0aGVyIHR3byBvYmplY3RzIGFyZSBub3QgZXF1YWxcbi8vIHdpdGggIT0gYXNzZXJ0Lm5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdEVxdWFsID0gZnVuY3Rpb24gbm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsID09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT0nLCBhc3NlcnQubm90RXF1YWwpO1xuICB9XG59O1xuXG4vLyA3LiBUaGUgZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGEgZGVlcCBlcXVhbGl0eSByZWxhdGlvbi5cbi8vIGFzc2VydC5kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuZGVlcEVxdWFsID0gZnVuY3Rpb24gZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKCFfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIGZhbHNlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ2RlZXBFcXVhbCcsIGFzc2VydC5kZWVwRXF1YWwpO1xuICB9XG59O1xuXG5hc3NlcnQuZGVlcFN0cmljdEVxdWFsID0gZnVuY3Rpb24gZGVlcFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKCFfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIHRydWUpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnZGVlcFN0cmljdEVxdWFsJywgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgc3RyaWN0LCBtZW1vcykge1xuICAvLyA3LjEuIEFsbCBpZGVudGljYWwgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChpc0J1ZmZlcihhY3R1YWwpICYmIGlzQnVmZmVyKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBjb21wYXJlKGFjdHVhbCwgZXhwZWN0ZWQpID09PSAwO1xuXG4gIC8vIDcuMi4gSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgRGF0ZSBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgRGF0ZSBvYmplY3QgdGhhdCByZWZlcnMgdG8gdGhlIHNhbWUgdGltZS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzRGF0ZShhY3R1YWwpICYmIHV0aWwuaXNEYXRlKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuZ2V0VGltZSgpID09PSBleHBlY3RlZC5nZXRUaW1lKCk7XG5cbiAgLy8gNy4zIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIFJlZ0V4cCBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgUmVnRXhwIG9iamVjdCB3aXRoIHRoZSBzYW1lIHNvdXJjZSBhbmRcbiAgLy8gcHJvcGVydGllcyAoYGdsb2JhbGAsIGBtdWx0aWxpbmVgLCBgbGFzdEluZGV4YCwgYGlnbm9yZUNhc2VgKS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzUmVnRXhwKGFjdHVhbCkgJiYgdXRpbC5pc1JlZ0V4cChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLnNvdXJjZSA9PT0gZXhwZWN0ZWQuc291cmNlICYmXG4gICAgICAgICAgIGFjdHVhbC5nbG9iYWwgPT09IGV4cGVjdGVkLmdsb2JhbCAmJlxuICAgICAgICAgICBhY3R1YWwubXVsdGlsaW5lID09PSBleHBlY3RlZC5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgYWN0dWFsLmxhc3RJbmRleCA9PT0gZXhwZWN0ZWQubGFzdEluZGV4ICYmXG4gICAgICAgICAgIGFjdHVhbC5pZ25vcmVDYXNlID09PSBleHBlY3RlZC5pZ25vcmVDYXNlO1xuXG4gIC8vIDcuNC4gT3RoZXIgcGFpcnMgdGhhdCBkbyBub3QgYm90aCBwYXNzIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JyxcbiAgLy8gZXF1aXZhbGVuY2UgaXMgZGV0ZXJtaW5lZCBieSA9PS5cbiAgfSBlbHNlIGlmICgoYWN0dWFsID09PSBudWxsIHx8IHR5cGVvZiBhY3R1YWwgIT09ICdvYmplY3QnKSAmJlxuICAgICAgICAgICAgIChleHBlY3RlZCA9PT0gbnVsbCB8fCB0eXBlb2YgZXhwZWN0ZWQgIT09ICdvYmplY3QnKSkge1xuICAgIHJldHVybiBzdHJpY3QgPyBhY3R1YWwgPT09IGV4cGVjdGVkIDogYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIElmIGJvdGggdmFsdWVzIGFyZSBpbnN0YW5jZXMgb2YgdHlwZWQgYXJyYXlzLCB3cmFwIHRoZWlyIHVuZGVybHlpbmdcbiAgLy8gQXJyYXlCdWZmZXJzIGluIGEgQnVmZmVyIGVhY2ggdG8gaW5jcmVhc2UgcGVyZm9ybWFuY2VcbiAgLy8gVGhpcyBvcHRpbWl6YXRpb24gcmVxdWlyZXMgdGhlIGFycmF5cyB0byBoYXZlIHRoZSBzYW1lIHR5cGUgYXMgY2hlY2tlZCBieVxuICAvLyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nIChha2EgcFRvU3RyaW5nKS4gTmV2ZXIgcGVyZm9ybSBiaW5hcnlcbiAgLy8gY29tcGFyaXNvbnMgZm9yIEZsb2F0KkFycmF5cywgdGhvdWdoLCBzaW5jZSBlLmcuICswID09PSAtMCBidXQgdGhlaXJcbiAgLy8gYml0IHBhdHRlcm5zIGFyZSBub3QgaWRlbnRpY2FsLlxuICB9IGVsc2UgaWYgKGlzVmlldyhhY3R1YWwpICYmIGlzVmlldyhleHBlY3RlZCkgJiZcbiAgICAgICAgICAgICBwVG9TdHJpbmcoYWN0dWFsKSA9PT0gcFRvU3RyaW5nKGV4cGVjdGVkKSAmJlxuICAgICAgICAgICAgICEoYWN0dWFsIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5IHx8XG4gICAgICAgICAgICAgICBhY3R1YWwgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkpKSB7XG4gICAgcmV0dXJuIGNvbXBhcmUobmV3IFVpbnQ4QXJyYXkoYWN0dWFsLmJ1ZmZlciksXG4gICAgICAgICAgICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoZXhwZWN0ZWQuYnVmZmVyKSkgPT09IDA7XG5cbiAgLy8gNy41IEZvciBhbGwgb3RoZXIgT2JqZWN0IHBhaXJzLCBpbmNsdWRpbmcgQXJyYXkgb2JqZWN0cywgZXF1aXZhbGVuY2UgaXNcbiAgLy8gZGV0ZXJtaW5lZCBieSBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGFzIHZlcmlmaWVkXG4gIC8vIHdpdGggT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKSwgdGhlIHNhbWUgc2V0IG9mIGtleXNcbiAgLy8gKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksIGVxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeVxuICAvLyBjb3JyZXNwb25kaW5nIGtleSwgYW5kIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS4gTm90ZTogdGhpc1xuICAvLyBhY2NvdW50cyBmb3IgYm90aCBuYW1lZCBhbmQgaW5kZXhlZCBwcm9wZXJ0aWVzIG9uIEFycmF5cy5cbiAgfSBlbHNlIGlmIChpc0J1ZmZlcihhY3R1YWwpICE9PSBpc0J1ZmZlcihleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSB7XG4gICAgbWVtb3MgPSBtZW1vcyB8fCB7YWN0dWFsOiBbXSwgZXhwZWN0ZWQ6IFtdfTtcblxuICAgIHZhciBhY3R1YWxJbmRleCA9IG1lbW9zLmFjdHVhbC5pbmRleE9mKGFjdHVhbCk7XG4gICAgaWYgKGFjdHVhbEluZGV4ICE9PSAtMSkge1xuICAgICAgaWYgKGFjdHVhbEluZGV4ID09PSBtZW1vcy5leHBlY3RlZC5pbmRleE9mKGV4cGVjdGVkKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBtZW1vcy5hY3R1YWwucHVzaChhY3R1YWwpO1xuICAgIG1lbW9zLmV4cGVjdGVkLnB1c2goZXhwZWN0ZWQpO1xuXG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQsIHN0cmljdCwgbWVtb3MpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIsIHN0cmljdCwgYWN0dWFsVmlzaXRlZE9iamVjdHMpIHtcbiAgaWYgKGEgPT09IG51bGwgfHwgYSA9PT0gdW5kZWZpbmVkIHx8IGIgPT09IG51bGwgfHwgYiA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy8gaWYgb25lIGlzIGEgcHJpbWl0aXZlLCB0aGUgb3RoZXIgbXVzdCBiZSBzYW1lXG4gIGlmICh1dGlsLmlzUHJpbWl0aXZlKGEpIHx8IHV0aWwuaXNQcmltaXRpdmUoYikpXG4gICAgcmV0dXJuIGEgPT09IGI7XG4gIGlmIChzdHJpY3QgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKGEpICE9PSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYikpXG4gICAgcmV0dXJuIGZhbHNlO1xuICB2YXIgYUlzQXJncyA9IGlzQXJndW1lbnRzKGEpO1xuICB2YXIgYklzQXJncyA9IGlzQXJndW1lbnRzKGIpO1xuICBpZiAoKGFJc0FyZ3MgJiYgIWJJc0FyZ3MpIHx8ICghYUlzQXJncyAmJiBiSXNBcmdzKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIGlmIChhSXNBcmdzKSB7XG4gICAgYSA9IHBTbGljZS5jYWxsKGEpO1xuICAgIGIgPSBwU2xpY2UuY2FsbChiKTtcbiAgICByZXR1cm4gX2RlZXBFcXVhbChhLCBiLCBzdHJpY3QpO1xuICB9XG4gIHZhciBrYSA9IG9iamVjdEtleXMoYSk7XG4gIHZhciBrYiA9IG9iamVjdEtleXMoYik7XG4gIHZhciBrZXksIGk7XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT09IGtiLmxlbmd0aClcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vdGhlIHNhbWUgc2V0IG9mIGtleXMgKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksXG4gIGthLnNvcnQoKTtcbiAga2Iuc29ydCgpO1xuICAvL35+fmNoZWFwIGtleSB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGthW2ldICE9PSBrYltpXSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvL2VxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeSBjb3JyZXNwb25kaW5nIGtleSwgYW5kXG4gIC8vfn5+cG9zc2libHkgZXhwZW5zaXZlIGRlZXAgdGVzdFxuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGtleSA9IGthW2ldO1xuICAgIGlmICghX2RlZXBFcXVhbChhW2tleV0sIGJba2V5XSwgc3RyaWN0LCBhY3R1YWxWaXNpdGVkT2JqZWN0cykpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIDguIFRoZSBub24tZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGZvciBhbnkgZGVlcCBpbmVxdWFsaXR5LlxuLy8gYXNzZXJ0Lm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3REZWVwRXF1YWwgPSBmdW5jdGlvbiBub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBmYWxzZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdub3REZWVwRXF1YWwnLCBhc3NlcnQubm90RGVlcEVxdWFsKTtcbiAgfVxufTtcblxuYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbCA9IG5vdERlZXBTdHJpY3RFcXVhbDtcbmZ1bmN0aW9uIG5vdERlZXBTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIHRydWUpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnbm90RGVlcFN0cmljdEVxdWFsJywgbm90RGVlcFN0cmljdEVxdWFsKTtcbiAgfVxufVxuXG5cbi8vIDkuIFRoZSBzdHJpY3QgZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIHN0cmljdCBlcXVhbGl0eSwgYXMgZGV0ZXJtaW5lZCBieSA9PT0uXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuc3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBzdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgIT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT09JywgYXNzZXJ0LnN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuLy8gMTAuIFRoZSBzdHJpY3Qgbm9uLWVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBmb3Igc3RyaWN0IGluZXF1YWxpdHksIGFzXG4vLyBkZXRlcm1pbmVkIGJ5ICE9PS4gIGFzc2VydC5ub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3RTdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIG5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPT0nLCBhc3NlcnQubm90U3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIGlmICghYWN0dWFsIHx8ICFleHBlY3RlZCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZXhwZWN0ZWQpID09ICdbb2JqZWN0IFJlZ0V4cF0nKSB7XG4gICAgcmV0dXJuIGV4cGVjdGVkLnRlc3QoYWN0dWFsKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgaWYgKGFjdHVhbCBpbnN0YW5jZW9mIGV4cGVjdGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBJZ25vcmUuICBUaGUgaW5zdGFuY2VvZiBjaGVjayBkb2Vzbid0IHdvcmsgZm9yIGFycm93IGZ1bmN0aW9ucy5cbiAgfVxuXG4gIGlmIChFcnJvci5pc1Byb3RvdHlwZU9mKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBleHBlY3RlZC5jYWxsKHt9LCBhY3R1YWwpID09PSB0cnVlO1xufVxuXG5mdW5jdGlvbiBfdHJ5QmxvY2soYmxvY2spIHtcbiAgdmFyIGVycm9yO1xuICB0cnkge1xuICAgIGJsb2NrKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlcnJvciA9IGU7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuXG5mdW5jdGlvbiBfdGhyb3dzKHNob3VsZFRocm93LCBibG9jaywgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgdmFyIGFjdHVhbDtcblxuICBpZiAodHlwZW9mIGJsb2NrICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJibG9ja1wiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBleHBlY3RlZCA9PT0gJ3N0cmluZycpIHtcbiAgICBtZXNzYWdlID0gZXhwZWN0ZWQ7XG4gICAgZXhwZWN0ZWQgPSBudWxsO1xuICB9XG5cbiAgYWN0dWFsID0gX3RyeUJsb2NrKGJsb2NrKTtcblxuICBtZXNzYWdlID0gKGV4cGVjdGVkICYmIGV4cGVjdGVkLm5hbWUgPyAnICgnICsgZXhwZWN0ZWQubmFtZSArICcpLicgOiAnLicpICtcbiAgICAgICAgICAgIChtZXNzYWdlID8gJyAnICsgbWVzc2FnZSA6ICcuJyk7XG5cbiAgaWYgKHNob3VsZFRocm93ICYmICFhY3R1YWwpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdNaXNzaW5nIGV4cGVjdGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIHZhciB1c2VyUHJvdmlkZWRNZXNzYWdlID0gdHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnO1xuICB2YXIgaXNVbndhbnRlZEV4Y2VwdGlvbiA9ICFzaG91bGRUaHJvdyAmJiB1dGlsLmlzRXJyb3IoYWN0dWFsKTtcbiAgdmFyIGlzVW5leHBlY3RlZEV4Y2VwdGlvbiA9ICFzaG91bGRUaHJvdyAmJiBhY3R1YWwgJiYgIWV4cGVjdGVkO1xuXG4gIGlmICgoaXNVbndhbnRlZEV4Y2VwdGlvbiAmJlxuICAgICAgdXNlclByb3ZpZGVkTWVzc2FnZSAmJlxuICAgICAgZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8XG4gICAgICBpc1VuZXhwZWN0ZWRFeGNlcHRpb24pIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdHb3QgdW53YW50ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgaWYgKChzaG91bGRUaHJvdyAmJiBhY3R1YWwgJiYgZXhwZWN0ZWQgJiZcbiAgICAgICFleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkgfHwgKCFzaG91bGRUaHJvdyAmJiBhY3R1YWwpKSB7XG4gICAgdGhyb3cgYWN0dWFsO1xuICB9XG59XG5cbi8vIDExLiBFeHBlY3RlZCB0byB0aHJvdyBhbiBlcnJvcjpcbi8vIGFzc2VydC50aHJvd3MoYmxvY2ssIEVycm9yX29wdCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQudGhyb3dzID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL2Vycm9yLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3ModHJ1ZSwgYmxvY2ssIGVycm9yLCBtZXNzYWdlKTtcbn07XG5cbi8vIEVYVEVOU0lPTiEgVGhpcyBpcyBhbm5veWluZyB0byB3cml0ZSBvdXRzaWRlIHRoaXMgbW9kdWxlLlxuYXNzZXJ0LmRvZXNOb3RUaHJvdyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzKGZhbHNlLCBibG9jaywgZXJyb3IsIG1lc3NhZ2UpO1xufTtcblxuYXNzZXJ0LmlmRXJyb3IgPSBmdW5jdGlvbihlcnIpIHsgaWYgKGVycikgdGhyb3cgZXJyOyB9O1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXNPd24uY2FsbChvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufTtcbiIsIi8vIGJhc2UteCBlbmNvZGluZ1xuLy8gRm9ya2VkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2NyeXB0b2NvaW5qcy9iczU4XG4vLyBPcmlnaW5hbGx5IHdyaXR0ZW4gYnkgTWlrZSBIZWFybiBmb3IgQml0Y29pbkpcbi8vIENvcHlyaWdodCAoYykgMjAxMSBHb29nbGUgSW5jXG4vLyBQb3J0ZWQgdG8gSmF2YVNjcmlwdCBieSBTdGVmYW4gVGhvbWFzXG4vLyBNZXJnZWQgQnVmZmVyIHJlZmFjdG9yaW5ncyBmcm9tIGJhc2U1OC1uYXRpdmUgYnkgU3RlcGhlbiBQYWlyXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTMgQml0UGF5IEluY1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJhc2UgKEFMUEhBQkVUKSB7XG4gIHZhciBBTFBIQUJFVF9NQVAgPSB7fVxuICB2YXIgQkFTRSA9IEFMUEhBQkVULmxlbmd0aFxuICB2YXIgTEVBREVSID0gQUxQSEFCRVQuY2hhckF0KDApXG5cbiAgLy8gcHJlLWNvbXB1dGUgbG9va3VwIHRhYmxlXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgQUxQSEFCRVQubGVuZ3RoOyBpKyspIHtcbiAgICBBTFBIQUJFVF9NQVBbQUxQSEFCRVQuY2hhckF0KGkpXSA9IGlcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuY29kZSAoc291cmNlKSB7XG4gICAgaWYgKHNvdXJjZS5sZW5ndGggPT09IDApIHJldHVybiAnJ1xuXG4gICAgdmFyIGRpZ2l0cyA9IFswXVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aDsgKytpKSB7XG4gICAgICBmb3IgKHZhciBqID0gMCwgY2FycnkgPSBzb3VyY2VbaV07IGogPCBkaWdpdHMubGVuZ3RoOyArK2opIHtcbiAgICAgICAgY2FycnkgKz0gZGlnaXRzW2pdIDw8IDhcbiAgICAgICAgZGlnaXRzW2pdID0gY2FycnkgJSBCQVNFXG4gICAgICAgIGNhcnJ5ID0gKGNhcnJ5IC8gQkFTRSkgfCAwXG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChjYXJyeSA+IDApIHtcbiAgICAgICAgZGlnaXRzLnB1c2goY2FycnkgJSBCQVNFKVxuICAgICAgICBjYXJyeSA9IChjYXJyeSAvIEJBU0UpIHwgMFxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBzdHJpbmcgPSAnJ1xuXG4gICAgLy8gZGVhbCB3aXRoIGxlYWRpbmcgemVyb3NcbiAgICBmb3IgKHZhciBrID0gMDsgc291cmNlW2tdID09PSAwICYmIGsgPCBzb3VyY2UubGVuZ3RoIC0gMTsgKytrKSBzdHJpbmcgKz0gQUxQSEFCRVRbMF1cbiAgICAvLyBjb252ZXJ0IGRpZ2l0cyB0byBhIHN0cmluZ1xuICAgIGZvciAodmFyIHEgPSBkaWdpdHMubGVuZ3RoIC0gMTsgcSA+PSAwOyAtLXEpIHN0cmluZyArPSBBTFBIQUJFVFtkaWdpdHNbcV1dXG5cbiAgICByZXR1cm4gc3RyaW5nXG4gIH1cblxuICBmdW5jdGlvbiBkZWNvZGVVbnNhZmUgKHN0cmluZykge1xuICAgIGlmIChzdHJpbmcubGVuZ3RoID09PSAwKSByZXR1cm4gW11cblxuICAgIHZhciBieXRlcyA9IFswXVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdmFsdWUgPSBBTFBIQUJFVF9NQVBbc3RyaW5nW2ldXVxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVyblxuXG4gICAgICBmb3IgKHZhciBqID0gMCwgY2FycnkgPSB2YWx1ZTsgaiA8IGJ5dGVzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIGNhcnJ5ICs9IGJ5dGVzW2pdICogQkFTRVxuICAgICAgICBieXRlc1tqXSA9IGNhcnJ5ICYgMHhmZlxuICAgICAgICBjYXJyeSA+Pj0gOFxuICAgICAgfVxuXG4gICAgICB3aGlsZSAoY2FycnkgPiAwKSB7XG4gICAgICAgIGJ5dGVzLnB1c2goY2FycnkgJiAweGZmKVxuICAgICAgICBjYXJyeSA+Pj0gOFxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGRlYWwgd2l0aCBsZWFkaW5nIHplcm9zXG4gICAgZm9yICh2YXIgayA9IDA7IHN0cmluZ1trXSA9PT0gTEVBREVSICYmIGsgPCBzdHJpbmcubGVuZ3RoIC0gMTsgKytrKSB7XG4gICAgICBieXRlcy5wdXNoKDApXG4gICAgfVxuXG4gICAgcmV0dXJuIGJ5dGVzLnJldmVyc2UoKVxuICB9XG5cbiAgZnVuY3Rpb24gZGVjb2RlIChzdHJpbmcpIHtcbiAgICB2YXIgYXJyYXkgPSBkZWNvZGVVbnNhZmUoc3RyaW5nKVxuICAgIGlmIChhcnJheSkgcmV0dXJuIGFycmF5XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05vbi1iYXNlJyArIEJBU0UgKyAnIGNoYXJhY3RlcicpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGVuY29kZTogZW5jb2RlLFxuICAgIGRlY29kZVVuc2FmZTogZGVjb2RlVW5zYWZlLFxuICAgIGRlY29kZTogZGVjb2RlXG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0J1xuXG5leHBvcnRzLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5leHBvcnRzLnRvQnl0ZUFycmF5ID0gdG9CeXRlQXJyYXlcbmV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IGZyb21CeXRlQXJyYXlcblxudmFyIGxvb2t1cCA9IFtdXG52YXIgcmV2TG9va3VwID0gW11cbnZhciBBcnIgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBVaW50OEFycmF5IDogQXJyYXlcblxudmFyIGNvZGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcbmZvciAodmFyIGkgPSAwLCBsZW4gPSBjb2RlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gIGxvb2t1cFtpXSA9IGNvZGVbaV1cbiAgcmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV0gPSBpXG59XG5cbi8vIFN1cHBvcnQgZGVjb2RpbmcgVVJMLXNhZmUgYmFzZTY0IHN0cmluZ3MsIGFzIE5vZGUuanMgZG9lcy5cbi8vIFNlZTogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQmFzZTY0I1VSTF9hcHBsaWNhdGlvbnNcbnJldkxvb2t1cFsnLScuY2hhckNvZGVBdCgwKV0gPSA2MlxucmV2TG9va3VwWydfJy5jaGFyQ29kZUF0KDApXSA9IDYzXG5cbmZ1bmN0aW9uIGdldExlbnMgKGI2NCkge1xuICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXG4gIGlmIChsZW4gJSA0ID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG4gIH1cblxuICAvLyBUcmltIG9mZiBleHRyYSBieXRlcyBhZnRlciBwbGFjZWhvbGRlciBieXRlcyBhcmUgZm91bmRcbiAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vYmVhdGdhbW1pdC9iYXNlNjQtanMvaXNzdWVzLzQyXG4gIHZhciB2YWxpZExlbiA9IGI2NC5pbmRleE9mKCc9JylcbiAgaWYgKHZhbGlkTGVuID09PSAtMSkgdmFsaWRMZW4gPSBsZW5cblxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gdmFsaWRMZW4gPT09IGxlblxuICAgID8gMFxuICAgIDogNCAtICh2YWxpZExlbiAlIDQpXG5cbiAgcmV0dXJuIFt2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuXVxufVxuXG4vLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKGI2NCkge1xuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiBfYnl0ZUxlbmd0aCAoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSB7XG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiB0b0J5dGVBcnJheSAoYjY0KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuXG4gIHZhciBhcnIgPSBuZXcgQXJyKF9ieXRlTGVuZ3RoKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikpXG5cbiAgdmFyIGN1ckJ5dGUgPSAwXG5cbiAgLy8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuICB2YXIgbGVuID0gcGxhY2VIb2xkZXJzTGVuID4gMFxuICAgID8gdmFsaWRMZW4gLSA0XG4gICAgOiB2YWxpZExlblxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHxcbiAgICAgIHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAyKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMSkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArXG4gICAgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9XG4gICAgICAoKHVpbnQ4W2ldIDw8IDE2KSAmIDB4RkYwMDAwKSArXG4gICAgICAoKHVpbnQ4W2kgKyAxXSA8PCA4KSAmIDB4RkYwMCkgK1xuICAgICAgKHVpbnQ4W2kgKyAyXSAmIDB4RkYpXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsoXG4gICAgICB1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpXG4gICAgKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDJdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl0gK1xuICAgICAgJz09J1xuICAgIClcbiAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgdG1wID0gKHVpbnQ4W2xlbiAtIDJdIDw8IDgpICsgdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAxMF0gK1xuICAgICAgbG9va3VwWyh0bXAgPj4gNCkgJiAweDNGXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCAyKSAmIDB4M0ZdICtcbiAgICAgICc9J1xuICAgIClcbiAgfVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuIiwiLy8gKHB1YmxpYykgQ29uc3RydWN0b3JcbmZ1bmN0aW9uIEJpZ0ludGVnZXIoYSwgYiwgYykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQmlnSW50ZWdlcikpXG4gICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGEsIGIsIGMpXG5cbiAgaWYgKGEgIT0gbnVsbCkge1xuICAgIGlmIChcIm51bWJlclwiID09IHR5cGVvZiBhKSB0aGlzLmZyb21OdW1iZXIoYSwgYiwgYylcbiAgICBlbHNlIGlmIChiID09IG51bGwgJiYgXCJzdHJpbmdcIiAhPSB0eXBlb2YgYSkgdGhpcy5mcm9tU3RyaW5nKGEsIDI1NilcbiAgICBlbHNlIHRoaXMuZnJvbVN0cmluZyhhLCBiKVxuICB9XG59XG5cbnZhciBwcm90byA9IEJpZ0ludGVnZXIucHJvdG90eXBlXG5cbi8vIGR1Y2stdHlwZWQgaXNCaWdJbnRlZ2VyXG5wcm90by5fX2JpZ2kgPSByZXF1aXJlKDMzKS52ZXJzaW9uXG5CaWdJbnRlZ2VyLmlzQmlnSW50ZWdlciA9IGZ1bmN0aW9uIChvYmosIGNoZWNrX3Zlcikge1xuICByZXR1cm4gb2JqICYmIG9iai5fX2JpZ2kgJiYgKCFjaGVja192ZXIgfHwgb2JqLl9fYmlnaSA9PT0gcHJvdG8uX19iaWdpKVxufVxuXG4vLyBCaXRzIHBlciBkaWdpdFxudmFyIGRiaXRzXG5cbi8vIGFtOiBDb21wdXRlIHdfaiArPSAoeCp0aGlzX2kpLCBwcm9wYWdhdGUgY2Fycmllcyxcbi8vIGMgaXMgaW5pdGlhbCBjYXJyeSwgcmV0dXJucyBmaW5hbCBjYXJyeS5cbi8vIGMgPCAzKmR2YWx1ZSwgeCA8IDIqZHZhbHVlLCB0aGlzX2kgPCBkdmFsdWVcbi8vIFdlIG5lZWQgdG8gc2VsZWN0IHRoZSBmYXN0ZXN0IG9uZSB0aGF0IHdvcmtzIGluIHRoaXMgZW52aXJvbm1lbnQuXG5cbi8vIGFtMTogdXNlIGEgc2luZ2xlIG11bHQgYW5kIGRpdmlkZSB0byBnZXQgdGhlIGhpZ2ggYml0cyxcbi8vIG1heCBkaWdpdCBiaXRzIHNob3VsZCBiZSAyNiBiZWNhdXNlXG4vLyBtYXggaW50ZXJuYWwgdmFsdWUgPSAyKmR2YWx1ZV4yLTIqZHZhbHVlICg8IDJeNTMpXG5mdW5jdGlvbiBhbTEoaSwgeCwgdywgaiwgYywgbikge1xuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgdiA9IHggKiB0aGlzW2krK10gKyB3W2pdICsgY1xuICAgIGMgPSBNYXRoLmZsb29yKHYgLyAweDQwMDAwMDApXG4gICAgd1tqKytdID0gdiAmIDB4M2ZmZmZmZlxuICB9XG4gIHJldHVybiBjXG59XG4vLyBhbTIgYXZvaWRzIGEgYmlnIG11bHQtYW5kLWV4dHJhY3QgY29tcGxldGVseS5cbi8vIE1heCBkaWdpdCBiaXRzIHNob3VsZCBiZSA8PSAzMCBiZWNhdXNlIHdlIGRvIGJpdHdpc2Ugb3BzXG4vLyBvbiB2YWx1ZXMgdXAgdG8gMipoZHZhbHVlXjItaGR2YWx1ZS0xICg8IDJeMzEpXG5mdW5jdGlvbiBhbTIoaSwgeCwgdywgaiwgYywgbikge1xuICB2YXIgeGwgPSB4ICYgMHg3ZmZmLFxuICAgIHhoID0geCA+PiAxNVxuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgbCA9IHRoaXNbaV0gJiAweDdmZmZcbiAgICB2YXIgaCA9IHRoaXNbaSsrXSA+PiAxNVxuICAgIHZhciBtID0geGggKiBsICsgaCAqIHhsXG4gICAgbCA9IHhsICogbCArICgobSAmIDB4N2ZmZikgPDwgMTUpICsgd1tqXSArIChjICYgMHgzZmZmZmZmZilcbiAgICBjID0gKGwgPj4+IDMwKSArIChtID4+PiAxNSkgKyB4aCAqIGggKyAoYyA+Pj4gMzApXG4gICAgd1tqKytdID0gbCAmIDB4M2ZmZmZmZmZcbiAgfVxuICByZXR1cm4gY1xufVxuLy8gQWx0ZXJuYXRlbHksIHNldCBtYXggZGlnaXQgYml0cyB0byAyOCBzaW5jZSBzb21lXG4vLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuXG5mdW5jdGlvbiBhbTMoaSwgeCwgdywgaiwgYywgbikge1xuICB2YXIgeGwgPSB4ICYgMHgzZmZmLFxuICAgIHhoID0geCA+PiAxNFxuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgbCA9IHRoaXNbaV0gJiAweDNmZmZcbiAgICB2YXIgaCA9IHRoaXNbaSsrXSA+PiAxNFxuICAgIHZhciBtID0geGggKiBsICsgaCAqIHhsXG4gICAgbCA9IHhsICogbCArICgobSAmIDB4M2ZmZikgPDwgMTQpICsgd1tqXSArIGNcbiAgICBjID0gKGwgPj4gMjgpICsgKG0gPj4gMTQpICsgeGggKiBoXG4gICAgd1tqKytdID0gbCAmIDB4ZmZmZmZmZlxuICB9XG4gIHJldHVybiBjXG59XG5cbi8vIHd0Zj9cbkJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0xXG5kYml0cyA9IDI2XG5cbkJpZ0ludGVnZXIucHJvdG90eXBlLkRCID0gZGJpdHNcbkJpZ0ludGVnZXIucHJvdG90eXBlLkRNID0gKCgxIDw8IGRiaXRzKSAtIDEpXG52YXIgRFYgPSBCaWdJbnRlZ2VyLnByb3RvdHlwZS5EViA9ICgxIDw8IGRiaXRzKVxuXG52YXIgQklfRlAgPSA1MlxuQmlnSW50ZWdlci5wcm90b3R5cGUuRlYgPSBNYXRoLnBvdygyLCBCSV9GUClcbkJpZ0ludGVnZXIucHJvdG90eXBlLkYxID0gQklfRlAgLSBkYml0c1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyICogZGJpdHMgLSBCSV9GUFxuXG4vLyBEaWdpdCBjb252ZXJzaW9uc1xudmFyIEJJX1JNID0gXCIwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIlxudmFyIEJJX1JDID0gbmV3IEFycmF5KClcbnZhciByciwgdnZcbnJyID0gXCIwXCIuY2hhckNvZGVBdCgwKVxuZm9yICh2diA9IDA7IHZ2IDw9IDk7ICsrdnYpIEJJX1JDW3JyKytdID0gdnZcbnJyID0gXCJhXCIuY2hhckNvZGVBdCgwKVxuZm9yICh2diA9IDEwOyB2diA8IDM2OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2XG5yciA9IFwiQVwiLmNoYXJDb2RlQXQoMClcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2dlxuXG5mdW5jdGlvbiBpbnQyY2hhcihuKSB7XG4gIHJldHVybiBCSV9STS5jaGFyQXQobilcbn1cblxuZnVuY3Rpb24gaW50QXQocywgaSkge1xuICB2YXIgYyA9IEJJX1JDW3MuY2hhckNvZGVBdChpKV1cbiAgcmV0dXJuIChjID09IG51bGwpID8gLTEgOiBjXG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvcHkgdGhpcyB0byByXG5mdW5jdGlvbiBibnBDb3B5VG8ocikge1xuICBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSB0aGlzW2ldXG4gIHIudCA9IHRoaXMudFxuICByLnMgPSB0aGlzLnNcbn1cblxuLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gaW50ZWdlciB2YWx1ZSB4LCAtRFYgPD0geCA8IERWXG5mdW5jdGlvbiBibnBGcm9tSW50KHgpIHtcbiAgdGhpcy50ID0gMVxuICB0aGlzLnMgPSAoeCA8IDApID8gLTEgOiAwXG4gIGlmICh4ID4gMCkgdGhpc1swXSA9IHhcbiAgZWxzZSBpZiAoeCA8IC0xKSB0aGlzWzBdID0geCArIERWXG4gIGVsc2UgdGhpcy50ID0gMFxufVxuXG4vLyByZXR1cm4gYmlnaW50IGluaXRpYWxpemVkIHRvIHZhbHVlXG5mdW5jdGlvbiBuYnYoaSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgci5mcm9tSW50KGkpXG4gIHJldHVybiByXG59XG5cbi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIHN0cmluZyBhbmQgcmFkaXhcbmZ1bmN0aW9uIGJucEZyb21TdHJpbmcocywgYikge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICB2YXIga1xuICBpZiAoYiA9PSAxNikgayA9IDRcbiAgZWxzZSBpZiAoYiA9PSA4KSBrID0gM1xuICBlbHNlIGlmIChiID09IDI1NikgayA9IDg7IC8vIGJ5dGUgYXJyYXlcbiAgZWxzZSBpZiAoYiA9PSAyKSBrID0gMVxuICBlbHNlIGlmIChiID09IDMyKSBrID0gNVxuICBlbHNlIGlmIChiID09IDQpIGsgPSAyXG4gIGVsc2Uge1xuICAgIHNlbGYuZnJvbVJhZGl4KHMsIGIpXG4gICAgcmV0dXJuXG4gIH1cbiAgc2VsZi50ID0gMFxuICBzZWxmLnMgPSAwXG4gIHZhciBpID0gcy5sZW5ndGgsXG4gICAgbWkgPSBmYWxzZSxcbiAgICBzaCA9IDBcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgdmFyIHggPSAoayA9PSA4KSA/IHNbaV0gJiAweGZmIDogaW50QXQocywgaSlcbiAgICBpZiAoeCA8IDApIHtcbiAgICAgIGlmIChzLmNoYXJBdChpKSA9PSBcIi1cIikgbWkgPSB0cnVlXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBtaSA9IGZhbHNlXG4gICAgaWYgKHNoID09IDApXG4gICAgICBzZWxmW3NlbGYudCsrXSA9IHhcbiAgICBlbHNlIGlmIChzaCArIGsgPiBzZWxmLkRCKSB7XG4gICAgICBzZWxmW3NlbGYudCAtIDFdIHw9ICh4ICYgKCgxIDw8IChzZWxmLkRCIC0gc2gpKSAtIDEpKSA8PCBzaFxuICAgICAgc2VsZltzZWxmLnQrK10gPSAoeCA+PiAoc2VsZi5EQiAtIHNoKSlcbiAgICB9IGVsc2VcbiAgICAgIHNlbGZbc2VsZi50IC0gMV0gfD0geCA8PCBzaFxuICAgIHNoICs9IGtcbiAgICBpZiAoc2ggPj0gc2VsZi5EQikgc2ggLT0gc2VsZi5EQlxuICB9XG4gIGlmIChrID09IDggJiYgKHNbMF0gJiAweDgwKSAhPSAwKSB7XG4gICAgc2VsZi5zID0gLTFcbiAgICBpZiAoc2ggPiAwKSBzZWxmW3NlbGYudCAtIDFdIHw9ICgoMSA8PCAoc2VsZi5EQiAtIHNoKSkgLSAxKSA8PCBzaFxuICB9XG4gIHNlbGYuY2xhbXAoKVxuICBpZiAobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhzZWxmLCBzZWxmKVxufVxuXG4vLyAocHJvdGVjdGVkKSBjbGFtcCBvZmYgZXhjZXNzIGhpZ2ggd29yZHNcbmZ1bmN0aW9uIGJucENsYW1wKCkge1xuICB2YXIgYyA9IHRoaXMucyAmIHRoaXMuRE1cbiAgd2hpbGUgKHRoaXMudCA+IDAgJiYgdGhpc1t0aGlzLnQgLSAxXSA9PSBjKS0tdGhpcy50XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gaW4gZ2l2ZW4gcmFkaXhcbmZ1bmN0aW9uIGJuVG9TdHJpbmcoYikge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgaWYgKHNlbGYucyA8IDApIHJldHVybiBcIi1cIiArIHNlbGYubmVnYXRlKClcbiAgICAudG9TdHJpbmcoYilcbiAgdmFyIGtcbiAgaWYgKGIgPT0gMTYpIGsgPSA0XG4gIGVsc2UgaWYgKGIgPT0gOCkgayA9IDNcbiAgZWxzZSBpZiAoYiA9PSAyKSBrID0gMVxuICBlbHNlIGlmIChiID09IDMyKSBrID0gNVxuICBlbHNlIGlmIChiID09IDQpIGsgPSAyXG4gIGVsc2UgcmV0dXJuIHNlbGYudG9SYWRpeChiKVxuICB2YXIga20gPSAoMSA8PCBrKSAtIDEsXG4gICAgZCwgbSA9IGZhbHNlLFxuICAgIHIgPSBcIlwiLFxuICAgIGkgPSBzZWxmLnRcbiAgdmFyIHAgPSBzZWxmLkRCIC0gKGkgKiBzZWxmLkRCKSAlIGtcbiAgaWYgKGktLSA+IDApIHtcbiAgICBpZiAocCA8IHNlbGYuREIgJiYgKGQgPSBzZWxmW2ldID4+IHApID4gMCkge1xuICAgICAgbSA9IHRydWVcbiAgICAgIHIgPSBpbnQyY2hhcihkKVxuICAgIH1cbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAocCA8IGspIHtcbiAgICAgICAgZCA9IChzZWxmW2ldICYgKCgxIDw8IHApIC0gMSkpIDw8IChrIC0gcClcbiAgICAgICAgZCB8PSBzZWxmWy0taV0gPj4gKHAgKz0gc2VsZi5EQiAtIGspXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkID0gKHNlbGZbaV0gPj4gKHAgLT0gaykpICYga21cbiAgICAgICAgaWYgKHAgPD0gMCkge1xuICAgICAgICAgIHAgKz0gc2VsZi5EQlxuICAgICAgICAgIC0taVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZCA+IDApIG0gPSB0cnVlXG4gICAgICBpZiAobSkgciArPSBpbnQyY2hhcihkKVxuICAgIH1cbiAgfVxuICByZXR1cm4gbSA/IHIgOiBcIjBcIlxufVxuXG4vLyAocHVibGljKSAtdGhpc1xuZnVuY3Rpb24gYm5OZWdhdGUoKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgfHRoaXN8XG5mdW5jdGlvbiBibkFicygpIHtcbiAgcmV0dXJuICh0aGlzLnMgPCAwKSA/IHRoaXMubmVnYXRlKCkgOiB0aGlzXG59XG5cbi8vIChwdWJsaWMpIHJldHVybiArIGlmIHRoaXMgPiBhLCAtIGlmIHRoaXMgPCBhLCAwIGlmIGVxdWFsXG5mdW5jdGlvbiBibkNvbXBhcmVUbyhhKSB7XG4gIHZhciByID0gdGhpcy5zIC0gYS5zXG4gIGlmIChyICE9IDApIHJldHVybiByXG4gIHZhciBpID0gdGhpcy50XG4gIHIgPSBpIC0gYS50XG4gIGlmIChyICE9IDApIHJldHVybiAodGhpcy5zIDwgMCkgPyAtciA6IHJcbiAgd2hpbGUgKC0taSA+PSAwKVxuICAgIGlmICgociA9IHRoaXNbaV0gLSBhW2ldKSAhPSAwKSByZXR1cm4gclxuICByZXR1cm4gMFxufVxuXG4vLyByZXR1cm5zIGJpdCBsZW5ndGggb2YgdGhlIGludGVnZXIgeFxuZnVuY3Rpb24gbmJpdHMoeCkge1xuICB2YXIgciA9IDEsXG4gICAgdFxuICBpZiAoKHQgPSB4ID4+PiAxNikgIT0gMCkge1xuICAgIHggPSB0XG4gICAgciArPSAxNlxuICB9XG4gIGlmICgodCA9IHggPj4gOCkgIT0gMCkge1xuICAgIHggPSB0XG4gICAgciArPSA4XG4gIH1cbiAgaWYgKCh0ID0geCA+PiA0KSAhPSAwKSB7XG4gICAgeCA9IHRcbiAgICByICs9IDRcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDIpICE9IDApIHtcbiAgICB4ID0gdFxuICAgIHIgKz0gMlxuICB9XG4gIGlmICgodCA9IHggPj4gMSkgIT0gMCkge1xuICAgIHggPSB0XG4gICAgciArPSAxXG4gIH1cbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBpbiBcInRoaXNcIlxuZnVuY3Rpb24gYm5CaXRMZW5ndGgoKSB7XG4gIGlmICh0aGlzLnQgPD0gMCkgcmV0dXJuIDBcbiAgcmV0dXJuIHRoaXMuREIgKiAodGhpcy50IC0gMSkgKyBuYml0cyh0aGlzW3RoaXMudCAtIDFdIF4gKHRoaXMucyAmIHRoaXMuRE0pKVxufVxuXG4vLyAocHVibGljKSByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBpbiBcInRoaXNcIlxuZnVuY3Rpb24gYm5CeXRlTGVuZ3RoKCkge1xuICByZXR1cm4gdGhpcy5iaXRMZW5ndGgoKSA+PiAzXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG4qREJcbmZ1bmN0aW9uIGJucERMU2hpZnRUbyhuLCByKSB7XG4gIHZhciBpXG4gIGZvciAoaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByW2kgKyBuXSA9IHRoaXNbaV1cbiAgZm9yIChpID0gbiAtIDE7IGkgPj0gMDsgLS1pKSByW2ldID0gMFxuICByLnQgPSB0aGlzLnQgKyBuXG4gIHIucyA9IHRoaXMuc1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuKkRCXG5mdW5jdGlvbiBibnBEUlNoaWZ0VG8obiwgcikge1xuICBmb3IgKHZhciBpID0gbjsgaSA8IHRoaXMudDsgKytpKSByW2kgLSBuXSA9IHRoaXNbaV1cbiAgci50ID0gTWF0aC5tYXgodGhpcy50IC0gbiwgMClcbiAgci5zID0gdGhpcy5zXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG5cbmZ1bmN0aW9uIGJucExTaGlmdFRvKG4sIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBicyA9IG4gJSBzZWxmLkRCXG4gIHZhciBjYnMgPSBzZWxmLkRCIC0gYnNcbiAgdmFyIGJtID0gKDEgPDwgY2JzKSAtIDFcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gc2VsZi5EQiksXG4gICAgYyA9IChzZWxmLnMgPDwgYnMpICYgc2VsZi5ETSxcbiAgICBpXG4gIGZvciAoaSA9IHNlbGYudCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgcltpICsgZHMgKyAxXSA9IChzZWxmW2ldID4+IGNicykgfCBjXG4gICAgYyA9IChzZWxmW2ldICYgYm0pIDw8IGJzXG4gIH1cbiAgZm9yIChpID0gZHMgLSAxOyBpID49IDA7IC0taSkgcltpXSA9IDBcbiAgcltkc10gPSBjXG4gIHIudCA9IHNlbGYudCArIGRzICsgMVxuICByLnMgPSBzZWxmLnNcbiAgci5jbGFtcCgpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzID4+IG5cbmZ1bmN0aW9uIGJucFJTaGlmdFRvKG4sIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHIucyA9IHNlbGYuc1xuICB2YXIgZHMgPSBNYXRoLmZsb29yKG4gLyBzZWxmLkRCKVxuICBpZiAoZHMgPj0gc2VsZi50KSB7XG4gICAgci50ID0gMFxuICAgIHJldHVyblxuICB9XG4gIHZhciBicyA9IG4gJSBzZWxmLkRCXG4gIHZhciBjYnMgPSBzZWxmLkRCIC0gYnNcbiAgdmFyIGJtID0gKDEgPDwgYnMpIC0gMVxuICByWzBdID0gc2VsZltkc10gPj4gYnNcbiAgZm9yICh2YXIgaSA9IGRzICsgMTsgaSA8IHNlbGYudDsgKytpKSB7XG4gICAgcltpIC0gZHMgLSAxXSB8PSAoc2VsZltpXSAmIGJtKSA8PCBjYnNcbiAgICByW2kgLSBkc10gPSBzZWxmW2ldID4+IGJzXG4gIH1cbiAgaWYgKGJzID4gMCkgcltzZWxmLnQgLSBkcyAtIDFdIHw9IChzZWxmLnMgJiBibSkgPDwgY2JzXG4gIHIudCA9IHNlbGYudCAtIGRzXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyAtIGFcbmZ1bmN0aW9uIGJucFN1YlRvKGEsIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBpID0gMCxcbiAgICBjID0gMCxcbiAgICBtID0gTWF0aC5taW4oYS50LCBzZWxmLnQpXG4gIHdoaWxlIChpIDwgbSkge1xuICAgIGMgKz0gc2VsZltpXSAtIGFbaV1cbiAgICByW2krK10gPSBjICYgc2VsZi5ETVxuICAgIGMgPj49IHNlbGYuREJcbiAgfVxuICBpZiAoYS50IDwgc2VsZi50KSB7XG4gICAgYyAtPSBhLnNcbiAgICB3aGlsZSAoaSA8IHNlbGYudCkge1xuICAgICAgYyArPSBzZWxmW2ldXG4gICAgICByW2krK10gPSBjICYgc2VsZi5ETVxuICAgICAgYyA+Pj0gc2VsZi5EQlxuICAgIH1cbiAgICBjICs9IHNlbGYuc1xuICB9IGVsc2Uge1xuICAgIGMgKz0gc2VsZi5zXG4gICAgd2hpbGUgKGkgPCBhLnQpIHtcbiAgICAgIGMgLT0gYVtpXVxuICAgICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICAgIGMgPj49IHNlbGYuREJcbiAgICB9XG4gICAgYyAtPSBhLnNcbiAgfVxuICByLnMgPSAoYyA8IDApID8gLTEgOiAwXG4gIGlmIChjIDwgLTEpIHJbaSsrXSA9IHNlbGYuRFYgKyBjXG4gIGVsc2UgaWYgKGMgPiAwKSByW2krK10gPSBjXG4gIHIudCA9IGlcbiAgci5jbGFtcCgpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICogYSwgciAhPSB0aGlzLGEgKEhBQyAxNC4xMilcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbmZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYSwgcikge1xuICB2YXIgeCA9IHRoaXMuYWJzKCksXG4gICAgeSA9IGEuYWJzKClcbiAgdmFyIGkgPSB4LnRcbiAgci50ID0gaSArIHkudFxuICB3aGlsZSAoLS1pID49IDApIHJbaV0gPSAwXG4gIGZvciAoaSA9IDA7IGkgPCB5LnQ7ICsraSkgcltpICsgeC50XSA9IHguYW0oMCwgeVtpXSwgciwgaSwgMCwgeC50KVxuICByLnMgPSAwXG4gIHIuY2xhbXAoKVxuICBpZiAodGhpcy5zICE9IGEucykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIsIHIpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzXjIsIHIgIT0gdGhpcyAoSEFDIDE0LjE2KVxuZnVuY3Rpb24gYm5wU3F1YXJlVG8ocikge1xuICB2YXIgeCA9IHRoaXMuYWJzKClcbiAgdmFyIGkgPSByLnQgPSAyICogeC50XG4gIHdoaWxlICgtLWkgPj0gMCkgcltpXSA9IDBcbiAgZm9yIChpID0gMDsgaSA8IHgudCAtIDE7ICsraSkge1xuICAgIHZhciBjID0geC5hbShpLCB4W2ldLCByLCAyICogaSwgMCwgMSlcbiAgICBpZiAoKHJbaSArIHgudF0gKz0geC5hbShpICsgMSwgMiAqIHhbaV0sIHIsIDIgKiBpICsgMSwgYywgeC50IC0gaSAtIDEpKSA+PSB4LkRWKSB7XG4gICAgICByW2kgKyB4LnRdIC09IHguRFZcbiAgICAgIHJbaSArIHgudCArIDFdID0gMVxuICAgIH1cbiAgfVxuICBpZiAoci50ID4gMCkgcltyLnQgLSAxXSArPSB4LmFtKGksIHhbaV0sIHIsIDIgKiBpLCAwLCAxKVxuICByLnMgPSAwXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSBkaXZpZGUgdGhpcyBieSBtLCBxdW90aWVudCBhbmQgcmVtYWluZGVyIHRvIHEsIHIgKEhBQyAxNC4yMClcbi8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLlxuZnVuY3Rpb24gYm5wRGl2UmVtVG8obSwgcSwgcikge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIHBtID0gbS5hYnMoKVxuICBpZiAocG0udCA8PSAwKSByZXR1cm5cbiAgdmFyIHB0ID0gc2VsZi5hYnMoKVxuICBpZiAocHQudCA8IHBtLnQpIHtcbiAgICBpZiAocSAhPSBudWxsKSBxLmZyb21JbnQoMClcbiAgICBpZiAociAhPSBudWxsKSBzZWxmLmNvcHlUbyhyKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChyID09IG51bGwpIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHZhciB5ID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICB0cyA9IHNlbGYucyxcbiAgICBtcyA9IG0uc1xuICB2YXIgbnNoID0gc2VsZi5EQiAtIG5iaXRzKHBtW3BtLnQgLSAxXSk7IC8vIG5vcm1hbGl6ZSBtb2R1bHVzXG4gIGlmIChuc2ggPiAwKSB7XG4gICAgcG0ubFNoaWZ0VG8obnNoLCB5KVxuICAgIHB0LmxTaGlmdFRvKG5zaCwgcilcbiAgfSBlbHNlIHtcbiAgICBwbS5jb3B5VG8oeSlcbiAgICBwdC5jb3B5VG8ocilcbiAgfVxuICB2YXIgeXMgPSB5LnRcbiAgdmFyIHkwID0geVt5cyAtIDFdXG4gIGlmICh5MCA9PSAwKSByZXR1cm5cbiAgdmFyIHl0ID0geTAgKiAoMSA8PCBzZWxmLkYxKSArICgoeXMgPiAxKSA/IHlbeXMgLSAyXSA+PiBzZWxmLkYyIDogMClcbiAgdmFyIGQxID0gc2VsZi5GViAvIHl0LFxuICAgIGQyID0gKDEgPDwgc2VsZi5GMSkgLyB5dCxcbiAgICBlID0gMSA8PCBzZWxmLkYyXG4gIHZhciBpID0gci50LFxuICAgIGogPSBpIC0geXMsXG4gICAgdCA9IChxID09IG51bGwpID8gbmV3IEJpZ0ludGVnZXIoKSA6IHFcbiAgeS5kbFNoaWZ0VG8oaiwgdClcbiAgaWYgKHIuY29tcGFyZVRvKHQpID49IDApIHtcbiAgICByW3IudCsrXSA9IDFcbiAgICByLnN1YlRvKHQsIHIpXG4gIH1cbiAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKHlzLCB0KVxuICB0LnN1YlRvKHksIHkpOyAvLyBcIm5lZ2F0aXZlXCIgeSBzbyB3ZSBjYW4gcmVwbGFjZSBzdWIgd2l0aCBhbSBsYXRlclxuICB3aGlsZSAoeS50IDwgeXMpIHlbeS50KytdID0gMFxuICB3aGlsZSAoLS1qID49IDApIHtcbiAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdFxuICAgIHZhciBxZCA9IChyWy0taV0gPT0geTApID8gc2VsZi5ETSA6IE1hdGguZmxvb3IocltpXSAqIGQxICsgKHJbaSAtIDFdICsgZSkgKiBkMilcbiAgICBpZiAoKHJbaV0gKz0geS5hbSgwLCBxZCwgciwgaiwgMCwgeXMpKSA8IHFkKSB7IC8vIFRyeSBpdCBvdXRcbiAgICAgIHkuZGxTaGlmdFRvKGosIHQpXG4gICAgICByLnN1YlRvKHQsIHIpXG4gICAgICB3aGlsZSAocltpXSA8IC0tcWQpIHIuc3ViVG8odCwgcilcbiAgICB9XG4gIH1cbiAgaWYgKHEgIT0gbnVsbCkge1xuICAgIHIuZHJTaGlmdFRvKHlzLCBxKVxuICAgIGlmICh0cyAhPSBtcykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHEsIHEpXG4gIH1cbiAgci50ID0geXNcbiAgci5jbGFtcCgpXG4gIGlmIChuc2ggPiAwKSByLnJTaGlmdFRvKG5zaCwgcik7IC8vIERlbm9ybWFsaXplIHJlbWFpbmRlclxuICBpZiAodHMgPCAwKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ociwgcilcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBtb2QgYVxuZnVuY3Rpb24gYm5Nb2QoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5hYnMoKVxuICAgIC5kaXZSZW1UbyhhLCBudWxsLCByKVxuICBpZiAodGhpcy5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgYS5zdWJUbyhyLCByKVxuICByZXR1cm4gclxufVxuXG4vLyBNb2R1bGFyIHJlZHVjdGlvbiB1c2luZyBcImNsYXNzaWNcIiBhbGdvcml0aG1cbmZ1bmN0aW9uIENsYXNzaWMobSkge1xuICB0aGlzLm0gPSBtXG59XG5cbmZ1bmN0aW9uIGNDb252ZXJ0KHgpIHtcbiAgaWYgKHgucyA8IDAgfHwgeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSByZXR1cm4geC5tb2QodGhpcy5tKVxuICBlbHNlIHJldHVybiB4XG59XG5cbmZ1bmN0aW9uIGNSZXZlcnQoeCkge1xuICByZXR1cm4geFxufVxuXG5mdW5jdGlvbiBjUmVkdWNlKHgpIHtcbiAgeC5kaXZSZW1Ubyh0aGlzLm0sIG51bGwsIHgpXG59XG5cbmZ1bmN0aW9uIGNNdWxUbyh4LCB5LCByKSB7XG4gIHgubXVsdGlwbHlUbyh5LCByKVxuICB0aGlzLnJlZHVjZShyKVxufVxuXG5mdW5jdGlvbiBjU3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpXG4gIHRoaXMucmVkdWNlKHIpXG59XG5cbkNsYXNzaWMucHJvdG90eXBlLmNvbnZlcnQgPSBjQ29udmVydFxuQ2xhc3NpYy5wcm90b3R5cGUucmV2ZXJ0ID0gY1JldmVydFxuQ2xhc3NpYy5wcm90b3R5cGUucmVkdWNlID0gY1JlZHVjZVxuQ2xhc3NpYy5wcm90b3R5cGUubXVsVG8gPSBjTXVsVG9cbkNsYXNzaWMucHJvdG90eXBlLnNxclRvID0gY1NxclRvXG5cbi8vIChwcm90ZWN0ZWQpIHJldHVybiBcIi0xL3RoaXMgJSAyXkRCXCI7IHVzZWZ1bCBmb3IgTW9udC4gcmVkdWN0aW9uXG4vLyBqdXN0aWZpY2F0aW9uOlxuLy8gICAgICAgICB4eSA9PSAxIChtb2QgbSlcbi8vICAgICAgICAgeHkgPSAgMStrbVxuLy8gICB4eSgyLXh5KSA9ICgxK2ttKSgxLWttKVxuLy8geFt5KDIteHkpXSA9IDEta14ybV4yXG4vLyB4W3koMi14eSldID09IDEgKG1vZCBtXjIpXG4vLyBpZiB5IGlzIDEveCBtb2QgbSwgdGhlbiB5KDIteHkpIGlzIDEveCBtb2QgbV4yXG4vLyBzaG91bGQgcmVkdWNlIHggYW5kIHkoMi14eSkgYnkgbV4yIGF0IGVhY2ggc3RlcCB0byBrZWVwIHNpemUgYm91bmRlZC5cbi8vIEpTIG11bHRpcGx5IFwib3ZlcmZsb3dzXCIgZGlmZmVyZW50bHkgZnJvbSBDL0MrKywgc28gY2FyZSBpcyBuZWVkZWQgaGVyZS5cbmZ1bmN0aW9uIGJucEludkRpZ2l0KCkge1xuICBpZiAodGhpcy50IDwgMSkgcmV0dXJuIDBcbiAgdmFyIHggPSB0aGlzWzBdXG4gIGlmICgoeCAmIDEpID09IDApIHJldHVybiAwXG4gIHZhciB5ID0geCAmIDM7IC8vIHkgPT0gMS94IG1vZCAyXjJcbiAgeSA9ICh5ICogKDIgLSAoeCAmIDB4ZikgKiB5KSkgJiAweGY7IC8vIHkgPT0gMS94IG1vZCAyXjRcbiAgeSA9ICh5ICogKDIgLSAoeCAmIDB4ZmYpICogeSkpICYgMHhmZjsgLy8geSA9PSAxL3ggbW9kIDJeOFxuICB5ID0gKHkgKiAoMiAtICgoKHggJiAweGZmZmYpICogeSkgJiAweGZmZmYpKSkgJiAweGZmZmY7IC8vIHkgPT0gMS94IG1vZCAyXjE2XG4gIC8vIGxhc3Qgc3RlcCAtIGNhbGN1bGF0ZSBpbnZlcnNlIG1vZCBEViBkaXJlY3RseVxuICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHNcbiAgeSA9ICh5ICogKDIgLSB4ICogeSAlIHRoaXMuRFYpKSAlIHRoaXMuRFY7IC8vIHkgPT0gMS94IG1vZCAyXmRiaXRzXG4gIC8vIHdlIHJlYWxseSB3YW50IHRoZSBuZWdhdGl2ZSBpbnZlcnNlLCBhbmQgLURWIDwgeSA8IERWXG4gIHJldHVybiAoeSA+IDApID8gdGhpcy5EViAtIHkgOiAteVxufVxuXG4vLyBNb250Z29tZXJ5IHJlZHVjdGlvblxuZnVuY3Rpb24gTW9udGdvbWVyeShtKSB7XG4gIHRoaXMubSA9IG1cbiAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKVxuICB0aGlzLm1wbCA9IHRoaXMubXAgJiAweDdmZmZcbiAgdGhpcy5tcGggPSB0aGlzLm1wID4+IDE1XG4gIHRoaXMudW0gPSAoMSA8PCAobS5EQiAtIDE1KSkgLSAxXG4gIHRoaXMubXQyID0gMiAqIG0udFxufVxuXG4vLyB4UiBtb2QgbVxuZnVuY3Rpb24gbW9udENvbnZlcnQoeCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgeC5hYnMoKVxuICAgIC5kbFNoaWZ0VG8odGhpcy5tLnQsIHIpXG4gIHIuZGl2UmVtVG8odGhpcy5tLCBudWxsLCByKVxuICBpZiAoeC5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgdGhpcy5tLnN1YlRvKHIsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIHgvUiBtb2QgbVxuZnVuY3Rpb24gbW9udFJldmVydCh4KSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB4LmNvcHlUbyhyKVxuICB0aGlzLnJlZHVjZShyKVxuICByZXR1cm4gclxufVxuXG4vLyB4ID0geC9SIG1vZCBtIChIQUMgMTQuMzIpXG5mdW5jdGlvbiBtb250UmVkdWNlKHgpIHtcbiAgd2hpbGUgKHgudCA8PSB0aGlzLm10MikgLy8gcGFkIHggc28gYW0gaGFzIGVub3VnaCByb29tIGxhdGVyXG4gICAgeFt4LnQrK10gPSAwXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tLnQ7ICsraSkge1xuICAgIC8vIGZhc3RlciB3YXkgb2YgY2FsY3VsYXRpbmcgdTAgPSB4W2ldKm1wIG1vZCBEVlxuICAgIHZhciBqID0geFtpXSAmIDB4N2ZmZlxuICAgIHZhciB1MCA9IChqICogdGhpcy5tcGwgKyAoKChqICogdGhpcy5tcGggKyAoeFtpXSA+PiAxNSkgKiB0aGlzLm1wbCkgJiB0aGlzLnVtKSA8PCAxNSkpICYgeC5ETVxuICAgIC8vIHVzZSBhbSB0byBjb21iaW5lIHRoZSBtdWx0aXBseS1zaGlmdC1hZGQgaW50byBvbmUgY2FsbFxuICAgIGogPSBpICsgdGhpcy5tLnRcbiAgICB4W2pdICs9IHRoaXMubS5hbSgwLCB1MCwgeCwgaSwgMCwgdGhpcy5tLnQpXG4gICAgLy8gcHJvcGFnYXRlIGNhcnJ5XG4gICAgd2hpbGUgKHhbal0gPj0geC5EVikge1xuICAgICAgeFtqXSAtPSB4LkRWXG4gICAgICB4Wysral0rK1xuICAgIH1cbiAgfVxuICB4LmNsYW1wKClcbiAgeC5kclNoaWZ0VG8odGhpcy5tLnQsIHgpXG4gIGlmICh4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHguc3ViVG8odGhpcy5tLCB4KVxufVxuXG4vLyByID0gXCJ4XjIvUiBtb2QgbVwiOyB4ICE9IHJcbmZ1bmN0aW9uIG1vbnRTcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocilcbiAgdGhpcy5yZWR1Y2Uocilcbn1cblxuLy8gciA9IFwieHkvUiBtb2QgbVwiOyB4LHkgIT0gclxuZnVuY3Rpb24gbW9udE11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpXG4gIHRoaXMucmVkdWNlKHIpXG59XG5cbk1vbnRnb21lcnkucHJvdG90eXBlLmNvbnZlcnQgPSBtb250Q29udmVydFxuTW9udGdvbWVyeS5wcm90b3R5cGUucmV2ZXJ0ID0gbW9udFJldmVydFxuTW9udGdvbWVyeS5wcm90b3R5cGUucmVkdWNlID0gbW9udFJlZHVjZVxuTW9udGdvbWVyeS5wcm90b3R5cGUubXVsVG8gPSBtb250TXVsVG9cbk1vbnRnb21lcnkucHJvdG90eXBlLnNxclRvID0gbW9udFNxclRvXG5cbi8vIChwcm90ZWN0ZWQpIHRydWUgaWZmIHRoaXMgaXMgZXZlblxuZnVuY3Rpb24gYm5wSXNFdmVuKCkge1xuICByZXR1cm4gKCh0aGlzLnQgPiAwKSA/ICh0aGlzWzBdICYgMSkgOiB0aGlzLnMpID09IDBcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpc15lLCBlIDwgMl4zMiwgZG9pbmcgc3FyIGFuZCBtdWwgd2l0aCBcInJcIiAoSEFDIDE0Ljc5KVxuZnVuY3Rpb24gYm5wRXhwKGUsIHopIHtcbiAgaWYgKGUgPiAweGZmZmZmZmZmIHx8IGUgPCAxKSByZXR1cm4gQmlnSW50ZWdlci5PTkVcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpLFxuICAgIHIyID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICBnID0gei5jb252ZXJ0KHRoaXMpLFxuICAgIGkgPSBuYml0cyhlKSAtIDFcbiAgZy5jb3B5VG8ocilcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgei5zcXJUbyhyLCByMilcbiAgICBpZiAoKGUgJiAoMSA8PCBpKSkgPiAwKSB6Lm11bFRvKHIyLCBnLCByKVxuICAgIGVsc2Uge1xuICAgICAgdmFyIHQgPSByXG4gICAgICByID0gcjJcbiAgICAgIHIyID0gdFxuICAgIH1cbiAgfVxuICByZXR1cm4gei5yZXZlcnQocilcbn1cblxuLy8gKHB1YmxpYykgdGhpc15lICUgbSwgMCA8PSBlIDwgMl4zMlxuZnVuY3Rpb24gYm5Nb2RQb3dJbnQoZSwgbSkge1xuICB2YXIgelxuICBpZiAoZSA8IDI1NiB8fCBtLmlzRXZlbigpKSB6ID0gbmV3IENsYXNzaWMobSlcbiAgZWxzZSB6ID0gbmV3IE1vbnRnb21lcnkobSlcbiAgcmV0dXJuIHRoaXMuZXhwKGUsIHopXG59XG5cbi8vIHByb3RlY3RlZFxucHJvdG8uY29weVRvID0gYm5wQ29weVRvXG5wcm90by5mcm9tSW50ID0gYm5wRnJvbUludFxucHJvdG8uZnJvbVN0cmluZyA9IGJucEZyb21TdHJpbmdcbnByb3RvLmNsYW1wID0gYm5wQ2xhbXBcbnByb3RvLmRsU2hpZnRUbyA9IGJucERMU2hpZnRUb1xucHJvdG8uZHJTaGlmdFRvID0gYm5wRFJTaGlmdFRvXG5wcm90by5sU2hpZnRUbyA9IGJucExTaGlmdFRvXG5wcm90by5yU2hpZnRUbyA9IGJucFJTaGlmdFRvXG5wcm90by5zdWJUbyA9IGJucFN1YlRvXG5wcm90by5tdWx0aXBseVRvID0gYm5wTXVsdGlwbHlUb1xucHJvdG8uc3F1YXJlVG8gPSBibnBTcXVhcmVUb1xucHJvdG8uZGl2UmVtVG8gPSBibnBEaXZSZW1Ub1xucHJvdG8uaW52RGlnaXQgPSBibnBJbnZEaWdpdFxucHJvdG8uaXNFdmVuID0gYm5wSXNFdmVuXG5wcm90by5leHAgPSBibnBFeHBcblxuLy8gcHVibGljXG5wcm90by50b1N0cmluZyA9IGJuVG9TdHJpbmdcbnByb3RvLm5lZ2F0ZSA9IGJuTmVnYXRlXG5wcm90by5hYnMgPSBibkFic1xucHJvdG8uY29tcGFyZVRvID0gYm5Db21wYXJlVG9cbnByb3RvLmJpdExlbmd0aCA9IGJuQml0TGVuZ3RoXG5wcm90by5ieXRlTGVuZ3RoID0gYm5CeXRlTGVuZ3RoXG5wcm90by5tb2QgPSBibk1vZFxucHJvdG8ubW9kUG93SW50ID0gYm5Nb2RQb3dJbnRcblxuLy8gKHB1YmxpYylcbmZ1bmN0aW9uIGJuQ2xvbmUoKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmNvcHlUbyhyKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgaW50ZWdlclxuZnVuY3Rpb24gYm5JbnRWYWx1ZSgpIHtcbiAgaWYgKHRoaXMucyA8IDApIHtcbiAgICBpZiAodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdIC0gdGhpcy5EVlxuICAgIGVsc2UgaWYgKHRoaXMudCA9PSAwKSByZXR1cm4gLTFcbiAgfSBlbHNlIGlmICh0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXNbMF1cbiAgZWxzZSBpZiAodGhpcy50ID09IDApIHJldHVybiAwXG4gIC8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyXG4gIHJldHVybiAoKHRoaXNbMV0gJiAoKDEgPDwgKDMyIC0gdGhpcy5EQikpIC0gMSkpIDw8IHRoaXMuREIpIHwgdGhpc1swXVxufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgYnl0ZVxuZnVuY3Rpb24gYm5CeXRlVmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMjQpID4+IDI0XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBzaG9ydCAoYXNzdW1lcyBEQj49MTYpXG5mdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMTYpID4+IDE2XG59XG5cbi8vIChwcm90ZWN0ZWQpIHJldHVybiB4IHMudC4gcl54IDwgRFZcbmZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yICogdGhpcy5EQiAvIE1hdGgubG9nKHIpKVxufVxuXG4vLyAocHVibGljKSAwIGlmIHRoaXMgPT0gMCwgMSBpZiB0aGlzID4gMFxuZnVuY3Rpb24gYm5TaWdOdW0oKSB7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gLTFcbiAgZWxzZSBpZiAodGhpcy50IDw9IDAgfHwgKHRoaXMudCA9PSAxICYmIHRoaXNbMF0gPD0gMCkpIHJldHVybiAwXG4gIGVsc2UgcmV0dXJuIDFcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmdcbmZ1bmN0aW9uIGJucFRvUmFkaXgoYikge1xuICBpZiAoYiA9PSBudWxsKSBiID0gMTBcbiAgaWYgKHRoaXMuc2lnbnVtKCkgPT0gMCB8fCBiIDwgMiB8fCBiID4gMzYpIHJldHVybiBcIjBcIlxuICB2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKVxuICB2YXIgYSA9IE1hdGgucG93KGIsIGNzKVxuICB2YXIgZCA9IG5idihhKSxcbiAgICB5ID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICB6ID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICByID0gXCJcIlxuICB0aGlzLmRpdlJlbVRvKGQsIHksIHopXG4gIHdoaWxlICh5LnNpZ251bSgpID4gMCkge1xuICAgIHIgPSAoYSArIHouaW50VmFsdWUoKSlcbiAgICAgIC50b1N0cmluZyhiKVxuICAgICAgLnN1YnN0cigxKSArIHJcbiAgICB5LmRpdlJlbVRvKGQsIHksIHopXG4gIH1cbiAgcmV0dXJuIHouaW50VmFsdWUoKVxuICAgIC50b1N0cmluZyhiKSArIHJcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCBmcm9tIHJhZGl4IHN0cmluZ1xuZnVuY3Rpb24gYm5wRnJvbVJhZGl4KHMsIGIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHNlbGYuZnJvbUludCgwKVxuICBpZiAoYiA9PSBudWxsKSBiID0gMTBcbiAgdmFyIGNzID0gc2VsZi5jaHVua1NpemUoYilcbiAgdmFyIGQgPSBNYXRoLnBvdyhiLCBjcyksXG4gICAgbWkgPSBmYWxzZSxcbiAgICBqID0gMCxcbiAgICB3ID0gMFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgeCA9IGludEF0KHMsIGkpXG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBpZiAocy5jaGFyQXQoaSkgPT0gXCItXCIgJiYgc2VsZi5zaWdudW0oKSA9PSAwKSBtaSA9IHRydWVcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIHcgPSBiICogdyArIHhcbiAgICBpZiAoKytqID49IGNzKSB7XG4gICAgICBzZWxmLmRNdWx0aXBseShkKVxuICAgICAgc2VsZi5kQWRkT2Zmc2V0KHcsIDApXG4gICAgICBqID0gMFxuICAgICAgdyA9IDBcbiAgICB9XG4gIH1cbiAgaWYgKGogPiAwKSB7XG4gICAgc2VsZi5kTXVsdGlwbHkoTWF0aC5wb3coYiwgaikpXG4gICAgc2VsZi5kQWRkT2Zmc2V0KHcsIDApXG4gIH1cbiAgaWYgKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8oc2VsZiwgc2VsZilcbn1cblxuLy8gKHByb3RlY3RlZCkgYWx0ZXJuYXRlIGNvbnN0cnVjdG9yXG5mdW5jdGlvbiBibnBGcm9tTnVtYmVyKGEsIGIsIGMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmIChcIm51bWJlclwiID09IHR5cGVvZiBiKSB7XG4gICAgLy8gbmV3IEJpZ0ludGVnZXIoaW50LGludCxSTkcpXG4gICAgaWYgKGEgPCAyKSBzZWxmLmZyb21JbnQoMSlcbiAgICBlbHNlIHtcbiAgICAgIHNlbGYuZnJvbU51bWJlcihhLCBjKVxuICAgICAgaWYgKCFzZWxmLnRlc3RCaXQoYSAtIDEpKSAvLyBmb3JjZSBNU0Igc2V0XG4gICAgICAgIHNlbGYuYml0d2lzZVRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhIC0gMSksIG9wX29yLCBzZWxmKVxuICAgICAgaWYgKHNlbGYuaXNFdmVuKCkpIHNlbGYuZEFkZE9mZnNldCgxLCAwKTsgLy8gZm9yY2Ugb2RkXG4gICAgICB3aGlsZSAoIXNlbGYuaXNQcm9iYWJsZVByaW1lKGIpKSB7XG4gICAgICAgIHNlbGYuZEFkZE9mZnNldCgyLCAwKVxuICAgICAgICBpZiAoc2VsZi5iaXRMZW5ndGgoKSA+IGEpIHNlbGYuc3ViVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEgLSAxKSwgc2VsZilcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gbmV3IEJpZ0ludGVnZXIoaW50LFJORylcbiAgICB2YXIgeCA9IG5ldyBBcnJheSgpLFxuICAgICAgdCA9IGEgJiA3XG4gICAgeC5sZW5ndGggPSAoYSA+PiAzKSArIDFcbiAgICBiLm5leHRCeXRlcyh4KVxuICAgIGlmICh0ID4gMCkgeFswXSAmPSAoKDEgPDwgdCkgLSAxKVxuICAgIGVsc2UgeFswXSA9IDBcbiAgICBzZWxmLmZyb21TdHJpbmcoeCwgMjU2KVxuICB9XG59XG5cbi8vIChwdWJsaWMpIGNvbnZlcnQgdG8gYmlnZW5kaWFuIGJ5dGUgYXJyYXlcbmZ1bmN0aW9uIGJuVG9CeXRlQXJyYXkoKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgaSA9IHNlbGYudCxcbiAgICByID0gbmV3IEFycmF5KClcbiAgclswXSA9IHNlbGYuc1xuICB2YXIgcCA9IHNlbGYuREIgLSAoaSAqIHNlbGYuREIpICUgOCxcbiAgICBkLCBrID0gMFxuICBpZiAoaS0tID4gMCkge1xuICAgIGlmIChwIDwgc2VsZi5EQiAmJiAoZCA9IHNlbGZbaV0gPj4gcCkgIT0gKHNlbGYucyAmIHNlbGYuRE0pID4+IHApXG4gICAgICByW2srK10gPSBkIHwgKHNlbGYucyA8PCAoc2VsZi5EQiAtIHApKVxuICAgIHdoaWxlIChpID49IDApIHtcbiAgICAgIGlmIChwIDwgOCkge1xuICAgICAgICBkID0gKHNlbGZbaV0gJiAoKDEgPDwgcCkgLSAxKSkgPDwgKDggLSBwKVxuICAgICAgICBkIHw9IHNlbGZbLS1pXSA+PiAocCArPSBzZWxmLkRCIC0gOClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGQgPSAoc2VsZltpXSA+PiAocCAtPSA4KSkgJiAweGZmXG4gICAgICAgIGlmIChwIDw9IDApIHtcbiAgICAgICAgICBwICs9IHNlbGYuREJcbiAgICAgICAgICAtLWlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKChkICYgMHg4MCkgIT0gMCkgZCB8PSAtMjU2XG4gICAgICBpZiAoayA9PT0gMCAmJiAoc2VsZi5zICYgMHg4MCkgIT0gKGQgJiAweDgwKSkrK2tcbiAgICAgIGlmIChrID4gMCB8fCBkICE9IHNlbGYucykgcltrKytdID0gZFxuICAgIH1cbiAgfVxuICByZXR1cm4gclxufVxuXG5mdW5jdGlvbiBibkVxdWFscyhhKSB7XG4gIHJldHVybiAodGhpcy5jb21wYXJlVG8oYSkgPT0gMClcbn1cblxuZnVuY3Rpb24gYm5NaW4oYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpIDwgMCkgPyB0aGlzIDogYVxufVxuXG5mdW5jdGlvbiBibk1heChhKSB7XG4gIHJldHVybiAodGhpcy5jb21wYXJlVG8oYSkgPiAwKSA/IHRoaXMgOiBhXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIG9wIGEgKGJpdHdpc2UpXG5mdW5jdGlvbiBibnBCaXR3aXNlVG8oYSwgb3AsIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBpLCBmLCBtID0gTWF0aC5taW4oYS50LCBzZWxmLnQpXG4gIGZvciAoaSA9IDA7IGkgPCBtOyArK2kpIHJbaV0gPSBvcChzZWxmW2ldLCBhW2ldKVxuICBpZiAoYS50IDwgc2VsZi50KSB7XG4gICAgZiA9IGEucyAmIHNlbGYuRE1cbiAgICBmb3IgKGkgPSBtOyBpIDwgc2VsZi50OyArK2kpIHJbaV0gPSBvcChzZWxmW2ldLCBmKVxuICAgIHIudCA9IHNlbGYudFxuICB9IGVsc2Uge1xuICAgIGYgPSBzZWxmLnMgJiBzZWxmLkRNXG4gICAgZm9yIChpID0gbTsgaSA8IGEudDsgKytpKSByW2ldID0gb3AoZiwgYVtpXSlcbiAgICByLnQgPSBhLnRcbiAgfVxuICByLnMgPSBvcChzZWxmLnMsIGEucylcbiAgci5jbGFtcCgpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgJiBhXG5mdW5jdGlvbiBvcF9hbmQoeCwgeSkge1xuICByZXR1cm4geCAmIHlcbn1cblxuZnVuY3Rpb24gYm5BbmQoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfYW5kLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzIHwgYVxuZnVuY3Rpb24gb3Bfb3IoeCwgeSkge1xuICByZXR1cm4geCB8IHlcbn1cblxuZnVuY3Rpb24gYm5PcihhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF9vciwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBeIGFcbmZ1bmN0aW9uIG9wX3hvcih4LCB5KSB7XG4gIHJldHVybiB4IF4geVxufVxuXG5mdW5jdGlvbiBiblhvcihhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF94b3IsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgJiB+YVxuZnVuY3Rpb24gb3BfYW5kbm90KHgsIHkpIHtcbiAgcmV0dXJuIHggJiB+eVxufVxuXG5mdW5jdGlvbiBibkFuZE5vdChhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF9hbmRub3QsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIH50aGlzXG5mdW5jdGlvbiBibk5vdCgpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSB0aGlzLkRNICYgfnRoaXNbaV1cbiAgci50ID0gdGhpcy50XG4gIHIucyA9IH50aGlzLnNcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyA8PCBuXG5mdW5jdGlvbiBiblNoaWZ0TGVmdChuKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICBpZiAobiA8IDApIHRoaXMuclNoaWZ0VG8oLW4sIHIpXG4gIGVsc2UgdGhpcy5sU2hpZnRUbyhuLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzID4+IG5cbmZ1bmN0aW9uIGJuU2hpZnRSaWdodChuKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICBpZiAobiA8IDApIHRoaXMubFNoaWZ0VG8oLW4sIHIpXG4gIGVsc2UgdGhpcy5yU2hpZnRUbyhuLCByKVxuICByZXR1cm4gclxufVxuXG4vLyByZXR1cm4gaW5kZXggb2YgbG93ZXN0IDEtYml0IGluIHgsIHggPCAyXjMxXG5mdW5jdGlvbiBsYml0KHgpIHtcbiAgaWYgKHggPT0gMCkgcmV0dXJuIC0xXG4gIHZhciByID0gMFxuICBpZiAoKHggJiAweGZmZmYpID09IDApIHtcbiAgICB4ID4+PSAxNlxuICAgIHIgKz0gMTZcbiAgfVxuICBpZiAoKHggJiAweGZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gOFxuICAgIHIgKz0gOFxuICB9XG4gIGlmICgoeCAmIDB4ZikgPT0gMCkge1xuICAgIHggPj49IDRcbiAgICByICs9IDRcbiAgfVxuICBpZiAoKHggJiAzKSA9PSAwKSB7XG4gICAgeCA+Pj0gMlxuICAgIHIgKz0gMlxuICB9XG4gIGlmICgoeCAmIDEpID09IDApKytyXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHJldHVybnMgaW5kZXggb2YgbG93ZXN0IDEtYml0IChvciAtMSBpZiBub25lKVxuZnVuY3Rpb24gYm5HZXRMb3dlc3RTZXRCaXQoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpXG4gICAgaWYgKHRoaXNbaV0gIT0gMCkgcmV0dXJuIGkgKiB0aGlzLkRCICsgbGJpdCh0aGlzW2ldKVxuICBpZiAodGhpcy5zIDwgMCkgcmV0dXJuIHRoaXMudCAqIHRoaXMuREJcbiAgcmV0dXJuIC0xXG59XG5cbi8vIHJldHVybiBudW1iZXIgb2YgMSBiaXRzIGluIHhcbmZ1bmN0aW9uIGNiaXQoeCkge1xuICB2YXIgciA9IDBcbiAgd2hpbGUgKHggIT0gMCkge1xuICAgIHggJj0geCAtIDFcbiAgICArK3JcbiAgfVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSByZXR1cm4gbnVtYmVyIG9mIHNldCBiaXRzXG5mdW5jdGlvbiBibkJpdENvdW50KCkge1xuICB2YXIgciA9IDAsXG4gICAgeCA9IHRoaXMucyAmIHRoaXMuRE1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSkgciArPSBjYml0KHRoaXNbaV0gXiB4KVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldFxuZnVuY3Rpb24gYm5UZXN0Qml0KG4pIHtcbiAgdmFyIGogPSBNYXRoLmZsb29yKG4gLyB0aGlzLkRCKVxuICBpZiAoaiA+PSB0aGlzLnQpIHJldHVybiAodGhpcy5zICE9IDApXG4gIHJldHVybiAoKHRoaXNbal0gJiAoMSA8PCAobiAlIHRoaXMuREIpKSkgIT0gMClcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyBvcCAoMTw8bilcbmZ1bmN0aW9uIGJucENoYW5nZUJpdChuLCBvcCkge1xuICB2YXIgciA9IEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChuKVxuICB0aGlzLmJpdHdpc2VUbyhyLCBvcCwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyB8ICgxPDxuKVxuZnVuY3Rpb24gYm5TZXRCaXQobikge1xuICByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobiwgb3Bfb3IpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgJiB+KDE8PG4pXG5mdW5jdGlvbiBibkNsZWFyQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX2FuZG5vdClcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBeICgxPDxuKVxuZnVuY3Rpb24gYm5GbGlwQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX3hvcilcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgKyBhXG5mdW5jdGlvbiBibnBBZGRUbyhhLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuXG4gIHZhciBpID0gMCxcbiAgICBjID0gMCxcbiAgICBtID0gTWF0aC5taW4oYS50LCBzZWxmLnQpXG4gIHdoaWxlIChpIDwgbSkge1xuICAgIGMgKz0gc2VsZltpXSArIGFbaV1cbiAgICByW2krK10gPSBjICYgc2VsZi5ETVxuICAgIGMgPj49IHNlbGYuREJcbiAgfVxuICBpZiAoYS50IDwgc2VsZi50KSB7XG4gICAgYyArPSBhLnNcbiAgICB3aGlsZSAoaSA8IHNlbGYudCkge1xuICAgICAgYyArPSBzZWxmW2ldXG4gICAgICByW2krK10gPSBjICYgc2VsZi5ETVxuICAgICAgYyA+Pj0gc2VsZi5EQlxuICAgIH1cbiAgICBjICs9IHNlbGYuc1xuICB9IGVsc2Uge1xuICAgIGMgKz0gc2VsZi5zXG4gICAgd2hpbGUgKGkgPCBhLnQpIHtcbiAgICAgIGMgKz0gYVtpXVxuICAgICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICAgIGMgPj49IHNlbGYuREJcbiAgICB9XG4gICAgYyArPSBhLnNcbiAgfVxuICByLnMgPSAoYyA8IDApID8gLTEgOiAwXG4gIGlmIChjID4gMCkgcltpKytdID0gY1xuICBlbHNlIGlmIChjIDwgLTEpIHJbaSsrXSA9IHNlbGYuRFYgKyBjXG4gIHIudCA9IGlcbiAgci5jbGFtcCgpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgKyBhXG5mdW5jdGlvbiBibkFkZChhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmFkZFRvKGEsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgLSBhXG5mdW5jdGlvbiBiblN1YnRyYWN0KGEpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMuc3ViVG8oYSwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAqIGFcbmZ1bmN0aW9uIGJuTXVsdGlwbHkoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5tdWx0aXBseVRvKGEsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXNeMlxuZnVuY3Rpb24gYm5TcXVhcmUoKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLnNxdWFyZVRvKHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgLyBhXG5mdW5jdGlvbiBibkRpdmlkZShhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmRpdlJlbVRvKGEsIHIsIG51bGwpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgJSBhXG5mdW5jdGlvbiBiblJlbWFpbmRlcihhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLmRpdlJlbVRvKGEsIG51bGwsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIFt0aGlzL2EsdGhpcyVhXVxuZnVuY3Rpb24gYm5EaXZpZGVBbmRSZW1haW5kZXIoYSkge1xuICB2YXIgcSA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5kaXZSZW1UbyhhLCBxLCByKVxuICByZXR1cm4gbmV3IEFycmF5KHEsIHIpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgKj0gbiwgdGhpcyA+PSAwLCAxIDwgbiA8IERWXG5mdW5jdGlvbiBibnBETXVsdGlwbHkobikge1xuICB0aGlzW3RoaXMudF0gPSB0aGlzLmFtKDAsIG4gLSAxLCB0aGlzLCAwLCAwLCB0aGlzLnQpXG4gICsrdGhpcy50XG4gIHRoaXMuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzICs9IG4gPDwgdyB3b3JkcywgdGhpcyA+PSAwXG5mdW5jdGlvbiBibnBEQWRkT2Zmc2V0KG4sIHcpIHtcbiAgaWYgKG4gPT0gMCkgcmV0dXJuXG4gIHdoaWxlICh0aGlzLnQgPD0gdykgdGhpc1t0aGlzLnQrK10gPSAwXG4gIHRoaXNbd10gKz0gblxuICB3aGlsZSAodGhpc1t3XSA+PSB0aGlzLkRWKSB7XG4gICAgdGhpc1t3XSAtPSB0aGlzLkRWXG4gICAgaWYgKCsrdyA+PSB0aGlzLnQpIHRoaXNbdGhpcy50KytdID0gMFxuICAgICsrdGhpc1t3XVxuICB9XG59XG5cbi8vIEEgXCJudWxsXCIgcmVkdWNlclxuZnVuY3Rpb24gTnVsbEV4cCgpIHt9XG5cbmZ1bmN0aW9uIG5Ob3AoeCkge1xuICByZXR1cm4geFxufVxuXG5mdW5jdGlvbiBuTXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcilcbn1cblxuZnVuY3Rpb24gblNxclRvKHgsIHIpIHtcbiAgeC5zcXVhcmVUbyhyKVxufVxuXG5OdWxsRXhwLnByb3RvdHlwZS5jb252ZXJ0ID0gbk5vcFxuTnVsbEV4cC5wcm90b3R5cGUucmV2ZXJ0ID0gbk5vcFxuTnVsbEV4cC5wcm90b3R5cGUubXVsVG8gPSBuTXVsVG9cbk51bGxFeHAucHJvdG90eXBlLnNxclRvID0gblNxclRvXG5cbi8vIChwdWJsaWMpIHRoaXNeZVxuZnVuY3Rpb24gYm5Qb3coZSkge1xuICByZXR1cm4gdGhpcy5leHAoZSwgbmV3IE51bGxFeHAoKSlcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IGxvd2VyIG4gd29yZHMgb2YgXCJ0aGlzICogYVwiLCBhLnQgPD0gblxuLy8gXCJ0aGlzXCIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLlxuZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGEsIG4sIHIpIHtcbiAgdmFyIGkgPSBNYXRoLm1pbih0aGlzLnQgKyBhLnQsIG4pXG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgci50ID0gaVxuICB3aGlsZSAoaSA+IDApIHJbLS1pXSA9IDBcbiAgdmFyIGpcbiAgZm9yIChqID0gci50IC0gdGhpcy50OyBpIDwgajsgKytpKSByW2kgKyB0aGlzLnRdID0gdGhpcy5hbSgwLCBhW2ldLCByLCBpLCAwLCB0aGlzLnQpXG4gIGZvciAoaiA9IE1hdGgubWluKGEudCwgbik7IGkgPCBqOyArK2kpIHRoaXMuYW0oMCwgYVtpXSwgciwgaSwgMCwgbiAtIGkpXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gXCJ0aGlzICogYVwiIHdpdGhvdXQgbG93ZXIgbiB3b3JkcywgbiA+IDBcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbmZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhhLCBuLCByKSB7XG4gIC0tblxuICB2YXIgaSA9IHIudCA9IHRoaXMudCArIGEudCAtIG5cbiAgci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMFxuICB3aGlsZSAoLS1pID49IDApIHJbaV0gPSAwXG4gIGZvciAoaSA9IE1hdGgubWF4KG4gLSB0aGlzLnQsIDApOyBpIDwgYS50OyArK2kpXG4gICAgclt0aGlzLnQgKyBpIC0gbl0gPSB0aGlzLmFtKG4gLSBpLCBhW2ldLCByLCAwLCAwLCB0aGlzLnQgKyBpIC0gbilcbiAgci5jbGFtcCgpXG4gIHIuZHJTaGlmdFRvKDEsIHIpXG59XG5cbi8vIEJhcnJldHQgbW9kdWxhciByZWR1Y3Rpb25cbmZ1bmN0aW9uIEJhcnJldHQobSkge1xuICAvLyBzZXR1cCBCYXJyZXR0XG4gIHRoaXMucjIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMucTMgPSBuZXcgQmlnSW50ZWdlcigpXG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbygyICogbS50LCB0aGlzLnIyKVxuICB0aGlzLm11ID0gdGhpcy5yMi5kaXZpZGUobSlcbiAgdGhpcy5tID0gbVxufVxuXG5mdW5jdGlvbiBiYXJyZXR0Q29udmVydCh4KSB7XG4gIGlmICh4LnMgPCAwIHx8IHgudCA+IDIgKiB0aGlzLm0udCkgcmV0dXJuIHgubW9kKHRoaXMubSlcbiAgZWxzZSBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA8IDApIHJldHVybiB4XG4gIGVsc2Uge1xuICAgIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICAgIHguY29weVRvKHIpXG4gICAgdGhpcy5yZWR1Y2UocilcbiAgICByZXR1cm4gclxuICB9XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoeCkge1xuICByZXR1cm4geFxufVxuXG4vLyB4ID0geCBtb2QgbSAoSEFDIDE0LjQyKVxuZnVuY3Rpb24gYmFycmV0dFJlZHVjZSh4KSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB4LmRyU2hpZnRUbyhzZWxmLm0udCAtIDEsIHNlbGYucjIpXG4gIGlmICh4LnQgPiBzZWxmLm0udCArIDEpIHtcbiAgICB4LnQgPSBzZWxmLm0udCArIDFcbiAgICB4LmNsYW1wKClcbiAgfVxuICBzZWxmLm11Lm11bHRpcGx5VXBwZXJUbyhzZWxmLnIyLCBzZWxmLm0udCArIDEsIHNlbGYucTMpXG4gIHNlbGYubS5tdWx0aXBseUxvd2VyVG8oc2VsZi5xMywgc2VsZi5tLnQgKyAxLCBzZWxmLnIyKVxuICB3aGlsZSAoeC5jb21wYXJlVG8oc2VsZi5yMikgPCAwKSB4LmRBZGRPZmZzZXQoMSwgc2VsZi5tLnQgKyAxKVxuICB4LnN1YlRvKHNlbGYucjIsIHgpXG4gIHdoaWxlICh4LmNvbXBhcmVUbyhzZWxmLm0pID49IDApIHguc3ViVG8oc2VsZi5tLCB4KVxufVxuXG4vLyByID0geF4yIG1vZCBtOyB4ICE9IHJcbmZ1bmN0aW9uIGJhcnJldHRTcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocilcbiAgdGhpcy5yZWR1Y2Uocilcbn1cblxuLy8gciA9IHgqeSBtb2QgbTsgeCx5ICE9IHJcbmZ1bmN0aW9uIGJhcnJldHRNdWxUbyh4LCB5LCByKSB7XG4gIHgubXVsdGlwbHlUbyh5LCByKVxuICB0aGlzLnJlZHVjZShyKVxufVxuXG5CYXJyZXR0LnByb3RvdHlwZS5jb252ZXJ0ID0gYmFycmV0dENvbnZlcnRcbkJhcnJldHQucHJvdG90eXBlLnJldmVydCA9IGJhcnJldHRSZXZlcnRcbkJhcnJldHQucHJvdG90eXBlLnJlZHVjZSA9IGJhcnJldHRSZWR1Y2VcbkJhcnJldHQucHJvdG90eXBlLm11bFRvID0gYmFycmV0dE11bFRvXG5CYXJyZXR0LnByb3RvdHlwZS5zcXJUbyA9IGJhcnJldHRTcXJUb1xuXG4vLyAocHVibGljKSB0aGlzXmUgJSBtIChIQUMgMTQuODUpXG5mdW5jdGlvbiBibk1vZFBvdyhlLCBtKSB7XG4gIHZhciBpID0gZS5iaXRMZW5ndGgoKSxcbiAgICBrLCByID0gbmJ2KDEpLFxuICAgIHpcbiAgaWYgKGkgPD0gMCkgcmV0dXJuIHJcbiAgZWxzZSBpZiAoaSA8IDE4KSBrID0gMVxuICBlbHNlIGlmIChpIDwgNDgpIGsgPSAzXG4gIGVsc2UgaWYgKGkgPCAxNDQpIGsgPSA0XG4gIGVsc2UgaWYgKGkgPCA3NjgpIGsgPSA1XG4gIGVsc2UgayA9IDZcbiAgaWYgKGkgPCA4KVxuICAgIHogPSBuZXcgQ2xhc3NpYyhtKVxuICBlbHNlIGlmIChtLmlzRXZlbigpKVxuICAgIHogPSBuZXcgQmFycmV0dChtKVxuICBlbHNlXG4gICAgeiA9IG5ldyBNb250Z29tZXJ5KG0pXG5cbiAgLy8gcHJlY29tcHV0YXRpb25cbiAgdmFyIGcgPSBuZXcgQXJyYXkoKSxcbiAgICBuID0gMyxcbiAgICBrMSA9IGsgLSAxLFxuICAgIGttID0gKDEgPDwgaykgLSAxXG4gIGdbMV0gPSB6LmNvbnZlcnQodGhpcylcbiAgaWYgKGsgPiAxKSB7XG4gICAgdmFyIGcyID0gbmV3IEJpZ0ludGVnZXIoKVxuICAgIHouc3FyVG8oZ1sxXSwgZzIpXG4gICAgd2hpbGUgKG4gPD0ga20pIHtcbiAgICAgIGdbbl0gPSBuZXcgQmlnSW50ZWdlcigpXG4gICAgICB6Lm11bFRvKGcyLCBnW24gLSAyXSwgZ1tuXSlcbiAgICAgIG4gKz0gMlxuICAgIH1cbiAgfVxuXG4gIHZhciBqID0gZS50IC0gMSxcbiAgICB3LCBpczEgPSB0cnVlLFxuICAgIHIyID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICB0XG4gIGkgPSBuYml0cyhlW2pdKSAtIDFcbiAgd2hpbGUgKGogPj0gMCkge1xuICAgIGlmIChpID49IGsxKSB3ID0gKGVbal0gPj4gKGkgLSBrMSkpICYga21cbiAgICBlbHNlIHtcbiAgICAgIHcgPSAoZVtqXSAmICgoMSA8PCAoaSArIDEpKSAtIDEpKSA8PCAoazEgLSBpKVxuICAgICAgaWYgKGogPiAwKSB3IHw9IGVbaiAtIDFdID4+ICh0aGlzLkRCICsgaSAtIGsxKVxuICAgIH1cblxuICAgIG4gPSBrXG4gICAgd2hpbGUgKCh3ICYgMSkgPT0gMCkge1xuICAgICAgdyA+Pj0gMVxuICAgICAgLS1uXG4gICAgfVxuICAgIGlmICgoaSAtPSBuKSA8IDApIHtcbiAgICAgIGkgKz0gdGhpcy5EQlxuICAgICAgLS1qXG4gICAgfVxuICAgIGlmIChpczEpIHsgLy8gcmV0ID09IDEsIGRvbid0IGJvdGhlciBzcXVhcmluZyBvciBtdWx0aXBseWluZyBpdFxuICAgICAgZ1t3XS5jb3B5VG8ocilcbiAgICAgIGlzMSA9IGZhbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChuID4gMSkge1xuICAgICAgICB6LnNxclRvKHIsIHIyKVxuICAgICAgICB6LnNxclRvKHIyLCByKVxuICAgICAgICBuIC09IDJcbiAgICAgIH1cbiAgICAgIGlmIChuID4gMCkgei5zcXJUbyhyLCByMilcbiAgICAgIGVsc2Uge1xuICAgICAgICB0ID0gclxuICAgICAgICByID0gcjJcbiAgICAgICAgcjIgPSB0XG4gICAgICB9XG4gICAgICB6Lm11bFRvKHIyLCBnW3ddLCByKVxuICAgIH1cblxuICAgIHdoaWxlIChqID49IDAgJiYgKGVbal0gJiAoMSA8PCBpKSkgPT0gMCkge1xuICAgICAgei5zcXJUbyhyLCByMilcbiAgICAgIHQgPSByXG4gICAgICByID0gcjJcbiAgICAgIHIyID0gdFxuICAgICAgaWYgKC0taSA8IDApIHtcbiAgICAgICAgaSA9IHRoaXMuREIgLSAxXG4gICAgICAgIC0talxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gei5yZXZlcnQocilcbn1cblxuLy8gKHB1YmxpYykgZ2NkKHRoaXMsYSkgKEhBQyAxNC41NClcbmZ1bmN0aW9uIGJuR0NEKGEpIHtcbiAgdmFyIHggPSAodGhpcy5zIDwgMCkgPyB0aGlzLm5lZ2F0ZSgpIDogdGhpcy5jbG9uZSgpXG4gIHZhciB5ID0gKGEucyA8IDApID8gYS5uZWdhdGUoKSA6IGEuY2xvbmUoKVxuICBpZiAoeC5jb21wYXJlVG8oeSkgPCAwKSB7XG4gICAgdmFyIHQgPSB4XG4gICAgeCA9IHlcbiAgICB5ID0gdFxuICB9XG4gIHZhciBpID0geC5nZXRMb3dlc3RTZXRCaXQoKSxcbiAgICBnID0geS5nZXRMb3dlc3RTZXRCaXQoKVxuICBpZiAoZyA8IDApIHJldHVybiB4XG4gIGlmIChpIDwgZykgZyA9IGlcbiAgaWYgKGcgPiAwKSB7XG4gICAgeC5yU2hpZnRUbyhnLCB4KVxuICAgIHkuclNoaWZ0VG8oZywgeSlcbiAgfVxuICB3aGlsZSAoeC5zaWdudW0oKSA+IDApIHtcbiAgICBpZiAoKGkgPSB4LmdldExvd2VzdFNldEJpdCgpKSA+IDApIHguclNoaWZ0VG8oaSwgeClcbiAgICBpZiAoKGkgPSB5LmdldExvd2VzdFNldEJpdCgpKSA+IDApIHkuclNoaWZ0VG8oaSwgeSlcbiAgICBpZiAoeC5jb21wYXJlVG8oeSkgPj0gMCkge1xuICAgICAgeC5zdWJUbyh5LCB4KVxuICAgICAgeC5yU2hpZnRUbygxLCB4KVxuICAgIH0gZWxzZSB7XG4gICAgICB5LnN1YlRvKHgsIHkpXG4gICAgICB5LnJTaGlmdFRvKDEsIHkpXG4gICAgfVxuICB9XG4gIGlmIChnID4gMCkgeS5sU2hpZnRUbyhnLCB5KVxuICByZXR1cm4geVxufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzICUgbiwgbiA8IDJeMjZcbmZ1bmN0aW9uIGJucE1vZEludChuKSB7XG4gIGlmIChuIDw9IDApIHJldHVybiAwXG4gIHZhciBkID0gdGhpcy5EViAlIG4sXG4gICAgciA9ICh0aGlzLnMgPCAwKSA/IG4gLSAxIDogMFxuICBpZiAodGhpcy50ID4gMClcbiAgICBpZiAoZCA9PSAwKSByID0gdGhpc1swXSAlIG5cbiAgICBlbHNlXG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHIgPSAoZCAqIHIgKyB0aGlzW2ldKSAlIG5cbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgMS90aGlzICUgbSAoSEFDIDE0LjYxKVxuZnVuY3Rpb24gYm5Nb2RJbnZlcnNlKG0pIHtcbiAgdmFyIGFjID0gbS5pc0V2ZW4oKVxuICBpZiAodGhpcy5zaWdudW0oKSA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKCdkaXZpc2lvbiBieSB6ZXJvJylcbiAgaWYgKCh0aGlzLmlzRXZlbigpICYmIGFjKSB8fCBtLnNpZ251bSgpID09IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk9cbiAgdmFyIHUgPSBtLmNsb25lKCksXG4gICAgdiA9IHRoaXMuY2xvbmUoKVxuICB2YXIgYSA9IG5idigxKSxcbiAgICBiID0gbmJ2KDApLFxuICAgIGMgPSBuYnYoMCksXG4gICAgZCA9IG5idigxKVxuICB3aGlsZSAodS5zaWdudW0oKSAhPSAwKSB7XG4gICAgd2hpbGUgKHUuaXNFdmVuKCkpIHtcbiAgICAgIHUuclNoaWZ0VG8oMSwgdSlcbiAgICAgIGlmIChhYykge1xuICAgICAgICBpZiAoIWEuaXNFdmVuKCkgfHwgIWIuaXNFdmVuKCkpIHtcbiAgICAgICAgICBhLmFkZFRvKHRoaXMsIGEpXG4gICAgICAgICAgYi5zdWJUbyhtLCBiKVxuICAgICAgICB9XG4gICAgICAgIGEuclNoaWZ0VG8oMSwgYSlcbiAgICAgIH0gZWxzZSBpZiAoIWIuaXNFdmVuKCkpIGIuc3ViVG8obSwgYilcbiAgICAgIGIuclNoaWZ0VG8oMSwgYilcbiAgICB9XG4gICAgd2hpbGUgKHYuaXNFdmVuKCkpIHtcbiAgICAgIHYuclNoaWZ0VG8oMSwgdilcbiAgICAgIGlmIChhYykge1xuICAgICAgICBpZiAoIWMuaXNFdmVuKCkgfHwgIWQuaXNFdmVuKCkpIHtcbiAgICAgICAgICBjLmFkZFRvKHRoaXMsIGMpXG4gICAgICAgICAgZC5zdWJUbyhtLCBkKVxuICAgICAgICB9XG4gICAgICAgIGMuclNoaWZ0VG8oMSwgYylcbiAgICAgIH0gZWxzZSBpZiAoIWQuaXNFdmVuKCkpIGQuc3ViVG8obSwgZClcbiAgICAgIGQuclNoaWZ0VG8oMSwgZClcbiAgICB9XG4gICAgaWYgKHUuY29tcGFyZVRvKHYpID49IDApIHtcbiAgICAgIHUuc3ViVG8odiwgdSlcbiAgICAgIGlmIChhYykgYS5zdWJUbyhjLCBhKVxuICAgICAgYi5zdWJUbyhkLCBiKVxuICAgIH0gZWxzZSB7XG4gICAgICB2LnN1YlRvKHUsIHYpXG4gICAgICBpZiAoYWMpIGMuc3ViVG8oYSwgYylcbiAgICAgIGQuc3ViVG8oYiwgZClcbiAgICB9XG4gIH1cbiAgaWYgKHYuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPXG4gIHdoaWxlIChkLmNvbXBhcmVUbyhtKSA+PSAwKSBkLnN1YlRvKG0sIGQpXG4gIHdoaWxlIChkLnNpZ251bSgpIDwgMCkgZC5hZGRUbyhtLCBkKVxuICByZXR1cm4gZFxufVxuXG52YXIgbG93cHJpbWVzID0gW1xuICAyLCAzLCA1LCA3LCAxMSwgMTMsIDE3LCAxOSwgMjMsIDI5LCAzMSwgMzcsIDQxLCA0MywgNDcsIDUzLCA1OSwgNjEsIDY3LCA3MSxcbiAgNzMsIDc5LCA4MywgODksIDk3LCAxMDEsIDEwMywgMTA3LCAxMDksIDExMywgMTI3LCAxMzEsIDEzNywgMTM5LCAxNDksIDE1MSxcbiAgMTU3LCAxNjMsIDE2NywgMTczLCAxNzksIDE4MSwgMTkxLCAxOTMsIDE5NywgMTk5LCAyMTEsIDIyMywgMjI3LCAyMjksIDIzMyxcbiAgMjM5LCAyNDEsIDI1MSwgMjU3LCAyNjMsIDI2OSwgMjcxLCAyNzcsIDI4MSwgMjgzLCAyOTMsIDMwNywgMzExLCAzMTMsIDMxNyxcbiAgMzMxLCAzMzcsIDM0NywgMzQ5LCAzNTMsIDM1OSwgMzY3LCAzNzMsIDM3OSwgMzgzLCAzODksIDM5NywgNDAxLCA0MDksIDQxOSxcbiAgNDIxLCA0MzEsIDQzMywgNDM5LCA0NDMsIDQ0OSwgNDU3LCA0NjEsIDQ2MywgNDY3LCA0NzksIDQ4NywgNDkxLCA0OTksIDUwMyxcbiAgNTA5LCA1MjEsIDUyMywgNTQxLCA1NDcsIDU1NywgNTYzLCA1NjksIDU3MSwgNTc3LCA1ODcsIDU5MywgNTk5LCA2MDEsIDYwNyxcbiAgNjEzLCA2MTcsIDYxOSwgNjMxLCA2NDEsIDY0MywgNjQ3LCA2NTMsIDY1OSwgNjYxLCA2NzMsIDY3NywgNjgzLCA2OTEsIDcwMSxcbiAgNzA5LCA3MTksIDcyNywgNzMzLCA3MzksIDc0MywgNzUxLCA3NTcsIDc2MSwgNzY5LCA3NzMsIDc4NywgNzk3LCA4MDksIDgxMSxcbiAgODIxLCA4MjMsIDgyNywgODI5LCA4MzksIDg1MywgODU3LCA4NTksIDg2MywgODc3LCA4ODEsIDg4MywgODg3LCA5MDcsIDkxMSxcbiAgOTE5LCA5MjksIDkzNywgOTQxLCA5NDcsIDk1MywgOTY3LCA5NzEsIDk3NywgOTgzLCA5OTEsIDk5N1xuXVxuXG52YXIgbHBsaW0gPSAoMSA8PCAyNikgLyBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aCAtIDFdXG5cbi8vIChwdWJsaWMpIHRlc3QgcHJpbWFsaXR5IHdpdGggY2VydGFpbnR5ID49IDEtLjVedFxuZnVuY3Rpb24gYm5Jc1Byb2JhYmxlUHJpbWUodCkge1xuICB2YXIgaSwgeCA9IHRoaXMuYWJzKClcbiAgaWYgKHgudCA9PSAxICYmIHhbMF0gPD0gbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGggLSAxXSkge1xuICAgIGZvciAoaSA9IDA7IGkgPCBsb3dwcmltZXMubGVuZ3RoOyArK2kpXG4gICAgICBpZiAoeFswXSA9PSBsb3dwcmltZXNbaV0pIHJldHVybiB0cnVlXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgaWYgKHguaXNFdmVuKCkpIHJldHVybiBmYWxzZVxuICBpID0gMVxuICB3aGlsZSAoaSA8IGxvd3ByaW1lcy5sZW5ndGgpIHtcbiAgICB2YXIgbSA9IGxvd3ByaW1lc1tpXSxcbiAgICAgIGogPSBpICsgMVxuICAgIHdoaWxlIChqIDwgbG93cHJpbWVzLmxlbmd0aCAmJiBtIDwgbHBsaW0pIG0gKj0gbG93cHJpbWVzW2orK11cbiAgICBtID0geC5tb2RJbnQobSlcbiAgICB3aGlsZSAoaSA8IGopIGlmIChtICUgbG93cHJpbWVzW2krK10gPT0gMCkgcmV0dXJuIGZhbHNlXG4gIH1cbiAgcmV0dXJuIHgubWlsbGVyUmFiaW4odClcbn1cblxuLy8gKHByb3RlY3RlZCkgdHJ1ZSBpZiBwcm9iYWJseSBwcmltZSAoSEFDIDQuMjQsIE1pbGxlci1SYWJpbilcbmZ1bmN0aW9uIGJucE1pbGxlclJhYmluKHQpIHtcbiAgdmFyIG4xID0gdGhpcy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSlcbiAgdmFyIGsgPSBuMS5nZXRMb3dlc3RTZXRCaXQoKVxuICBpZiAoayA8PSAwKSByZXR1cm4gZmFsc2VcbiAgdmFyIHIgPSBuMS5zaGlmdFJpZ2h0KGspXG4gIHQgPSAodCArIDEpID4+IDFcbiAgaWYgKHQgPiBsb3dwcmltZXMubGVuZ3RoKSB0ID0gbG93cHJpbWVzLmxlbmd0aFxuICB2YXIgYSA9IG5ldyBCaWdJbnRlZ2VyKG51bGwpXG4gIHZhciBqLCBiYXNlcyA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdDsgKytpKSB7XG4gICAgZm9yICg7Oykge1xuICAgICAgaiA9IGxvd3ByaW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBsb3dwcmltZXMubGVuZ3RoKV1cbiAgICAgIGlmIChiYXNlcy5pbmRleE9mKGopID09IC0xKSBicmVha1xuICAgIH1cbiAgICBiYXNlcy5wdXNoKGopXG4gICAgYS5mcm9tSW50KGopXG4gICAgdmFyIHkgPSBhLm1vZFBvdyhyLCB0aGlzKVxuICAgIGlmICh5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkge1xuICAgICAgdmFyIGogPSAxXG4gICAgICB3aGlsZSAoaisrIDwgayAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkge1xuICAgICAgICB5ID0geS5tb2RQb3dJbnQoMiwgdGhpcylcbiAgICAgICAgaWYgKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICAgIGlmICh5LmNvbXBhcmVUbyhuMSkgIT0gMCkgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbi8vIHByb3RlY3RlZFxucHJvdG8uY2h1bmtTaXplID0gYm5wQ2h1bmtTaXplXG5wcm90by50b1JhZGl4ID0gYm5wVG9SYWRpeFxucHJvdG8uZnJvbVJhZGl4ID0gYm5wRnJvbVJhZGl4XG5wcm90by5mcm9tTnVtYmVyID0gYm5wRnJvbU51bWJlclxucHJvdG8uYml0d2lzZVRvID0gYm5wQml0d2lzZVRvXG5wcm90by5jaGFuZ2VCaXQgPSBibnBDaGFuZ2VCaXRcbnByb3RvLmFkZFRvID0gYm5wQWRkVG9cbnByb3RvLmRNdWx0aXBseSA9IGJucERNdWx0aXBseVxucHJvdG8uZEFkZE9mZnNldCA9IGJucERBZGRPZmZzZXRcbnByb3RvLm11bHRpcGx5TG93ZXJUbyA9IGJucE11bHRpcGx5TG93ZXJUb1xucHJvdG8ubXVsdGlwbHlVcHBlclRvID0gYm5wTXVsdGlwbHlVcHBlclRvXG5wcm90by5tb2RJbnQgPSBibnBNb2RJbnRcbnByb3RvLm1pbGxlclJhYmluID0gYm5wTWlsbGVyUmFiaW5cblxuLy8gcHVibGljXG5wcm90by5jbG9uZSA9IGJuQ2xvbmVcbnByb3RvLmludFZhbHVlID0gYm5JbnRWYWx1ZVxucHJvdG8uYnl0ZVZhbHVlID0gYm5CeXRlVmFsdWVcbnByb3RvLnNob3J0VmFsdWUgPSBiblNob3J0VmFsdWVcbnByb3RvLnNpZ251bSA9IGJuU2lnTnVtXG5wcm90by50b0J5dGVBcnJheSA9IGJuVG9CeXRlQXJyYXlcbnByb3RvLmVxdWFscyA9IGJuRXF1YWxzXG5wcm90by5taW4gPSBibk1pblxucHJvdG8ubWF4ID0gYm5NYXhcbnByb3RvLmFuZCA9IGJuQW5kXG5wcm90by5vciA9IGJuT3JcbnByb3RvLnhvciA9IGJuWG9yXG5wcm90by5hbmROb3QgPSBibkFuZE5vdFxucHJvdG8ubm90ID0gYm5Ob3RcbnByb3RvLnNoaWZ0TGVmdCA9IGJuU2hpZnRMZWZ0XG5wcm90by5zaGlmdFJpZ2h0ID0gYm5TaGlmdFJpZ2h0XG5wcm90by5nZXRMb3dlc3RTZXRCaXQgPSBibkdldExvd2VzdFNldEJpdFxucHJvdG8uYml0Q291bnQgPSBibkJpdENvdW50XG5wcm90by50ZXN0Qml0ID0gYm5UZXN0Qml0XG5wcm90by5zZXRCaXQgPSBiblNldEJpdFxucHJvdG8uY2xlYXJCaXQgPSBibkNsZWFyQml0XG5wcm90by5mbGlwQml0ID0gYm5GbGlwQml0XG5wcm90by5hZGQgPSBibkFkZFxucHJvdG8uc3VidHJhY3QgPSBiblN1YnRyYWN0XG5wcm90by5tdWx0aXBseSA9IGJuTXVsdGlwbHlcbnByb3RvLmRpdmlkZSA9IGJuRGl2aWRlXG5wcm90by5yZW1haW5kZXIgPSBiblJlbWFpbmRlclxucHJvdG8uZGl2aWRlQW5kUmVtYWluZGVyID0gYm5EaXZpZGVBbmRSZW1haW5kZXJcbnByb3RvLm1vZFBvdyA9IGJuTW9kUG93XG5wcm90by5tb2RJbnZlcnNlID0gYm5Nb2RJbnZlcnNlXG5wcm90by5wb3cgPSBiblBvd1xucHJvdG8uZ2NkID0gYm5HQ0RcbnByb3RvLmlzUHJvYmFibGVQcmltZSA9IGJuSXNQcm9iYWJsZVByaW1lXG5cbi8vIEpTQk4tc3BlY2lmaWMgZXh0ZW5zaW9uXG5wcm90by5zcXVhcmUgPSBiblNxdWFyZVxuXG4vLyBjb25zdGFudHNcbkJpZ0ludGVnZXIuWkVSTyA9IG5idigwKVxuQmlnSW50ZWdlci5PTkUgPSBuYnYoMSlcbkJpZ0ludGVnZXIudmFsdWVPZiA9IG5idlxuXG5tb2R1bGUuZXhwb3J0cyA9IEJpZ0ludGVnZXJcbiIsIi8vIEZJWE1FOiBLaW5kIG9mIGEgd2VpcmQgd2F5IHRvIHRocm93IGV4Y2VwdGlvbnMsIGNvbnNpZGVyIHJlbW92aW5nXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0JylcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9iaWdpJylcblxuLyoqXG4gKiBUdXJucyBhIGJ5dGUgYXJyYXkgaW50byBhIGJpZyBpbnRlZ2VyLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBpbnRlcnByZXQgYSBieXRlIGFycmF5IGFzIGEgYmlnIGludGVnZXIgaW4gYmlnXG4gKiBlbmRpYW4gbm90YXRpb24uXG4gKi9cbkJpZ0ludGVnZXIuZnJvbUJ5dGVBcnJheVVuc2lnbmVkID0gZnVuY3Rpb24oYnl0ZUFycmF5KSB7XG4gIC8vIEJpZ0ludGVnZXIgZXhwZWN0cyBhIERFUiBpbnRlZ2VyIGNvbmZvcm1hbnQgYnl0ZSBhcnJheVxuICBpZiAoYnl0ZUFycmF5WzBdICYgMHg4MCkge1xuICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihbMF0uY29uY2F0KGJ5dGVBcnJheSkpXG4gIH1cblxuICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoYnl0ZUFycmF5KVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBieXRlIGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBiaWcgaW50ZWdlci5cbiAqXG4gKiBUaGlzIHJldHVybnMgdGhlIGFic29sdXRlIG9mIHRoZSBjb250YWluZWQgdmFsdWUgaW4gYmlnIGVuZGlhblxuICogZm9ybS4gQSB2YWx1ZSBvZiB6ZXJvIHJlc3VsdHMgaW4gYW4gZW1wdHkgYXJyYXkuXG4gKi9cbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5VW5zaWduZWQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IHRoaXMudG9CeXRlQXJyYXkoKVxuICByZXR1cm4gYnl0ZUFycmF5WzBdID09PSAwID8gYnl0ZUFycmF5LnNsaWNlKDEpIDogYnl0ZUFycmF5XG59XG5cbkJpZ0ludGVnZXIuZnJvbURFUkludGVnZXIgPSBmdW5jdGlvbihieXRlQXJyYXkpIHtcbiAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGJ5dGVBcnJheSlcbn1cblxuLypcbiAqIENvbnZlcnRzIEJpZ0ludGVnZXIgdG8gYSBERVIgaW50ZWdlciByZXByZXNlbnRhdGlvbi5cbiAqXG4gKiBUaGUgZm9ybWF0IGZvciB0aGlzIHZhbHVlIHVzZXMgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0IGFzIGEgc2lnblxuICogYml0LiAgSWYgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0IGlzIGFscmVhZHkgc2V0IGFuZCB0aGUgaW50ZWdlciBpc1xuICogcG9zaXRpdmUsIGEgMHgwMCBpcyBwcmVwZW5kZWQuXG4gKlxuICogRXhhbXBsZXM6XG4gKlxuICogICAgICAwID0+ICAgICAweDAwXG4gKiAgICAgIDEgPT4gICAgIDB4MDFcbiAqICAgICAtMSA9PiAgICAgMHhmZlxuICogICAgMTI3ID0+ICAgICAweDdmXG4gKiAgIC0xMjcgPT4gICAgIDB4ODFcbiAqICAgIDEyOCA9PiAgIDB4MDA4MFxuICogICAtMTI4ID0+ICAgICAweDgwXG4gKiAgICAyNTUgPT4gICAweDAwZmZcbiAqICAgLTI1NSA9PiAgIDB4ZmYwMVxuICogIDE2MzAwID0+ICAgMHgzZmFjXG4gKiAtMTYzMDAgPT4gICAweGMwNTRcbiAqICA2MjMwMCA9PiAweDAwZjM1Y1xuICogLTYyMzAwID0+IDB4ZmYwY2E0XG4qL1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9ERVJJbnRlZ2VyID0gQmlnSW50ZWdlci5wcm90b3R5cGUudG9CeXRlQXJyYXlcblxuQmlnSW50ZWdlci5mcm9tQnVmZmVyID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIC8vIEJpZ0ludGVnZXIgZXhwZWN0cyBhIERFUiBpbnRlZ2VyIGNvbmZvcm1hbnQgYnl0ZSBhcnJheVxuICBpZiAoYnVmZmVyWzBdICYgMHg4MCkge1xuICAgIHZhciBieXRlQXJyYXkgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChidWZmZXIpXG5cbiAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoWzBdLmNvbmNhdChieXRlQXJyYXkpKVxuICB9XG5cbiAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGJ1ZmZlcilcbn1cblxuQmlnSW50ZWdlci5mcm9tSGV4ID0gZnVuY3Rpb24oaGV4KSB7XG4gIGlmIChoZXggPT09ICcnKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPXG5cbiAgYXNzZXJ0LmVxdWFsKGhleCwgaGV4Lm1hdGNoKC9eW0EtRmEtZjAtOV0rLyksICdJbnZhbGlkIGhleCBzdHJpbmcnKVxuICBhc3NlcnQuZXF1YWwoaGV4Lmxlbmd0aCAlIDIsIDAsICdJbmNvbXBsZXRlIGhleCcpXG4gIHJldHVybiBuZXcgQmlnSW50ZWdlcihoZXgsIDE2KVxufVxuXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J1ZmZlciA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IHRoaXMudG9CeXRlQXJyYXlVbnNpZ25lZCgpXG4gIHZhciB6ZXJvcyA9IFtdXG5cbiAgdmFyIHBhZGRpbmcgPSBzaXplIC0gYnl0ZUFycmF5Lmxlbmd0aFxuICB3aGlsZSAoemVyb3MubGVuZ3RoIDwgcGFkZGluZykgemVyb3MucHVzaCgwKVxuXG4gIHJldHVybiBuZXcgQnVmZmVyKHplcm9zLmNvbmNhdChieXRlQXJyYXkpKVxufVxuXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgcmV0dXJuIHRoaXMudG9CdWZmZXIoc2l6ZSkudG9TdHJpbmcoJ2hleCcpXG59XG4iLCJ2YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoMzApXG5cbi8vYWRkb25zXG5yZXF1aXJlKDMxKVxuXG5tb2R1bGUuZXhwb3J0cyA9IEJpZ0ludGVnZXIiLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwiYnVnc1wiOiB7XG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vY3J5cHRvY29pbmpzL2JpZ2kvaXNzdWVzXCJcbiAgfSxcbiAgXCJidW5kbGVEZXBlbmRlbmNpZXNcIjogZmFsc2UsXG4gIFwiZGVwZW5kZW5jaWVzXCI6IHt9LFxuICBcImRlcHJlY2F0ZWRcIjogZmFsc2UsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJCaWcgaW50ZWdlcnMuXCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImNvdmVyYWxsc1wiOiBcIl4yLjExLjJcIixcbiAgICBcImlzdGFuYnVsXCI6IFwiXjAuMy41XCIsXG4gICAgXCJqc2hpbnRcIjogXCJeMi41LjFcIixcbiAgICBcIm1vY2hhXCI6IFwiXjIuMS4wXCIsXG4gICAgXCJtb2NoaWZ5XCI6IFwiXjIuMS4wXCJcbiAgfSxcbiAgXCJob21lcGFnZVwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG9jb2luanMvYmlnaSNyZWFkbWVcIixcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJjcnlwdG9ncmFwaHlcIixcbiAgICBcIm1hdGhcIixcbiAgICBcImJpdGNvaW5cIixcbiAgICBcImFyYml0cmFyeVwiLFxuICAgIFwicHJlY2lzaW9uXCIsXG4gICAgXCJhcml0aG1ldGljXCIsXG4gICAgXCJiaWdcIixcbiAgICBcImludGVnZXJcIixcbiAgICBcImludFwiLFxuICAgIFwibnVtYmVyXCIsXG4gICAgXCJiaWdpbnRlZ2VyXCIsXG4gICAgXCJiaWdpbnRcIixcbiAgICBcImJpZ251bWJlclwiLFxuICAgIFwiZGVjaW1hbFwiLFxuICAgIFwiZmxvYXRcIlxuICBdLFxuICBcIm1haW5cIjogXCIuL2xpYi9pbmRleC5qc1wiLFxuICBcIm5hbWVcIjogXCJiaWdpXCIsXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ1cmxcIjogXCJnaXQraHR0cHM6Ly9naXRodWIuY29tL2NyeXB0b2NvaW5qcy9iaWdpLmdpdFwiLFxuICAgIFwidHlwZVwiOiBcImdpdFwiXG4gIH0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJicm93c2VyLXRlc3RcIjogXCJtb2NoaWZ5IC0td2QgLVIgc3BlY1wiLFxuICAgIFwiY292ZXJhZ2VcIjogXCJpc3RhbmJ1bCBjb3ZlciAuL25vZGVfbW9kdWxlcy8uYmluL19tb2NoYSAtLSAtLXJlcG9ydGVyIGxpc3QgdGVzdC8qLmpzXCIsXG4gICAgXCJjb3ZlcmFsbHNcIjogXCJucG0gcnVuLXNjcmlwdCBjb3ZlcmFnZSAmJiBub2RlIC4vbm9kZV9tb2R1bGVzLy5iaW4vY292ZXJhbGxzIDwgY292ZXJhZ2UvbGNvdi5pbmZvXCIsXG4gICAgXCJqc2hpbnRcIjogXCJqc2hpbnQgLS1jb25maWcganNoaW50Lmpzb24gbGliLyouanMgOyB0cnVlXCIsXG4gICAgXCJ0ZXN0XCI6IFwiX21vY2hhIC0tIHRlc3QvKi5qc1wiLFxuICAgIFwidW5pdFwiOiBcIm1vY2hhXCJcbiAgfSxcbiAgXCJ0ZXN0bGluZ1wiOiB7XG4gICAgXCJmaWxlc1wiOiBcInRlc3QvKi5qc1wiLFxuICAgIFwiaGFybmVzc1wiOiBcIm1vY2hhXCIsXG4gICAgXCJicm93c2Vyc1wiOiBbXG4gICAgICBcImllLzkuLmxhdGVzdFwiLFxuICAgICAgXCJmaXJlZm94L2xhdGVzdFwiLFxuICAgICAgXCJjaHJvbWUvbGF0ZXN0XCIsXG4gICAgICBcInNhZmFyaS82LjAuLmxhdGVzdFwiLFxuICAgICAgXCJpcGhvbmUvNi4wLi5sYXRlc3RcIixcbiAgICAgIFwiYW5kcm9pZC1icm93c2VyLzQuMi4ubGF0ZXN0XCJcbiAgICBdXG4gIH0sXG4gIFwidmVyc2lvblwiOiBcIjEuNC4yXCJcbn0iLCIiLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG4ndXNlIHN0cmljdCdcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUICE9PSB1bmRlZmluZWRcbiAgPyBnbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVFxuICA6IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuLypcbiAqIEV4cG9ydCBrTWF4TGVuZ3RoIGFmdGVyIHR5cGVkIGFycmF5IHN1cHBvcnQgaXMgZGV0ZXJtaW5lZC5cbiAqL1xuZXhwb3J0cy5rTWF4TGVuZ3RoID0ga01heExlbmd0aCgpXG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuX19wcm90b19fID0ge19fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsIGZvbzogZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfX1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MiAmJiAvLyB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoa01heExlbmd0aCgpIDwgbGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoJylcbiAgfVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICBpZiAodGhhdCA9PT0gbnVsbCkge1xuICAgICAgdGhhdCA9IG5ldyBCdWZmZXIobGVuZ3RoKVxuICAgIH1cbiAgICB0aGF0Lmxlbmd0aCA9IGxlbmd0aFxuICB9XG5cbiAgcmV0dXJuIHRoYXRcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgLy8gQ29tbW9uIGNhc2UuXG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIGlmICh0eXBlb2YgZW5jb2RpbmdPck9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0lmIGVuY29kaW5nIGlzIHNwZWNpZmllZCB0aGVuIHRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nJ1xuICAgICAgKVxuICAgIH1cbiAgICByZXR1cm4gYWxsb2NVbnNhZmUodGhpcywgYXJnKVxuICB9XG4gIHJldHVybiBmcm9tKHRoaXMsIGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxuLy8gVE9ETzogTGVnYWN5LCBub3QgbmVlZGVkIGFueW1vcmUuIFJlbW92ZSBpbiBuZXh0IG1ham9yIHZlcnNpb24uXG5CdWZmZXIuX2F1Z21lbnQgPSBmdW5jdGlvbiAoYXJyKSB7XG4gIGFyci5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gZnJvbSAodGhhdCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUJ1ZmZlcih0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIHJldHVybiBmcm9tT2JqZWN0KHRoYXQsIHZhbHVlKVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIEJ1ZmZlcihhcmcsIGVuY29kaW5nKSBidXQgdGhyb3dzIGEgVHlwZUVycm9yXG4gKiBpZiB2YWx1ZSBpcyBhIG51bWJlci5cbiAqIEJ1ZmZlci5mcm9tKHN0clssIGVuY29kaW5nXSlcbiAqIEJ1ZmZlci5mcm9tKGFycmF5KVxuICogQnVmZmVyLmZyb20oYnVmZmVyKVxuICogQnVmZmVyLmZyb20oYXJyYXlCdWZmZXJbLCBieXRlT2Zmc2V0WywgbGVuZ3RoXV0pXG4gKiovXG5CdWZmZXIuZnJvbSA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBmcm9tKG51bGwsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbmlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICBCdWZmZXIucHJvdG90eXBlLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXkucHJvdG90eXBlXG4gIEJ1ZmZlci5fX3Byb3RvX18gPSBVaW50OEFycmF5XG4gIGlmICh0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wuc3BlY2llcyAmJlxuICAgICAgQnVmZmVyW1N5bWJvbC5zcGVjaWVzXSA9PT0gQnVmZmVyKSB7XG4gICAgLy8gRml4IHN1YmFycmF5KCkgaW4gRVMyMDE2LiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL3B1bGwvOTdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgICAgdmFsdWU6IG51bGwsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9IGVsc2UgaWYgKHNpemUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wic2l6ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIG5lZ2F0aXZlJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAodGhhdCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2MobnVsbCwgc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlICh0aGF0LCBzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBzaXplIDwgMCA/IDAgOiBjaGVja2VkKHNpemUpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSB7XG4gICAgICB0aGF0W2ldID0gMFxuICAgIH1cbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKG51bGwsIHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJlbmNvZGluZ1wiIG11c3QgYmUgYSB2YWxpZCBzdHJpbmcgZW5jb2RpbmcnKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSB0aGF0LndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICB0aGF0ID0gdGhhdC5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlICh0aGF0LCBhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyICh0aGF0LCBhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGFycmF5LmJ5dGVMZW5ndGggLy8gdGhpcyB0aHJvd3MgaWYgYGFycmF5YCBpcyBub3QgYSB2YWxpZCBBcnJheUJ1ZmZlclxuXG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdvZmZzZXRcXCcgaXMgb3V0IG9mIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ2xlbmd0aFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYXJyYXkgPSBuZXcgVWludDhBcnJheShhcnJheSwgYnl0ZU9mZnNldClcbiAgfSBlbHNlIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gYXJyYXlcbiAgICB0aGF0Ll9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIGFuIG9iamVjdCBpbnN0YW5jZSBvZiB0aGUgQnVmZmVyIGNsYXNzXG4gICAgdGhhdCA9IGZyb21BcnJheUxpa2UodGhhdCwgYXJyYXkpXG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAodGhhdCwgb2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHRoYXQgPSBjcmVhdGVCdWZmZXIodGhhdCwgbGVuKVxuXG4gICAgaWYgKHRoYXQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdGhhdFxuICAgIH1cblxuICAgIG9iai5jb3B5KHRoYXQsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gdGhhdFxuICB9XG5cbiAgaWYgKG9iaikge1xuICAgIGlmICgodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICBvYmouYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHx8ICdsZW5ndGgnIGluIG9iaikge1xuICAgICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBpc25hbihvYmoubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIDApXG4gICAgICB9XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmopXG4gICAgfVxuXG4gICAgaWYgKG9iai50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iai5kYXRhKSkge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCwgb2JqLmRhdGEpXG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LicpXG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoKClgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0ga01heExlbmd0aCgpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIGtNYXhMZW5ndGgoKS50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnbGF0aW4xJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gICAgfVxuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKVxuICAgIHBvcyArPSBidWYubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSkge1xuICAgIHJldHVybiBzdHJpbmcubGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpIHx8IHN0cmluZyBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHN0cmluZyA9ICcnICsgc3RyaW5nXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAobGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgY2FzZSB1bmRlZmluZWQ6XG4gICAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIGxlbiAqIDJcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBsZW4gPj4+IDFcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aCAvLyBhc3N1bWUgdXRmOFxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICAvLyBObyBuZWVkIHRvIHZlcmlmeSB0aGF0IFwidGhpcy5sZW5ndGggPD0gTUFYX1VJTlQzMlwiIHNpbmNlIGl0J3MgYSByZWFkLW9ubHlcbiAgLy8gcHJvcGVydHkgb2YgYSB0eXBlZCBhcnJheS5cblxuICAvLyBUaGlzIGJlaGF2ZXMgbmVpdGhlciBsaWtlIFN0cmluZyBub3IgVWludDhBcnJheSBpbiB0aGF0IHdlIHNldCBzdGFydC9lbmRcbiAgLy8gdG8gdGhlaXIgdXBwZXIvbG93ZXIgYm91bmRzIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgb3V0IG9mIHJhbmdlLlxuICAvLyB1bmRlZmluZWQgaXMgaGFuZGxlZCBzcGVjaWFsbHkgYXMgcGVyIEVDTUEtMjYyIDZ0aCBFZGl0aW9uLFxuICAvLyBTZWN0aW9uIDEzLjMuMy43IFJ1bnRpbWUgU2VtYW50aWNzOiBLZXllZEJpbmRpbmdJbml0aWFsaXphdGlvbi5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQgfHwgc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgLy8gUmV0dXJuIGVhcmx5IGlmIHN0YXJ0ID4gdGhpcy5sZW5ndGguIERvbmUgaGVyZSB0byBwcmV2ZW50IHBvdGVudGlhbCB1aW50MzJcbiAgLy8gY29lcmNpb24gZmFpbCBiZWxvdy5cbiAgaWYgKHN0YXJ0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoZW5kIDw9IDApIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIEZvcmNlIGNvZXJzaW9uIHRvIHVpbnQzMi4gVGhpcyB3aWxsIGFsc28gY29lcmNlIGZhbHNleS9OYU4gdmFsdWVzIHRvIDAuXG4gIGVuZCA+Pj49IDBcbiAgc3RhcnQgPj4+PSAwXG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbi8vIFRoZSBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIGFuZCBgaXMtYnVmZmVyYCAoaW4gU2FmYXJpIDUtNykgdG8gZGV0ZWN0XG4vLyBCdWZmZXIgaW5zdGFuY2VzLlxuQnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXIgPSB0cnVlXG5cbmZ1bmN0aW9uIHN3YXAgKGIsIG4sIG0pIHtcbiAgdmFyIGkgPSBiW25dXG4gIGJbbl0gPSBiW21dXG4gIGJbbV0gPSBpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2ID0gZnVuY3Rpb24gc3dhcDE2ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSAyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMSlcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAzMiA9IGZ1bmN0aW9uIHN3YXAzMiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMzItYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDMpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDIpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwNjQgPSBmdW5jdGlvbiBzd2FwNjQgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDggIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDY0LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDgpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyA3KVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyA2KVxuICAgIHN3YXAodGhpcywgaSArIDIsIGkgKyA1KVxuICAgIHN3YXAodGhpcywgaSArIDMsIGkgKyA0KVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlICh0YXJnZXQsIHN0YXJ0LCBlbmQsIHRoaXNTdGFydCwgdGhpc0VuZCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIH1cblxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXJ0ID0gMFxuICB9XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHRhcmdldCA/IHRhcmdldC5sZW5ndGggOiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc1N0YXJ0ID0gMFxuICB9XG4gIGlmICh0aGlzRW5kID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzRW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgZW5kID4gdGFyZ2V0Lmxlbmd0aCB8fCB0aGlzU3RhcnQgPCAwIHx8IHRoaXNFbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdvdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kICYmIHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAwXG4gIH1cbiAgaWYgKHRoaXNTdGFydCA+PSB0aGlzRW5kKSB7XG4gICAgcmV0dXJuIC0xXG4gIH1cbiAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICBzdGFydCA+Pj49IDBcbiAgZW5kID4+Pj0gMFxuICB0aGlzU3RhcnQgPj4+PSAwXG4gIHRoaXNFbmQgPj4+PSAwXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCkgcmV0dXJuIDBcblxuICB2YXIgeCA9IHRoaXNFbmQgLSB0aGlzU3RhcnRcbiAgdmFyIHkgPSBlbmQgLSBzdGFydFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcblxuICB2YXIgdGhpc0NvcHkgPSB0aGlzLnNsaWNlKHRoaXNTdGFydCwgdGhpc0VuZClcbiAgdmFyIHRhcmdldENvcHkgPSB0YXJnZXQuc2xpY2Uoc3RhcnQsIGVuZClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKHRoaXNDb3B5W2ldICE9PSB0YXJnZXRDb3B5W2ldKSB7XG4gICAgICB4ID0gdGhpc0NvcHlbaV1cbiAgICAgIHkgPSB0YXJnZXRDb3B5W2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuLy8gRmluZHMgZWl0aGVyIHRoZSBmaXJzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPj0gYGJ5dGVPZmZzZXRgLFxuLy8gT1IgdGhlIGxhc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0IDw9IGBieXRlT2Zmc2V0YC5cbi8vXG4vLyBBcmd1bWVudHM6XG4vLyAtIGJ1ZmZlciAtIGEgQnVmZmVyIHRvIHNlYXJjaFxuLy8gLSB2YWwgLSBhIHN0cmluZywgQnVmZmVyLCBvciBudW1iZXJcbi8vIC0gYnl0ZU9mZnNldCAtIGFuIGluZGV4IGludG8gYGJ1ZmZlcmA7IHdpbGwgYmUgY2xhbXBlZCB0byBhbiBpbnQzMlxuLy8gLSBlbmNvZGluZyAtIGFuIG9wdGlvbmFsIGVuY29kaW5nLCByZWxldmFudCBpcyB2YWwgaXMgYSBzdHJpbmdcbi8vIC0gZGlyIC0gdHJ1ZSBmb3IgaW5kZXhPZiwgZmFsc2UgZm9yIGxhc3RJbmRleE9mXG5mdW5jdGlvbiBiaWRpcmVjdGlvbmFsSW5kZXhPZiAoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgLy8gRW1wdHkgYnVmZmVyIG1lYW5zIG5vIG1hdGNoXG4gIGlmIChidWZmZXIubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldFxuICBpZiAodHlwZW9mIGJ5dGVPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBieXRlT2Zmc2V0XG4gICAgYnl0ZU9mZnNldCA9IDBcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0ID4gMHg3ZmZmZmZmZikge1xuICAgIGJ5dGVPZmZzZXQgPSAweDdmZmZmZmZmXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IC0weDgwMDAwMDAwKSB7XG4gICAgYnl0ZU9mZnNldCA9IC0weDgwMDAwMDAwXG4gIH1cbiAgYnl0ZU9mZnNldCA9ICtieXRlT2Zmc2V0ICAvLyBDb2VyY2UgdG8gTnVtYmVyLlxuICBpZiAoaXNOYU4oYnl0ZU9mZnNldCkpIHtcbiAgICAvLyBieXRlT2Zmc2V0OiBpdCBpdCdzIHVuZGVmaW5lZCwgbnVsbCwgTmFOLCBcImZvb1wiLCBldGMsIHNlYXJjaCB3aG9sZSBidWZmZXJcbiAgICBieXRlT2Zmc2V0ID0gZGlyID8gMCA6IChidWZmZXIubGVuZ3RoIC0gMSlcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0OiBuZWdhdGl2ZSBvZmZzZXRzIHN0YXJ0IGZyb20gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gIGlmIChieXRlT2Zmc2V0IDwgMCkgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggKyBieXRlT2Zmc2V0XG4gIGlmIChieXRlT2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICBpZiAoZGlyKSByZXR1cm4gLTFcbiAgICBlbHNlIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoIC0gMVxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAwKSB7XG4gICAgaWYgKGRpcikgYnl0ZU9mZnNldCA9IDBcbiAgICBlbHNlIHJldHVybiAtMVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIHZhbFxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWwgPSBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICB9XG5cbiAgLy8gRmluYWxseSwgc2VhcmNoIGVpdGhlciBpbmRleE9mIChpZiBkaXIgaXMgdHJ1ZSkgb3IgbGFzdEluZGV4T2ZcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWwpKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcvYnVmZmVyIGFsd2F5cyBmYWlsc1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDB4RkYgLy8gU2VhcmNoIGZvciBhIGJ5dGUgdmFsdWUgWzAtMjU1XVxuICAgIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJlxuICAgICAgICB0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKGRpcikge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCBbIHZhbCBdLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuZnVuY3Rpb24gYXJyYXlJbmRleE9mIChhcnIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICB2YXIgaW5kZXhTaXplID0gMVxuICB2YXIgYXJyTGVuZ3RoID0gYXJyLmxlbmd0aFxuICB2YXIgdmFsTGVuZ3RoID0gdmFsLmxlbmd0aFxuXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICBpZiAoZW5jb2RpbmcgPT09ICd1Y3MyJyB8fCBlbmNvZGluZyA9PT0gJ3Vjcy0yJyB8fFxuICAgICAgICBlbmNvZGluZyA9PT0gJ3V0ZjE2bGUnIHx8IGVuY29kaW5nID09PSAndXRmLTE2bGUnKSB7XG4gICAgICBpZiAoYXJyLmxlbmd0aCA8IDIgfHwgdmFsLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9XG4gICAgICBpbmRleFNpemUgPSAyXG4gICAgICBhcnJMZW5ndGggLz0gMlxuICAgICAgdmFsTGVuZ3RoIC89IDJcbiAgICAgIGJ5dGVPZmZzZXQgLz0gMlxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWQgKGJ1ZiwgaSkge1xuICAgIGlmIChpbmRleFNpemUgPT09IDEpIHtcbiAgICAgIHJldHVybiBidWZbaV1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGJ1Zi5yZWFkVUludDE2QkUoaSAqIGluZGV4U2l6ZSlcbiAgICB9XG4gIH1cblxuICB2YXIgaVxuICBpZiAoZGlyKSB7XG4gICAgdmFyIGZvdW5kSW5kZXggPSAtMVxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPCBhcnJMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHJlYWQoYXJyLCBpKSA9PT0gcmVhZCh2YWwsIGZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4KSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbExlbmd0aCkgcmV0dXJuIGZvdW5kSW5kZXggKiBpbmRleFNpemVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ICE9PSAtMSkgaSAtPSBpIC0gZm91bmRJbmRleFxuICAgICAgICBmb3VuZEluZGV4ID0gLTFcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGJ5dGVPZmZzZXQgKyB2YWxMZW5ndGggPiBhcnJMZW5ndGgpIGJ5dGVPZmZzZXQgPSBhcnJMZW5ndGggLSB2YWxMZW5ndGhcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIGZvdW5kID0gdHJ1ZVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWxMZW5ndGg7IGorKykge1xuICAgICAgICBpZiAocmVhZChhcnIsIGkgKyBqKSAhPT0gcmVhZCh2YWwsIGopKSB7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcyA9IGZ1bmN0aW9uIGluY2x1ZGVzICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiB0aGlzLmluZGV4T2YodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykgIT09IC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIHRydWUpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUubGFzdEluZGV4T2YgPSBmdW5jdGlvbiBsYXN0SW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKGlzTmFOKHBhcnNlZCkpIHJldHVybiBpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBsYXRpbjFXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gICAgaWYgKGlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCB8IDBcbiAgICAgIGlmIChlbmNvZGluZyA9PT0gdW5kZWZpbmVkKSBlbmNvZGluZyA9ICd1dGY4J1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICAvLyBsZWdhY3kgd3JpdGUoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpIC0gcmVtb3ZlIGluIHYwLjEzXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0J1ZmZlci53cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXRbLCBsZW5ndGhdKSBpcyBubyBsb25nZXIgc3VwcG9ydGVkJ1xuICAgIClcbiAgfVxuXG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldFxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgfHwgbGVuZ3RoID4gcmVtYWluaW5nKSBsZW5ndGggPSByZW1haW5pbmdcblxuICBpZiAoKHN0cmluZy5sZW5ndGggPiAwICYmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDApKSB8fCBvZmZzZXQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIHdyaXRlIG91dHNpZGUgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gbGF0aW4xU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZClcbiAgICBuZXdCdWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47ICsraSkge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlVUludEJFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIG1heEJ5dGVzID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpIC0gMVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG1heEJ5dGVzLCAwKVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVVSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAxLCAweGZmLCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDIpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSkpKSA+Pj5cbiAgICAgIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpICogOFxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7ICsraSkge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSAtIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBsaW1pdCA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSBieXRlTGVuZ3RoIC0gMVxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSArIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA4LCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDUyLCA4KVxuICByZXR1cm4gb2Zmc2V0ICsgOFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlQkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uIGNvcHkgKHRhcmdldCwgdGFyZ2V0U3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldFN0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldFN0YXJ0ID0gdGFyZ2V0Lmxlbmd0aFxuICBpZiAoIXRhcmdldFN0YXJ0KSB0YXJnZXRTdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCB0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGlmICh0YXJnZXRTdGFydCA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIH1cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcbiAgdmFyIGlcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHN0YXJ0IDwgdGFyZ2V0U3RhcnQgJiYgdGFyZ2V0U3RhcnQgPCBlbmQpIHtcbiAgICAvLyBkZXNjZW5kaW5nIGNvcHkgZnJvbSBlbmRcbiAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSBpZiAobGVuIDwgMTAwMCB8fCAhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBhc2NlbmRpbmcgY29weSBmcm9tIHN0YXJ0XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbChcbiAgICAgIHRhcmdldCxcbiAgICAgIHRoaXMuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgbGVuKSxcbiAgICAgIHRhcmdldFN0YXJ0XG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBVc2FnZTpcbi8vICAgIGJ1ZmZlci5maWxsKG51bWJlclssIG9mZnNldFssIGVuZF1dKVxuLy8gICAgYnVmZmVyLmZpbGwoYnVmZmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChzdHJpbmdbLCBvZmZzZXRbLCBlbmRdXVssIGVuY29kaW5nXSlcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwgKHZhbCwgc3RhcnQsIGVuZCwgZW5jb2RpbmcpIHtcbiAgLy8gSGFuZGxlIHN0cmluZyBjYXNlczpcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKHR5cGVvZiBzdGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gc3RhcnRcbiAgICAgIHN0YXJ0ID0gMFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbmQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuZFxuICAgICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgICB9XG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBjb2RlID0gdmFsLmNoYXJDb2RlQXQoMClcbiAgICAgIGlmIChjb2RlIDwgMjU2KSB7XG4gICAgICAgIHZhbCA9IGNvZGVcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZW5jb2RpbmcgbXVzdCBiZSBhIHN0cmluZycpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAyNTVcbiAgfVxuXG4gIC8vIEludmFsaWQgcmFuZ2VzIGFyZSBub3Qgc2V0IHRvIGEgZGVmYXVsdCwgc28gY2FuIHJhbmdlIGNoZWNrIGVhcmx5LlxuICBpZiAoc3RhcnQgPCAwIHx8IHRoaXMubGVuZ3RoIDwgc3RhcnQgfHwgdGhpcy5sZW5ndGggPCBlbmQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IHRoaXMubGVuZ3RoIDogZW5kID4+PiAwXG5cbiAgaWYgKCF2YWwpIHZhbCA9IDBcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICB0aGlzW2ldID0gdmFsXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IEJ1ZmZlci5pc0J1ZmZlcih2YWwpXG4gICAgICA/IHZhbFxuICAgICAgOiB1dGY4VG9CeXRlcyhuZXcgQnVmZmVyKHZhbCwgZW5jb2RpbmcpLnRvU3RyaW5nKCkpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGZvciAoaSA9IDA7IGkgPCBlbmQgLSBzdGFydDsgKytpKSB7XG4gICAgICB0aGlzW2kgKyBzdGFydF0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGlzbmFuICh2YWwpIHtcbiAgcmV0dXJuIHZhbCAhPT0gdmFsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoMzUpLkJ1ZmZlcjtcblxudmFyIGlzQnVmZmVyRW5jb2RpbmcgPSBCdWZmZXIuaXNFbmNvZGluZ1xuICB8fCBmdW5jdGlvbihlbmNvZGluZykge1xuICAgICAgIHN3aXRjaCAoZW5jb2RpbmcgJiYgZW5jb2RpbmcudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgY2FzZSAnaGV4JzogY2FzZSAndXRmOCc6IGNhc2UgJ3V0Zi04JzogY2FzZSAnYXNjaWknOiBjYXNlICdiaW5hcnknOiBjYXNlICdiYXNlNjQnOiBjYXNlICd1Y3MyJzogY2FzZSAndWNzLTInOiBjYXNlICd1dGYxNmxlJzogY2FzZSAndXRmLTE2bGUnOiBjYXNlICdyYXcnOiByZXR1cm4gdHJ1ZTtcbiAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBmYWxzZTtcbiAgICAgICB9XG4gICAgIH1cblxuXG5mdW5jdGlvbiBhc3NlcnRFbmNvZGluZyhlbmNvZGluZykge1xuICBpZiAoZW5jb2RpbmcgJiYgIWlzQnVmZmVyRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB9XG59XG5cbi8vIFN0cmluZ0RlY29kZXIgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIGZvciBlZmZpY2llbnRseSBzcGxpdHRpbmcgYSBzZXJpZXMgb2Zcbi8vIGJ1ZmZlcnMgaW50byBhIHNlcmllcyBvZiBKUyBzdHJpbmdzIHdpdGhvdXQgYnJlYWtpbmcgYXBhcnQgbXVsdGktYnl0ZVxuLy8gY2hhcmFjdGVycy4gQ0VTVS04IGlzIGhhbmRsZWQgYXMgcGFydCBvZiB0aGUgVVRGLTggZW5jb2RpbmcuXG4vL1xuLy8gQFRPRE8gSGFuZGxpbmcgYWxsIGVuY29kaW5ncyBpbnNpZGUgYSBzaW5nbGUgb2JqZWN0IG1ha2VzIGl0IHZlcnkgZGlmZmljdWx0XG4vLyB0byByZWFzb24gYWJvdXQgdGhpcyBjb2RlLCBzbyBpdCBzaG91bGQgYmUgc3BsaXQgdXAgaW4gdGhlIGZ1dHVyZS5cbi8vIEBUT0RPIFRoZXJlIHNob3VsZCBiZSBhIHV0Zjgtc3RyaWN0IGVuY29kaW5nIHRoYXQgcmVqZWN0cyBpbnZhbGlkIFVURi04IGNvZGVcbi8vIHBvaW50cyBhcyB1c2VkIGJ5IENFU1UtOC5cbnZhciBTdHJpbmdEZWNvZGVyID0gZXhwb3J0cy5TdHJpbmdEZWNvZGVyID0gZnVuY3Rpb24oZW5jb2RpbmcpIHtcbiAgdGhpcy5lbmNvZGluZyA9IChlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXS8sICcnKTtcbiAgYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpO1xuICBzd2l0Y2ggKHRoaXMuZW5jb2RpbmcpIHtcbiAgICBjYXNlICd1dGY4JzpcbiAgICAgIC8vIENFU1UtOCByZXByZXNlbnRzIGVhY2ggb2YgU3Vycm9nYXRlIFBhaXIgYnkgMy1ieXRlc1xuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgLy8gVVRGLTE2IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAyLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAyO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXI7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgLy8gQmFzZS02NCBzdG9yZXMgMyBieXRlcyBpbiA0IGNoYXJzLCBhbmQgcGFkcyB0aGUgcmVtYWluZGVyLlxuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aGlzLndyaXRlID0gcGFzc1Rocm91Z2hXcml0ZTtcbiAgICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEVub3VnaCBzcGFjZSB0byBzdG9yZSBhbGwgYnl0ZXMgb2YgYSBzaW5nbGUgY2hhcmFjdGVyLiBVVEYtOCBuZWVkcyA0XG4gIC8vIGJ5dGVzLCBidXQgQ0VTVS04IG1heSByZXF1aXJlIHVwIHRvIDYgKDMgYnl0ZXMgcGVyIHN1cnJvZ2F0ZSkuXG4gIHRoaXMuY2hhckJ1ZmZlciA9IG5ldyBCdWZmZXIoNik7XG4gIC8vIE51bWJlciBvZiBieXRlcyByZWNlaXZlZCBmb3IgdGhlIGN1cnJlbnQgaW5jb21wbGV0ZSBtdWx0aS1ieXRlIGNoYXJhY3Rlci5cbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSAwO1xuICAvLyBOdW1iZXIgb2YgYnl0ZXMgZXhwZWN0ZWQgZm9yIHRoZSBjdXJyZW50IGluY29tcGxldGUgbXVsdGktYnl0ZSBjaGFyYWN0ZXIuXG4gIHRoaXMuY2hhckxlbmd0aCA9IDA7XG59O1xuXG5cbi8vIHdyaXRlIGRlY29kZXMgdGhlIGdpdmVuIGJ1ZmZlciBhbmQgcmV0dXJucyBpdCBhcyBKUyBzdHJpbmcgdGhhdCBpc1xuLy8gZ3VhcmFudGVlZCB0byBub3QgY29udGFpbiBhbnkgcGFydGlhbCBtdWx0aS1ieXRlIGNoYXJhY3RlcnMuIEFueSBwYXJ0aWFsXG4vLyBjaGFyYWN0ZXIgZm91bmQgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyIGlzIGJ1ZmZlcmVkIHVwLCBhbmQgd2lsbCBiZVxuLy8gcmV0dXJuZWQgd2hlbiBjYWxsaW5nIHdyaXRlIGFnYWluIHdpdGggdGhlIHJlbWFpbmluZyBieXRlcy5cbi8vXG4vLyBOb3RlOiBDb252ZXJ0aW5nIGEgQnVmZmVyIGNvbnRhaW5pbmcgYW4gb3JwaGFuIHN1cnJvZ2F0ZSB0byBhIFN0cmluZ1xuLy8gY3VycmVudGx5IHdvcmtzLCBidXQgY29udmVydGluZyBhIFN0cmluZyB0byBhIEJ1ZmZlciAodmlhIGBuZXcgQnVmZmVyYCwgb3Jcbi8vIEJ1ZmZlciN3cml0ZSkgd2lsbCByZXBsYWNlIGluY29tcGxldGUgc3Vycm9nYXRlcyB3aXRoIHRoZSB1bmljb2RlXG4vLyByZXBsYWNlbWVudCBjaGFyYWN0ZXIuIFNlZSBodHRwczovL2NvZGVyZXZpZXcuY2hyb21pdW0ub3JnLzEyMTE3MzAwOS8gLlxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIGNoYXJTdHIgPSAnJztcbiAgLy8gaWYgb3VyIGxhc3Qgd3JpdGUgZW5kZWQgd2l0aCBhbiBpbmNvbXBsZXRlIG11bHRpYnl0ZSBjaGFyYWN0ZXJcbiAgd2hpbGUgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGRldGVybWluZSBob3cgbWFueSByZW1haW5pbmcgYnl0ZXMgdGhpcyBidWZmZXIgaGFzIHRvIG9mZmVyIGZvciB0aGlzIGNoYXJcbiAgICB2YXIgYXZhaWxhYmxlID0gKGJ1ZmZlci5sZW5ndGggPj0gdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQpID9cbiAgICAgICAgdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQgOlxuICAgICAgICBidWZmZXIubGVuZ3RoO1xuXG4gICAgLy8gYWRkIHRoZSBuZXcgYnl0ZXMgdG8gdGhlIGNoYXIgYnVmZmVyXG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCB0aGlzLmNoYXJSZWNlaXZlZCwgMCwgYXZhaWxhYmxlKTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCArPSBhdmFpbGFibGU7XG5cbiAgICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQgPCB0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAgIC8vIHN0aWxsIG5vdCBlbm91Z2ggY2hhcnMgaW4gdGhpcyBidWZmZXI/IHdhaXQgZm9yIG1vcmUgLi4uXG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGJ5dGVzIGJlbG9uZ2luZyB0byB0aGUgY3VycmVudCBjaGFyYWN0ZXIgZnJvbSB0aGUgYnVmZmVyXG4gICAgYnVmZmVyID0gYnVmZmVyLnNsaWNlKGF2YWlsYWJsZSwgYnVmZmVyLmxlbmd0aCk7XG5cbiAgICAvLyBnZXQgdGhlIGNoYXJhY3RlciB0aGF0IHdhcyBzcGxpdFxuICAgIGNoYXJTdHIgPSB0aGlzLmNoYXJCdWZmZXIuc2xpY2UoMCwgdGhpcy5jaGFyTGVuZ3RoKS50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcblxuICAgIC8vIENFU1UtODogbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgICB2YXIgY2hhckNvZGUgPSBjaGFyU3RyLmNoYXJDb2RlQXQoY2hhclN0ci5sZW5ndGggLSAxKTtcbiAgICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoICs9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICAgIGNoYXJTdHIgPSAnJztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0aGlzLmNoYXJSZWNlaXZlZCA9IHRoaXMuY2hhckxlbmd0aCA9IDA7XG5cbiAgICAvLyBpZiB0aGVyZSBhcmUgbm8gbW9yZSBieXRlcyBpbiB0aGlzIGJ1ZmZlciwganVzdCBlbWl0IG91ciBjaGFyXG4gICAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBjaGFyU3RyO1xuICAgIH1cbiAgICBicmVhaztcbiAgfVxuXG4gIC8vIGRldGVybWluZSBhbmQgc2V0IGNoYXJMZW5ndGggLyBjaGFyUmVjZWl2ZWRcbiAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpO1xuXG4gIHZhciBlbmQgPSBidWZmZXIubGVuZ3RoO1xuICBpZiAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gYnVmZmVyIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlciBieXRlcyB3ZSBnb3RcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIDAsIGJ1ZmZlci5sZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCwgZW5kKTtcbiAgICBlbmQgLT0gdGhpcy5jaGFyUmVjZWl2ZWQ7XG4gIH1cblxuICBjaGFyU3RyICs9IGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCBlbmQpO1xuXG4gIHZhciBlbmQgPSBjaGFyU3RyLmxlbmd0aCAtIDE7XG4gIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChlbmQpO1xuICAvLyBDRVNVLTg6IGxlYWQgc3Vycm9nYXRlIChEODAwLURCRkYpIGlzIGFsc28gdGhlIGluY29tcGxldGUgY2hhcmFjdGVyXG4gIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgdmFyIHNpemUgPSB0aGlzLnN1cnJvZ2F0ZVNpemU7XG4gICAgdGhpcy5jaGFyTGVuZ3RoICs9IHNpemU7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gc2l6ZTtcbiAgICB0aGlzLmNoYXJCdWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIHNpemUsIDAsIHNpemUpO1xuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgMCwgMCwgc2l6ZSk7XG4gICAgcmV0dXJuIGNoYXJTdHIuc3Vic3RyaW5nKDAsIGVuZCk7XG4gIH1cblxuICAvLyBvciBqdXN0IGVtaXQgdGhlIGNoYXJTdHJcbiAgcmV0dXJuIGNoYXJTdHI7XG59O1xuXG4vLyBkZXRlY3RJbmNvbXBsZXRlQ2hhciBkZXRlcm1pbmVzIGlmIHRoZXJlIGlzIGFuIGluY29tcGxldGUgVVRGLTggY2hhcmFjdGVyIGF0XG4vLyB0aGUgZW5kIG9mIHRoZSBnaXZlbiBidWZmZXIuIElmIHNvLCBpdCBzZXRzIHRoaXMuY2hhckxlbmd0aCB0byB0aGUgYnl0ZVxuLy8gbGVuZ3RoIHRoYXQgY2hhcmFjdGVyLCBhbmQgc2V0cyB0aGlzLmNoYXJSZWNlaXZlZCB0byB0aGUgbnVtYmVyIG9mIGJ5dGVzXG4vLyB0aGF0IGFyZSBhdmFpbGFibGUgZm9yIHRoaXMgY2hhcmFjdGVyLlxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IGJ5dGVzIHdlIGhhdmUgdG8gY2hlY2sgYXQgdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlclxuICB2YXIgaSA9IChidWZmZXIubGVuZ3RoID49IDMpID8gMyA6IGJ1ZmZlci5sZW5ndGg7XG5cbiAgLy8gRmlndXJlIG91dCBpZiBvbmUgb2YgdGhlIGxhc3QgaSBieXRlcyBvZiBvdXIgYnVmZmVyIGFubm91bmNlcyBhblxuICAvLyBpbmNvbXBsZXRlIGNoYXIuXG4gIGZvciAoOyBpID4gMDsgaS0tKSB7XG4gICAgdmFyIGMgPSBidWZmZXJbYnVmZmVyLmxlbmd0aCAtIGldO1xuXG4gICAgLy8gU2VlIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTgjRGVzY3JpcHRpb25cblxuICAgIC8vIDExMFhYWFhYXG4gICAgaWYgKGkgPT0gMSAmJiBjID4+IDUgPT0gMHgwNikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMjtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTBYWFhYXG4gICAgaWYgKGkgPD0gMiAmJiBjID4+IDQgPT0gMHgwRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMztcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTEwWFhYXG4gICAgaWYgKGkgPD0gMyAmJiBjID4+IDMgPT0gMHgxRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGk7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBpZiAoYnVmZmVyICYmIGJ1ZmZlci5sZW5ndGgpXG4gICAgcmVzID0gdGhpcy53cml0ZShidWZmZXIpO1xuXG4gIGlmICh0aGlzLmNoYXJSZWNlaXZlZCkge1xuICAgIHZhciBjciA9IHRoaXMuY2hhclJlY2VpdmVkO1xuICAgIHZhciBidWYgPSB0aGlzLmNoYXJCdWZmZXI7XG4gICAgdmFyIGVuYyA9IHRoaXMuZW5jb2Rpbmc7XG4gICAgcmVzICs9IGJ1Zi5zbGljZSgwLCBjcikudG9TdHJpbmcoZW5jKTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcikge1xuICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAyO1xuICB0aGlzLmNoYXJMZW5ndGggPSB0aGlzLmNoYXJSZWNlaXZlZCA/IDIgOiAwO1xufVxuXG5mdW5jdGlvbiBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpIHtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBidWZmZXIubGVuZ3RoICUgMztcbiAgdGhpcy5jaGFyTGVuZ3RoID0gdGhpcy5jaGFyUmVjZWl2ZWQgPyAzIDogMDtcbn1cbiIsInZhciBiYXNleCA9IHJlcXVpcmUoMjgpXG52YXIgQUxQSEFCRVQgPSAnMTIzNDU2Nzg5QUJDREVGR0hKS0xNTlBRUlNUVVZXWFlaYWJjZGVmZ2hpamttbm9wcXJzdHV2d3h5eidcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNleChBTFBIQUJFVClcbiIsIi8qXHJcbiBDb3B5cmlnaHQgMjAxMy0yMDE0IERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcblxyXG4gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcclxuIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cclxuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG5cclxuIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcclxuIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcclxuIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxyXG4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxyXG4gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEBsaWNlbnNlIGJ5dGVidWZmZXIuanMgKGMpIDIwMTUgRGFuaWVsIFdpcnR6IDxkY29kZUBkY29kZS5pbz5cclxuICogQmFja2luZyBidWZmZXI6IEFycmF5QnVmZmVyLCBBY2Nlc3NvcjogVWludDhBcnJheVxyXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wXHJcbiAqIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vYnl0ZWJ1ZmZlci5qcyBmb3IgZGV0YWlsc1xyXG4gKi9cclxuKGZ1bmN0aW9uKGdsb2JhbCwgZmFjdG9yeSkge1xyXG5cclxuICAgIC8qIEFNRCAqLyBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmVbXCJhbWRcIl0pXHJcbiAgICAgICAgZGVmaW5lKFtcImxvbmdcIl0sIGZhY3RvcnkpO1xyXG4gICAgLyogQ29tbW9uSlMgKi8gZWxzZSBpZiAodHlwZW9mIHJlcXVpcmUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiBtb2R1bGUgJiYgbW9kdWxlW1wiZXhwb3J0c1wiXSlcclxuICAgICAgICBtb2R1bGVbJ2V4cG9ydHMnXSA9IChmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgdmFyIExvbmc7IHRyeSB7IExvbmcgPSByZXF1aXJlKDY4KTsgfSBjYXRjaCAoZSkge31cclxuICAgICAgICAgICAgcmV0dXJuIGZhY3RvcnkoTG9uZyk7XHJcbiAgICAgICAgfSkoKTtcclxuICAgIC8qIEdsb2JhbCAqLyBlbHNlXHJcbiAgICAgICAgKGdsb2JhbFtcImRjb2RlSU9cIl0gPSBnbG9iYWxbXCJkY29kZUlPXCJdIHx8IHt9KVtcIkJ5dGVCdWZmZXJcIl0gPSBmYWN0b3J5KGdsb2JhbFtcImRjb2RlSU9cIl1bXCJMb25nXCJdKTtcclxuXHJcbn0pKHRoaXMsIGZ1bmN0aW9uKExvbmcpIHtcclxuICAgIFwidXNlIHN0cmljdFwiO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBCeXRlQnVmZmVyLlxyXG4gICAgICogQGNsYXNzIFRoZSBzd2lzcyBhcm15IGtuaWZlIGZvciBiaW5hcnkgZGF0YSBpbiBKYXZhU2NyaXB0LlxyXG4gICAgICogQGV4cG9ydHMgQnl0ZUJ1ZmZlclxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGNhcGFjaXR5IEluaXRpYWwgY2FwYWNpdHkuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfQ0FQQUNJVFl9LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbm9Bc3NlcnQgV2hldGhlciB0byBza2lwIGFzc2VydGlvbnMgb2Ygb2Zmc2V0cyBhbmQgdmFsdWVzLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlR9LlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICB2YXIgQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGNhcGFjaXR5LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBjYXBhY2l0eSA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIGNhcGFjaXR5ID0gQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZO1xyXG4gICAgICAgIGlmICh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTjtcclxuICAgICAgICBpZiAodHlwZW9mIG5vQXNzZXJ0ID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgbm9Bc3NlcnQgPSBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlQ7XHJcbiAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBjYXBhY2l0eSA9IGNhcGFjaXR5IHwgMDtcclxuICAgICAgICAgICAgaWYgKGNhcGFjaXR5IDwgMClcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIGNhcGFjaXR5XCIpO1xyXG4gICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSAhIWxpdHRsZUVuZGlhbjtcclxuICAgICAgICAgICAgbm9Bc3NlcnQgPSAhIW5vQXNzZXJ0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQmFja2luZyBBcnJheUJ1ZmZlci5cclxuICAgICAgICAgKiBAdHlwZSB7IUFycmF5QnVmZmVyfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmJ1ZmZlciA9IGNhcGFjaXR5ID09PSAwID8gRU1QVFlfQlVGRkVSIDogbmV3IEFycmF5QnVmZmVyKGNhcGFjaXR5KTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVWludDhBcnJheSB1dGlsaXplZCB0byBtYW5pcHVsYXRlIHRoZSBiYWNraW5nIGJ1ZmZlci4gQmVjb21lcyBgbnVsbGAgaWYgdGhlIGJhY2tpbmcgYnVmZmVyIGhhcyBhIGNhcGFjaXR5IG9mIGAwYC5cclxuICAgICAgICAgKiBAdHlwZSB7P1VpbnQ4QXJyYXl9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMudmlldyA9IGNhcGFjaXR5ID09PSAwID8gbnVsbCA6IG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyKTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQWJzb2x1dGUgcmVhZC93cml0ZSBvZmZzZXQuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICogQHNlZSBCeXRlQnVmZmVyI2ZsaXBcclxuICAgICAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjY2xlYXJcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLm9mZnNldCA9IDA7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE1hcmtlZCBvZmZzZXQuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICogQHNlZSBCeXRlQnVmZmVyI21hcmtcclxuICAgICAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjcmVzZXRcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLm1hcmtlZE9mZnNldCA9IC0xO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBBYnNvbHV0ZSBsaW1pdCBvZiB0aGUgY29udGFpbmVkIGRhdGEuIFNldCB0byB0aGUgYmFja2luZyBidWZmZXIncyBjYXBhY2l0eSB1cG9uIGFsbG9jYXRpb24uXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICogQHNlZSBCeXRlQnVmZmVyI2ZsaXBcclxuICAgICAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjY2xlYXJcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmxpbWl0ID0gY2FwYWNpdHk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlciwgZGVmYXVsdHMgdG8gYGZhbHNlYCBmb3IgYmlnIGVuZGlhbi5cclxuICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5saXR0bGVFbmRpYW4gPSBsaXR0bGVFbmRpYW47XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcywgZGVmYXVsdHMgdG8gYGZhbHNlYC5cclxuICAgICAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5ub0Fzc2VydCA9IG5vQXNzZXJ0O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEJ5dGVCdWZmZXIgdmVyc2lvbi5cclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5WRVJTSU9OID0gXCI1LjAuMVwiO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTGl0dGxlIGVuZGlhbiBjb25zdGFudCB0aGF0IGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgaXRzIGJvb2xlYW4gdmFsdWUuIEV2YWx1YXRlcyB0byBgdHJ1ZWAuXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4gPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQmlnIGVuZGlhbiBjb25zdGFudCB0aGF0IGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgaXRzIGJvb2xlYW4gdmFsdWUuIEV2YWx1YXRlcyB0byBgZmFsc2VgLlxyXG4gICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5CSUdfRU5ESUFOID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZhdWx0IGluaXRpYWwgY2FwYWNpdHkgb2YgYDE2YC5cclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuREVGQVVMVF9DQVBBQ0lUWSA9IDE2O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmYXVsdCBlbmRpYW5lc3Mgb2YgYGZhbHNlYCBmb3IgYmlnIGVuZGlhbi5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOID0gQnl0ZUJ1ZmZlci5CSUdfRU5ESUFOO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmYXVsdCBubyBhc3NlcnRpb25zIGZsYWcgb2YgYGZhbHNlYC5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlQgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEEgYExvbmdgIGNsYXNzIGZvciByZXByZXNlbnRpbmcgYSA2NC1iaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyIHZhbHVlLiBNYXkgYmUgYG51bGxgIGlmIExvbmcuanMgaGFzIG5vdCBiZWVuIGxvYWRlZFxyXG4gICAgICogIGFuZCBpbnQ2NCBzdXBwb3J0IGlzIG5vdCBhdmFpbGFibGUuXHJcbiAgICAgKiBAdHlwZSB7P0xvbmd9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vbG9uZy5qc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkxvbmcgPSBMb25nIHx8IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAYWxpYXMgQnl0ZUJ1ZmZlci5wcm90b3R5cGVcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgQnl0ZUJ1ZmZlclByb3RvdHlwZSA9IEJ5dGVCdWZmZXIucHJvdG90eXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW4gaW5kaWNhdG9yIHVzZWQgdG8gcmVsaWFibHkgZGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBhIEJ5dGVCdWZmZXIgb3Igbm90LlxyXG4gICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuX19pc0J5dGVCdWZmZXJfXztcclxuXHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnl0ZUJ1ZmZlclByb3RvdHlwZSwgXCJfX2lzQnl0ZUJ1ZmZlcl9fXCIsIHtcclxuICAgICAgICB2YWx1ZTogdHJ1ZSxcclxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlXHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBoZWxwZXJzXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7IUFycmF5QnVmZmVyfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBFTVBUWV9CVUZGRVIgPSBuZXcgQXJyYXlCdWZmZXIoMCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdHJpbmcuZnJvbUNoYXJDb2RlIHJlZmVyZW5jZSBmb3IgY29tcGlsZS10aW1lIHJlbmFtaW5nLlxyXG4gICAgICogQHR5cGUge2Z1bmN0aW9uKC4uLm51bWJlcik6c3RyaW5nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBzdHJpbmdGcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIHNvdXJjZSBmdW5jdGlvbiBmb3IgYSBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcyBTdHJpbmcgdG8gcmVhZCBmcm9tXHJcbiAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb24oKTpudW1iZXJ8bnVsbH0gU291cmNlIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjaGFyIGNvZGUgcmVzcGVjdGl2ZWx5IGBudWxsYCBpZiB0aGVyZSBhcmVcclxuICAgICAqICBubyBtb3JlIGNoYXJhY3RlcnMgbGVmdC5cclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgdGhlIGFyZ3VtZW50IGlzIGludmFsaWRcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBzdHJpbmdTb3VyY2Uocykge1xyXG4gICAgICAgIHZhciBpPTA7IHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGkgPCBzLmxlbmd0aCA/IHMuY2hhckNvZGVBdChpKyspIDogbnVsbDtcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIGRlc3RpbmF0aW9uIGZ1bmN0aW9uIGZvciBhIHN0cmluZy5cclxuICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbihudW1iZXI9KTp1bmRlZmluZWR8c3RyaW5nfSBEZXN0aW5hdGlvbiBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggdGhlIG5leHQgY2hhciBjb2RlLlxyXG4gICAgICogIFJldHVybnMgdGhlIGZpbmFsIHN0cmluZyB3aGVuIGNhbGxlZCB3aXRob3V0IGFyZ3VtZW50cy5cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBzdHJpbmdEZXN0aW5hdGlvbigpIHtcclxuICAgICAgICB2YXIgY3MgPSBbXSwgcHMgPSBbXTsgcmV0dXJuIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcclxuICAgICAgICAgICAgICAgIHJldHVybiBwcy5qb2luKCcnKStzdHJpbmdGcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjcyk7XHJcbiAgICAgICAgICAgIGlmIChjcy5sZW5ndGggKyBhcmd1bWVudHMubGVuZ3RoID4gMTAyNClcclxuICAgICAgICAgICAgICAgIHBzLnB1c2goc3RyaW5nRnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY3MpKSxcclxuICAgICAgICAgICAgICAgICAgICBjcy5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShjcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgYWNjZXNzb3IgdHlwZS5cclxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gYEJ1ZmZlcmAgdW5kZXIgbm9kZS5qcywgYFVpbnQ4QXJyYXlgIHJlc3BlY3RpdmVseSBgRGF0YVZpZXdgIGluIHRoZSBicm93c2VyIChjbGFzc2VzKVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmFjY2Vzc29yID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBBbGxvY2F0ZXMgYSBuZXcgQnl0ZUJ1ZmZlciBiYWNrZWQgYnkgYSBidWZmZXIgb2YgdGhlIHNwZWNpZmllZCBjYXBhY2l0eS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gY2FwYWNpdHkgSW5pdGlhbCBjYXBhY2l0eS4gRGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9DQVBBQ0lUWX0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0Fzc2VydCBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuYWxsb2NhdGUgPSBmdW5jdGlvbihjYXBhY2l0eSwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQnl0ZUJ1ZmZlcihjYXBhY2l0eSwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uY2F0ZW5hdGVzIG11bHRpcGxlIEJ5dGVCdWZmZXJzIGludG8gb25lLlxyXG4gICAgICogQHBhcmFtIHshQXJyYXkuPCFCeXRlQnVmZmVyfCFBcnJheUJ1ZmZlcnwhVWludDhBcnJheXxzdHJpbmc+fSBidWZmZXJzIEJ1ZmZlcnMgdG8gY29uY2F0ZW5hdGVcclxuICAgICAqIEBwYXJhbSB7KHN0cmluZ3xib29sZWFuKT19IGVuY29kaW5nIFN0cmluZyBlbmNvZGluZyBpZiBgYnVmZmVyc2AgY29udGFpbnMgYSBzdHJpbmcgKFwiYmFzZTY0XCIsIFwiaGV4XCIsIFwiYmluYXJ5XCIsXHJcbiAgICAgKiAgZGVmYXVsdHMgdG8gXCJ1dGY4XCIpXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlciBmb3IgdGhlIHJlc3VsdGluZyBCeXRlQnVmZmVyLiBEZWZhdWx0c1xyXG4gICAgICogIHRvIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcyBmb3IgdGhlIHJlc3VsdGluZyBCeXRlQnVmZmVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBDb25jYXRlbmF0ZWQgQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uKGJ1ZmZlcnMsIGVuY29kaW5nLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Jvb2xlYW4nIHx8IHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgbm9Bc3NlcnQgPSBsaXR0bGVFbmRpYW47XHJcbiAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IGVuY29kaW5nO1xyXG4gICAgICAgICAgICBlbmNvZGluZyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNhcGFjaXR5ID0gMDtcclxuICAgICAgICBmb3IgKHZhciBpPTAsIGs9YnVmZmVycy5sZW5ndGgsIGxlbmd0aDsgaTxrOyArK2kpIHtcclxuICAgICAgICAgICAgaWYgKCFCeXRlQnVmZmVyLmlzQnl0ZUJ1ZmZlcihidWZmZXJzW2ldKSlcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcnNbaV0gPSBCeXRlQnVmZmVyLndyYXAoYnVmZmVyc1tpXSwgZW5jb2RpbmcpO1xyXG4gICAgICAgICAgICBsZW5ndGggPSBidWZmZXJzW2ldLmxpbWl0IC0gYnVmZmVyc1tpXS5vZmZzZXQ7XHJcbiAgICAgICAgICAgIGlmIChsZW5ndGggPiAwKSBjYXBhY2l0eSArPSBsZW5ndGg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjYXBhY2l0eSA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBCeXRlQnVmZmVyKDAsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpO1xyXG4gICAgICAgIHZhciBiYiA9IG5ldyBCeXRlQnVmZmVyKGNhcGFjaXR5LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSxcclxuICAgICAgICAgICAgYmk7XHJcbiAgICAgICAgaT0wOyB3aGlsZSAoaTxrKSB7XHJcbiAgICAgICAgICAgIGJpID0gYnVmZmVyc1tpKytdO1xyXG4gICAgICAgICAgICBsZW5ndGggPSBiaS5saW1pdCAtIGJpLm9mZnNldDtcclxuICAgICAgICAgICAgaWYgKGxlbmd0aCA8PSAwKSBjb250aW51ZTtcclxuICAgICAgICAgICAgYmIudmlldy5zZXQoYmkudmlldy5zdWJhcnJheShiaS5vZmZzZXQsIGJpLmxpbWl0KSwgYmIub2Zmc2V0KTtcclxuICAgICAgICAgICAgYmIub2Zmc2V0ICs9IGxlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgYmIubGltaXQgPSBiYi5vZmZzZXQ7XHJcbiAgICAgICAgYmIub2Zmc2V0ID0gMDtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCB0eXBlIGlzIGEgQnl0ZUJ1ZmZlci5cclxuICAgICAqIEBwYXJhbSB7Kn0gYmIgQnl0ZUJ1ZmZlciB0byB0ZXN0XHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIGl0IGlzIGEgQnl0ZUJ1ZmZlciwgb3RoZXJ3aXNlIGBmYWxzZWBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5pc0J5dGVCdWZmZXIgPSBmdW5jdGlvbihiYikge1xyXG4gICAgICAgIHJldHVybiAoYmIgJiYgYmJbXCJfX2lzQnl0ZUJ1ZmZlcl9fXCJdKSA9PT0gdHJ1ZTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGJhY2tpbmcgYnVmZmVyIHR5cGUuXHJcbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IGBCdWZmZXJgIHVuZGVyIG5vZGUuanMsIGBBcnJheUJ1ZmZlcmAgaW4gdGhlIGJyb3dzZXIgKGNsYXNzZXMpXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIudHlwZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBBcnJheUJ1ZmZlcjtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFdyYXBzIGEgYnVmZmVyIG9yIGEgc3RyaW5nLiBTZXRzIHRoZSBhbGxvY2F0ZWQgQnl0ZUJ1ZmZlcidzIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gdG8gYDBgIGFuZCBpdHNcclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0gdG8gdGhlIGxlbmd0aCBvZiB0aGUgd3JhcHBlZCBkYXRhLlxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcnwhQXJyYXlCdWZmZXJ8IVVpbnQ4QXJyYXl8c3RyaW5nfCFBcnJheS48bnVtYmVyPn0gYnVmZmVyIEFueXRoaW5nIHRoYXQgY2FuIGJlIHdyYXBwZWRcclxuICAgICAqIEBwYXJhbSB7KHN0cmluZ3xib29sZWFuKT19IGVuY29kaW5nIFN0cmluZyBlbmNvZGluZyBpZiBgYnVmZmVyYCBpcyBhIHN0cmluZyAoXCJiYXNlNjRcIiwgXCJoZXhcIiwgXCJiaW5hcnlcIiwgZGVmYXVsdHMgdG9cclxuICAgICAqICBcInV0ZjhcIilcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcy4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQSBCeXRlQnVmZmVyIHdyYXBwaW5nIGBidWZmZXJgXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIud3JhcCA9IGZ1bmN0aW9uKGJ1ZmZlciwgZW5jb2RpbmcsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBub0Fzc2VydCA9IGxpdHRsZUVuZGlhbjtcclxuICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gZW5jb2Rpbmc7XHJcbiAgICAgICAgICAgIGVuY29kaW5nID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHlwZW9mIGJ1ZmZlciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgICAgICBlbmNvZGluZyA9IFwidXRmOFwiO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiYmFzZTY0XCI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbUJhc2U2NChidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiaGV4XCI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbUhleChidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiYmluYXJ5XCI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbUJpbmFyeShidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwidXRmOFwiOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21VVEY4KGJ1ZmZlciwgbGl0dGxlRW5kaWFuKTtcclxuICAgICAgICAgICAgICAgIGNhc2UgXCJkZWJ1Z1wiOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21EZWJ1ZyhidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiVW5zdXBwb3J0ZWQgZW5jb2Rpbmc6IFwiK2VuY29kaW5nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYnVmZmVyID09PSBudWxsIHx8IHR5cGVvZiBidWZmZXIgIT09ICdvYmplY3QnKVxyXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJ1ZmZlclwiKTtcclxuICAgICAgICB2YXIgYmI7XHJcbiAgICAgICAgaWYgKEJ5dGVCdWZmZXIuaXNCeXRlQnVmZmVyKGJ1ZmZlcikpIHtcclxuICAgICAgICAgICAgYmIgPSBCeXRlQnVmZmVyUHJvdG90eXBlLmNsb25lLmNhbGwoYnVmZmVyKTtcclxuICAgICAgICAgICAgYmIubWFya2VkT2Zmc2V0ID0gLTE7XHJcbiAgICAgICAgICAgIHJldHVybiBiYjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsgLy8gRXh0cmFjdCBBcnJheUJ1ZmZlciBmcm9tIFVpbnQ4QXJyYXlcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcigwLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KTtcclxuICAgICAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiAwKSB7IC8vIEF2b2lkIHJlZmVyZW5jZXMgdG8gbW9yZSB0aGFuIG9uZSBFTVBUWV9CVUZGRVJcclxuICAgICAgICAgICAgICAgIGJiLmJ1ZmZlciA9IGJ1ZmZlci5idWZmZXI7XHJcbiAgICAgICAgICAgICAgICBiYi5vZmZzZXQgPSBidWZmZXIuYnl0ZU9mZnNldDtcclxuICAgICAgICAgICAgICAgIGJiLmxpbWl0ID0gYnVmZmVyLmJ5dGVPZmZzZXQgKyBidWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgICAgICAgICAgICAgIGJiLnZpZXcgPSBuZXcgVWludDhBcnJheShidWZmZXIuYnVmZmVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAoYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsgLy8gUmV1c2UgQXJyYXlCdWZmZXJcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcigwLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KTtcclxuICAgICAgICAgICAgaWYgKGJ1ZmZlci5ieXRlTGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgYmIuYnVmZmVyID0gYnVmZmVyO1xyXG4gICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgIGJiLmxpbWl0ID0gYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICBiYi52aWV3ID0gYnVmZmVyLmJ5dGVMZW5ndGggPiAwID8gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSA6IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChidWZmZXIpID09PSBcIltvYmplY3QgQXJyYXldXCIpIHsgLy8gQ3JlYXRlIGZyb20gb2N0ZXRzXHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoYnVmZmVyLmxlbmd0aCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCk7XHJcbiAgICAgICAgICAgIGJiLmxpbWl0ID0gYnVmZmVyLmxlbmd0aDtcclxuICAgICAgICAgICAgZm9yICh2YXIgaT0wOyBpPGJ1ZmZlci5sZW5ndGg7ICsraSlcclxuICAgICAgICAgICAgICAgIGJiLnZpZXdbaV0gPSBidWZmZXJbaV07XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYnVmZmVyXCIpOyAvLyBPdGhlcndpc2UgZmFpbFxyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgdGhlIGFycmF5IGFzIGEgYml0c2V0LlxyXG4gICAgICogQHBhcmFtIHtBcnJheTxib29sZWFuPn0gdmFsdWUgQXJyYXkgb2YgYm9vbGVhbnMgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGBsZW5ndGhgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVCaXRTZXQgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgQXJyYXkpKVxyXG4gICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBCaXRTZXQ6IE5vdCBhbiBhcnJheVwiKTtcclxuICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgICBiaXRzID0gdmFsdWUubGVuZ3RoLFxyXG4gICAgICAgICAgYnl0ZXMgPSAoYml0cyA+PiAzKSxcclxuICAgICAgICAgIGJpdCA9IDAsXHJcbiAgICAgICAgICBrO1xyXG5cclxuICAgICAgb2Zmc2V0ICs9IHRoaXMud3JpdGVWYXJpbnQzMihiaXRzLG9mZnNldCk7XHJcblxyXG4gICAgICB3aGlsZShieXRlcy0tKSB7XHJcbiAgICAgICAgayA9ICghIXZhbHVlW2JpdCsrXSAmIDEpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDEpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDIpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDMpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDQpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDUpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDYpIHxcclxuICAgICAgICAgICAgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IDcpO1xyXG4gICAgICAgIHRoaXMud3JpdGVCeXRlKGssb2Zmc2V0KyspO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZihiaXQgPCBiaXRzKSB7XHJcbiAgICAgICAgdmFyIG0gPSAwOyBrID0gMDtcclxuICAgICAgICB3aGlsZShiaXQgPCBiaXRzKSBrID0gayB8ICgoISF2YWx1ZVtiaXQrK10gJiAxKSA8PCAobSsrKSk7XHJcbiAgICAgICAgdGhpcy53cml0ZUJ5dGUoayxvZmZzZXQrKyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBvZmZzZXQgLSBzdGFydDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgQml0U2V0IGFzIGFuIGFycmF5IG9mIGJvb2xlYW5zLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYGxlbmd0aGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtBcnJheTxib29sZWFuPlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRCaXRTZXQgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuXHJcbiAgICAgIHZhciByZXQgPSB0aGlzLnJlYWRWYXJpbnQzMihvZmZzZXQpLFxyXG4gICAgICAgICAgYml0cyA9IHJldC52YWx1ZSxcclxuICAgICAgICAgIGJ5dGVzID0gKGJpdHMgPj4gMyksXHJcbiAgICAgICAgICBiaXQgPSAwLFxyXG4gICAgICAgICAgdmFsdWUgPSBbXSxcclxuICAgICAgICAgIGs7XHJcblxyXG4gICAgICBvZmZzZXQgKz0gcmV0Lmxlbmd0aDtcclxuXHJcbiAgICAgIHdoaWxlKGJ5dGVzLS0pIHtcclxuICAgICAgICBrID0gdGhpcy5yZWFkQnl0ZShvZmZzZXQrKyk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4MDEpO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDAyKTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHgwNCk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4MDgpO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDEwKTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHgyMCk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4NDApO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDgwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYoYml0IDwgYml0cykge1xyXG4gICAgICAgIHZhciBtID0gMDtcclxuICAgICAgICBrID0gdGhpcy5yZWFkQnl0ZShvZmZzZXQrKyk7XHJcbiAgICAgICAgd2hpbGUoYml0IDwgYml0cykgdmFsdWVbYml0KytdID0gISEoKGsgPj4gKG0rKykpICYgMSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBieXRlcyB0byByZWFkXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgbGVuZ3RoYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRCeXRlcyA9IGZ1bmN0aW9uKGxlbmd0aCwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgbGVuZ3RoID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrbGVuZ3RoK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzbGljZSA9IHRoaXMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBsZW5ndGgpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gbGVuZ3RoO1xuICAgICAgICByZXR1cm4gc2xpY2U7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgcGF5bG9hZCBvZiBieXRlcy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNhcHBlbmR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFCeXRlQnVmZmVyfCFBcnJheUJ1ZmZlcnwhVWludDhBcnJheXxzdHJpbmd9IHNvdXJjZSBEYXRhIHRvIHdyaXRlLiBJZiBgc291cmNlYCBpcyBhIEJ5dGVCdWZmZXIsIGl0cyBvZmZzZXRzXHJcbiAgICAgKiAgd2lsbCBiZSBtb2RpZmllZCBhY2NvcmRpbmcgdG8gdGhlIHBlcmZvcm1lZCByZWFkIG9wZXJhdGlvbi5cclxuICAgICAqIEBwYXJhbSB7KHN0cmluZ3xudW1iZXIpPX0gZW5jb2RpbmcgRW5jb2RpbmcgaWYgYGRhdGFgIGlzIGEgc3RyaW5nIChcImJhc2U2NFwiLCBcImhleFwiLCBcImJpbmFyeVwiLCBkZWZhdWx0cyB0byBcInV0ZjhcIilcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlQnl0ZXMgPSBCeXRlQnVmZmVyUHJvdG90eXBlLmFwcGVuZDtcclxuXHJcbiAgICAvLyB0eXBlcy9pbnRzL2ludDhcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiA4Yml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgIHZhciBjYXBhY2l0eTAgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkwKVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MCAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MCA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSAxO1xuICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0XSA9IHZhbHVlO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIDhiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVJbnQ4fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUJ5dGUgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50ODtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGFuIDhiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMSA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzErXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy52aWV3W29mZnNldF07XHJcbiAgICAgICAgaWYgKCh2YWx1ZSAmIDB4ODApID09PSAweDgwKSB2YWx1ZSA9IC0oMHhGRiAtIHZhbHVlICsgMSk7IC8vIENhc3QgdG8gc2lnbmVkXHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAxO1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gOGJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkSW50OH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEJ5dGUgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQ4O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIDhiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50OCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICB2YXIgY2FwYWNpdHkxID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MSlcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTEgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTEgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gMTtcbiAgICAgICAgdGhpcy52aWV3W29mZnNldF0gPSB2YWx1ZTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDE7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiA4Yml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVVaW50OH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVSW50OCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50ODtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGFuIDhiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMSA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzErXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy52aWV3W29mZnNldF07XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAxO1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gOGJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRVaW50OH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVJbnQ4ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDg7XHJcblxyXG4gICAgLy8gdHlwZXMvaW50cy9pbnQxNlxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMTZiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgb3IgYHZhbHVlYCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDE2ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSB8PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICB2YXIgY2FwYWNpdHkyID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MilcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTIgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTIgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gMjtcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgJiAweEZGMDApID4+PiA4O1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIHZhbHVlICYgMHgwMEZGO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXRdICAgPSAodmFsdWUgJiAweEZGMDApID4+PiA4O1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gIHZhbHVlICYgMHgwMEZGO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDI7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDE2Yml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlSW50MTZ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgb3IgYHZhbHVlYCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVNob3J0ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDE2O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAxNmJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDIgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisyK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IDA7XHJcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQgIF07XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgODtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDg7XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICgodmFsdWUgJiAweDgwMDApID09PSAweDgwMDApIHZhbHVlID0gLSgweEZGRkYgLSB2YWx1ZSArIDEpOyAvLyBDYXN0IHRvIHNpZ25lZFxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMjtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMTZiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZEludDE2fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFNob3J0ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50MTY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAxNmJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIG9yIGB2YWx1ZWAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50MTYgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgdmFyIGNhcGFjaXR5MyA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTMpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkzICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkzIDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDI7XG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKHZhbHVlICYgMHhGRjAwKSA+Pj4gODtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICB2YWx1ZSAmIDB4MDBGRjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0XSAgID0gKHZhbHVlICYgMHhGRjAwKSA+Pj4gODtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9ICB2YWx1ZSAmIDB4MDBGRjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAyO1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAxNmJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlVWludDE2fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIG9yIGB2YWx1ZWAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVSW50MTYgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDE2O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAxNmJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDIgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisyK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IDA7XHJcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQgIF07XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgODtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDg7XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMjtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMTZiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkVWludDE2fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVJbnQxNiA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQxNjtcclxuXHJcbiAgICAvLyB0eXBlcy9pbnRzL2ludDMyXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAzMmJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDMyID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSB8PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSA0O1xuICAgICAgICB2YXIgY2FwYWNpdHk0ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5NClcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTQgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTQgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gNDtcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKHZhbHVlID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9ICh2YWx1ZSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIHZhbHVlICAgICAgICAgJiAweEZGO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKHZhbHVlID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICB2YWx1ZSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlSW50MzJ9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDMyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIis0K1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IDA7XHJcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8IDE2O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQgIF07XG4gICAgICAgICAgICB2YWx1ZSArPSB0aGlzLnZpZXdbb2Zmc2V0KzNdIDw8IDI0ID4+PiAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAxNjtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgIDg7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgdmFsdWUgKz0gdGhpcy52aWV3W29mZnNldCAgXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZSB8PSAwOyAvLyBDYXN0IHRvIHNpZ25lZFxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gNDtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMzJiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZEludDMyfS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDMyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMzJiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVpbnQzMiA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSA0O1xuICAgICAgICB2YXIgY2FwYWNpdHk1ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5NSlcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTUgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTUgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gNDtcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKHZhbHVlID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9ICh2YWx1ZSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIHZhbHVlICAgICAgICAgJiAweEZGO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKHZhbHVlID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICB2YWx1ZSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVVaW50MzJ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVSW50MzIgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDMyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIis0K1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IDA7XHJcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8IDE2O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQgIF07XG4gICAgICAgICAgICB2YWx1ZSArPSB0aGlzLnZpZXdbb2Zmc2V0KzNdIDw8IDI0ID4+PiAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAxNjtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgIDg7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgdmFsdWUgKz0gdGhpcy52aWV3W29mZnNldCAgXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDMyYml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZFVpbnQzMn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVSW50MzIgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVaW50MzI7XHJcblxyXG4gICAgLy8gdHlwZXMvaW50cy9pbnQ2NFxyXG5cclxuICAgIGlmIChMb25nKSB7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdyaXRlcyBhIDY0Yml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQ2NCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghKHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgTG9uZykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlciBvciBMb25nKVwiKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICBvZmZzZXQgKz0gODtcbiAgICAgICAgICAgIHZhciBjYXBhY2l0eTYgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5NilcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHk2ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHk2IDogb2Zmc2V0KTtcbiAgICAgICAgICAgIG9mZnNldCAtPSA4O1xuICAgICAgICAgICAgdmFyIGxvID0gdmFsdWUubG93LFxyXG4gICAgICAgICAgICAgICAgaGkgPSB2YWx1ZS5oaWdoO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAobG8gPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChsbyA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGxvID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgbG8gICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKGhpID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAoaGkgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChoaSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIGhpICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAoaGkgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChoaSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGhpID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAgaGkgICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gKGxvID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAobG8gPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChsbyA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gIGxvICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXcml0ZXMgYSA2NGJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZUludDY0fS5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlTG9uZyA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQ2NDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSA2NGJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDY0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDggPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrOCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBsbyA9IDAsXHJcbiAgICAgICAgICAgICAgICBoaSA9IDA7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICAgICAgbG8gID0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQgIF07XG4gICAgICAgICAgICAgICAgbG8gKz0gdGhpcy52aWV3W29mZnNldCszXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIGhpICA9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgMTY7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xuICAgICAgICAgICAgICAgIGhpICs9IHRoaXMudmlld1tvZmZzZXQrM10gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaGkgID0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQrM107XG4gICAgICAgICAgICAgICAgaGkgKz0gdGhpcy52aWV3W29mZnNldCAgXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIGxvICA9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgMTY7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAgODtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgICAgIGxvICs9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IG5ldyBMb25nKGxvLCBoaSwgZmFsc2UpO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSA2NGJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkSW50NjR9LlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkTG9uZyA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDY0O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXcml0ZXMgYSA2NGJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50NjQgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoISh2YWx1ZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIExvbmcpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIgb3IgTG9uZylcIik7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgb2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICB2YXIgY2FwYWNpdHk3ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTcpXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5NyAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5NyA6IG9mZnNldCk7XG4gICAgICAgICAgICBvZmZzZXQgLT0gODtcbiAgICAgICAgICAgIHZhciBsbyA9IHZhbHVlLmxvdyxcclxuICAgICAgICAgICAgICAgIGhpID0gdmFsdWUuaGlnaDtcclxuICAgICAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKGxvID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAobG8gPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChsbyA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIGxvICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9IChoaSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGhpID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAoaGkgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICBoaSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gKGhpID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAoaGkgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChoaSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gIGhpICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9IChsbyA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGxvID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAobG8gPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICBsbyAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA4O1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV3JpdGVzIGEgNjRiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZVVpbnQ2NH0uXHJcbiAgICAgICAgICogQGZ1bmN0aW9uXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVJbnQ2NCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50NjQ7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlYWRzIGEgNjRiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQ2NCA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA4ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzgrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgbG8gPSAwLFxyXG4gICAgICAgICAgICAgICAgaGkgPSAwO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgICAgIGxvICA9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgMTY7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xuICAgICAgICAgICAgICAgIGxvICs9IHRoaXMudmlld1tvZmZzZXQrM10gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICBoaSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgIDg7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCAgXTtcbiAgICAgICAgICAgICAgICBoaSArPSB0aGlzLnZpZXdbb2Zmc2V0KzNdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGhpICA9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgMTY7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAgODtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgICAgIGhpICs9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICBsbyAgPSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgIDg7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCszXTtcbiAgICAgICAgICAgICAgICBsbyArPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBuZXcgTG9uZyhsbywgaGksIHRydWUpO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSA2NGJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRVaW50NjR9LlxyXG4gICAgICAgICAqIEBmdW5jdGlvblxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVUludDY0ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDY0O1xyXG5cclxuICAgIH0gLy8gTG9uZ1xyXG5cclxuXHJcbiAgICAvLyB0eXBlcy9mbG9hdHMvZmxvYXQzMlxyXG5cclxuICAgIC8qXHJcbiAgICAgaWVlZTc1NCAtIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvaWVlZTc1NFxyXG5cclxuICAgICBUaGUgTUlUIExpY2Vuc2UgKE1JVClcclxuXHJcbiAgICAgQ29weXJpZ2h0IChjKSBGZXJvc3MgQWJvdWtoYWRpamVoXHJcblxyXG4gICAgIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcclxuICAgICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXHJcbiAgICAgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xyXG4gICAgIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcclxuICAgICBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcclxuICAgICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxyXG5cclxuICAgICBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxyXG4gICAgIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxyXG5cclxuICAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXHJcbiAgICAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXHJcbiAgICAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXHJcbiAgICAgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxyXG4gICAgIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXHJcbiAgICAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxyXG4gICAgIFRIRSBTT0ZUV0FSRS5cclxuICAgICovXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhbiBJRUVFNzU0IGZsb2F0IGZyb20gYSBieXRlIGFycmF5LlxyXG4gICAgICogQHBhcmFtIHshQXJyYXl9IGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBpc0xFXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbUxlblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG5CeXRlc1xyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBpZWVlNzU0X3JlYWQoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xyXG4gICAgICAgIHZhciBlLCBtLFxyXG4gICAgICAgICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxyXG4gICAgICAgICAgICBlTWF4ID0gKDEgPDwgZUxlbikgLSAxLFxyXG4gICAgICAgICAgICBlQmlhcyA9IGVNYXggPj4gMSxcclxuICAgICAgICAgICAgbkJpdHMgPSAtNyxcclxuICAgICAgICAgICAgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwLFxyXG4gICAgICAgICAgICBkID0gaXNMRSA/IC0xIDogMSxcclxuICAgICAgICAgICAgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXTtcclxuXHJcbiAgICAgICAgaSArPSBkO1xyXG5cclxuICAgICAgICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKTtcclxuICAgICAgICBzID4+PSAoLW5CaXRzKTtcclxuICAgICAgICBuQml0cyArPSBlTGVuO1xyXG4gICAgICAgIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XHJcblxyXG4gICAgICAgIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpO1xyXG4gICAgICAgIGUgPj49ICgtbkJpdHMpO1xyXG4gICAgICAgIG5CaXRzICs9IG1MZW47XHJcbiAgICAgICAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cclxuXHJcbiAgICAgICAgaWYgKGUgPT09IDApIHtcclxuICAgICAgICAgICAgZSA9IDEgLSBlQmlhcztcclxuICAgICAgICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbik7XHJcbiAgICAgICAgICAgIGUgPSBlIC0gZUJpYXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIElFRUU3NTQgZmxvYXQgdG8gYSBieXRlIGFycmF5LlxyXG4gICAgICogQHBhcmFtIHshQXJyYXl9IGJ1ZmZlclxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGlzTEVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtTGVuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbkJ5dGVzXHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gaWVlZTc1NF93cml0ZShidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xyXG4gICAgICAgIHZhciBlLCBtLCBjLFxyXG4gICAgICAgICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxyXG4gICAgICAgICAgICBlTWF4ID0gKDEgPDwgZUxlbikgLSAxLFxyXG4gICAgICAgICAgICBlQmlhcyA9IGVNYXggPj4gMSxcclxuICAgICAgICAgICAgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApLFxyXG4gICAgICAgICAgICBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSksXHJcbiAgICAgICAgICAgIGQgPSBpc0xFID8gMSA6IC0xLFxyXG4gICAgICAgICAgICBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwO1xyXG5cclxuICAgICAgICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKTtcclxuXHJcbiAgICAgICAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcclxuICAgICAgICAgICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwO1xyXG4gICAgICAgICAgICBlID0gZU1heDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMik7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcclxuICAgICAgICAgICAgICAgIGUtLTtcclxuICAgICAgICAgICAgICAgIGMgKj0gMjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlICs9IHJ0IC8gYztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcclxuICAgICAgICAgICAgICAgIGUrKztcclxuICAgICAgICAgICAgICAgIGMgLz0gMjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XHJcbiAgICAgICAgICAgICAgICBtID0gMDtcclxuICAgICAgICAgICAgICAgIGUgPSBlTWF4O1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XHJcbiAgICAgICAgICAgICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XHJcbiAgICAgICAgICAgICAgICBlID0gZSArIGVCaWFzO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xyXG4gICAgICAgICAgICAgICAgZSA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XHJcblxyXG4gICAgICAgIGUgPSAoZSA8PCBtTGVuKSB8IG07XHJcbiAgICAgICAgZUxlbiArPSBtTGVuO1xyXG4gICAgICAgIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cclxuXHJcbiAgICAgICAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMzJiaXQgZmxvYXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUZsb2F0MzIgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYSBudW1iZXIpXCIpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDQ7XG4gICAgICAgIHZhciBjYXBhY2l0eTggPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHk4KVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5OCAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5OCA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSA0O1xuICAgICAgICBpZWVlNzU0X3dyaXRlKHRoaXMudmlldywgdmFsdWUsIG9mZnNldCwgdGhpcy5saXR0bGVFbmRpYW4sIDIzLCA0KTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IGZsb2F0LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlRmxvYXQzMn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRmxvYXQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRmxvYXQzMjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMzJiaXQgZmxvYXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEZsb2F0MzIgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA0ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrNCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSBpZWVlNzU0X3JlYWQodGhpcy52aWV3LCBvZmZzZXQsIHRoaXMubGl0dGxlRW5kaWFuLCAyMywgNCk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA0O1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCBmbG9hdC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkRmxvYXQzMn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkRmxvYXQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRGbG9hdDMyO1xyXG5cclxuICAgIC8vIHR5cGVzL2Zsb2F0cy9mbG9hdDY0XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSA2NGJpdCBmbG9hdC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRmxvYXQ2NCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhIG51bWJlcilcIik7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gODtcbiAgICAgICAgdmFyIGNhcGFjaXR5OSA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTkpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHk5ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHk5IDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDg7XG4gICAgICAgIGllZWU3NTRfd3JpdGUodGhpcy52aWV3LCB2YWx1ZSwgb2Zmc2V0LCB0aGlzLmxpdHRsZUVuZGlhbiwgNTIsIDgpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gODtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgNjRiaXQgZmxvYXQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVGbG9hdDY0fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVEb3VibGUgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRmxvYXQ2NDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgNjRiaXQgZmxvYXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEZsb2F0NjQgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA4ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrOCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSBpZWVlNzU0X3JlYWQodGhpcy52aWV3LCBvZmZzZXQsIHRoaXMubGl0dGxlRW5kaWFuLCA1MiwgOCk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA4O1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSA2NGJpdCBmbG9hdC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkRmxvYXQ2NH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkRG91YmxlID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkRmxvYXQ2NDtcclxuXHJcblxyXG4gICAgLy8gdHlwZXMvdmFyaW50cy92YXJpbnQzMlxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgYSAzMmJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5NQVhfVkFSSU5UMzJfQllURVMgPSA1O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBzdG9yZSBhIDMyYml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIGVuY29kZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkLiBDYXBwZWQgdG8ge0BsaW5rIEJ5dGVCdWZmZXIuTUFYX1ZBUklOVDMyX0JZVEVTfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmNhbGN1bGF0ZVZhcmludDMyID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICAvLyByZWY6IHNyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmNjXHJcbiAgICAgICAgdmFsdWUgPSB2YWx1ZSA+Pj4gMDtcclxuICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDEgPDwgNyApIHJldHVybiAxO1xyXG4gICAgICAgIGVsc2UgaWYgKHZhbHVlIDwgMSA8PCAxNCkgcmV0dXJuIDI7XHJcbiAgICAgICAgZWxzZSBpZiAodmFsdWUgPCAxIDw8IDIxKSByZXR1cm4gMztcclxuICAgICAgICBlbHNlIGlmICh2YWx1ZSA8IDEgPDwgMjgpIHJldHVybiA0O1xyXG4gICAgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogWmlnemFnIGVuY29kZXMgYSBzaWduZWQgMzJiaXQgaW50ZWdlciBzbyB0aGF0IGl0IGNhbiBiZSBlZmZlY3RpdmVseSB1c2VkIHdpdGggdmFyaW50IGVuY29kaW5nLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gU2lnbmVkIDMyYml0IGludGVnZXJcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFVuc2lnbmVkIHppZ3phZyBlbmNvZGVkIDMyYml0IGludGVnZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci56aWdaYWdFbmNvZGUzMiA9IGZ1bmN0aW9uKG4pIHtcclxuICAgICAgICByZXR1cm4gKCgobiB8PSAwKSA8PCAxKSBeIChuID4+IDMxKSkgPj4+IDA7IC8vIHJlZjogc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmhcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGEgemlnemFnIGVuY29kZWQgc2lnbmVkIDMyYml0IGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBVbnNpZ25lZCB6aWd6YWcgZW5jb2RlZCAzMmJpdCBpbnRlZ2VyXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgMzJiaXQgaW50ZWdlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTMyID0gZnVuY3Rpb24obikge1xyXG4gICAgICAgIHJldHVybiAoKG4gPj4+IDEpIF4gLShuICYgMSkpIHwgMDsgLy8gLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaFxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSB0aGlzIGlmIGBvZmZzZXRgIGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVmFyaW50MzIgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHNpemUgPSBCeXRlQnVmZmVyLmNhbGN1bGF0ZVZhcmludDMyKHZhbHVlKSxcclxuICAgICAgICAgICAgYjtcclxuICAgICAgICBvZmZzZXQgKz0gc2l6ZTtcbiAgICAgICAgdmFyIGNhcGFjaXR5MTAgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxMClcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTEwICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxMCA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSBzaXplO1xuICAgICAgICB2YWx1ZSA+Pj49IDA7XHJcbiAgICAgICAgd2hpbGUgKHZhbHVlID49IDB4ODApIHtcclxuICAgICAgICAgICAgYiA9ICh2YWx1ZSAmIDB4N2YpIHwgMHg4MDtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IGI7XHJcbiAgICAgICAgICAgIHZhbHVlID4+Pj0gNztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IHZhbHVlO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzaXplO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIHppZy16YWcgZW5jb2RlZCAoc2lnbmVkKSAzMmJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gdGhpcyBpZiBgb2Zmc2V0YCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVZhcmludDMyWmlnWmFnID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLndyaXRlVmFyaW50MzIoQnl0ZUJ1ZmZlci56aWdaYWdFbmNvZGUzMih2YWx1ZSksIG9mZnNldCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfCF7dmFsdWU6IG51bWJlciwgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgdmFsdWUgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgdmFsdWUgcmVhZFxyXG4gICAgICogIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIGl0J3Mgbm90IGEgdmFsaWQgdmFyaW50LiBIYXMgYSBwcm9wZXJ0eSBgdHJ1bmNhdGVkID0gdHJ1ZWAgaWYgdGhlcmUgaXMgbm90IGVub3VnaCBkYXRhIGF2YWlsYWJsZVxyXG4gICAgICogIHRvIGZ1bGx5IGRlY29kZSB0aGUgdmFyaW50LlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRWYXJpbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDEgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisxK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBjID0gMCxcclxuICAgICAgICAgICAgdmFsdWUgPSAwID4+PiAwLFxyXG4gICAgICAgICAgICBiO1xyXG4gICAgICAgIGRvIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0ICYmIG9mZnNldCA+IHRoaXMubGltaXQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBlcnIgPSBFcnJvcihcIlRydW5jYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIGVyclsndHJ1bmNhdGVkJ10gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdO1xyXG4gICAgICAgICAgICBpZiAoYyA8IDUpXHJcbiAgICAgICAgICAgICAgICB2YWx1ZSB8PSAoYiAmIDB4N2YpIDw8ICg3KmMpO1xyXG4gICAgICAgICAgICArK2M7XHJcbiAgICAgICAgfSB3aGlsZSAoKGIgJiAweDgwKSAhPT0gMCk7XHJcbiAgICAgICAgdmFsdWUgfD0gMDtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgXCJ2YWx1ZVwiOiB2YWx1ZSxcclxuICAgICAgICAgICAgXCJsZW5ndGhcIjogY1xyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSB6aWctemFnIGVuY29kZWQgKHNpZ25lZCkgMzJiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcnwhe3ZhbHVlOiBudW1iZXIsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHZhbHVlIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHZhbHVlIHJlYWRcclxuICAgICAqICBhbmQgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBpdCdzIG5vdCBhIHZhbGlkIHZhcmludFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRWYXJpbnQzMlppZ1phZyA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciB2YWwgPSB0aGlzLnJlYWRWYXJpbnQzMihvZmZzZXQpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnb2JqZWN0JylcclxuICAgICAgICAgICAgdmFsW1widmFsdWVcIl0gPSBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTMyKHZhbFtcInZhbHVlXCJdKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHZhbCA9IEJ5dGVCdWZmZXIuemlnWmFnRGVjb2RlMzIodmFsKTtcclxuICAgICAgICByZXR1cm4gdmFsO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyB0eXBlcy92YXJpbnRzL3ZhcmludDY0XHJcblxyXG4gICAgaWYgKExvbmcpIHtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgYSA2NGJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICAgICAqIEBjb25zdFxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyLk1BWF9WQVJJTlQ2NF9CWVRFUyA9IDEwO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDYWxjdWxhdGVzIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIGEgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IHZhbHVlIFZhbHVlIHRvIGVuY29kZVxyXG4gICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBieXRlcyByZXF1aXJlZC4gQ2FwcGVkIHRvIHtAbGluayBCeXRlQnVmZmVyLk1BWF9WQVJJTlQ2NF9CWVRFU31cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlci5jYWxjdWxhdGVWYXJpbnQ2NCA9IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5jY1xyXG4gICAgICAgICAgICB2YXIgcGFydDAgPSB2YWx1ZS50b0ludCgpID4+PiAwLFxyXG4gICAgICAgICAgICAgICAgcGFydDEgPSB2YWx1ZS5zaGlmdFJpZ2h0VW5zaWduZWQoMjgpLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgICAgICBwYXJ0MiA9IHZhbHVlLnNoaWZ0UmlnaHRVbnNpZ25lZCg1NikudG9JbnQoKSA+Pj4gMDtcclxuICAgICAgICAgICAgaWYgKHBhcnQyID09IDApIHtcclxuICAgICAgICAgICAgICAgIGlmIChwYXJ0MSA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnQwIDwgMSA8PCAxNClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnQwIDwgMSA8PCA3ID8gMSA6IDI7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFydDAgPCAxIDw8IDIxID8gMyA6IDQ7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0MSA8IDEgPDwgMTQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0MSA8IDEgPDwgNyA/IDUgOiA2O1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnQxIDwgMSA8PCAyMSA/IDcgOiA4O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0MiA8IDEgPDwgNyA/IDkgOiAxMDtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBaaWd6YWcgZW5jb2RlcyBhIHNpZ25lZCA2NGJpdCBpbnRlZ2VyIHNvIHRoYXQgaXQgY2FuIGJlIGVmZmVjdGl2ZWx5IHVzZWQgd2l0aCB2YXJpbnQgZW5jb2RpbmcuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IHZhbHVlIFNpZ25lZCBsb25nXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfSBVbnNpZ25lZCB6aWd6YWcgZW5jb2RlZCBsb25nXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXIuemlnWmFnRW5jb2RlNjQgPSBmdW5jdGlvbih2YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUudW5zaWduZWQgIT09IGZhbHNlKSB2YWx1ZSA9IHZhbHVlLnRvU2lnbmVkKCk7XG4gICAgICAgICAgICAvLyByZWY6IHNyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oXHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zaGlmdExlZnQoMSkueG9yKHZhbHVlLnNoaWZ0UmlnaHQoNjMpKS50b1Vuc2lnbmVkKCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVjb2RlcyBhIHppZ3phZyBlbmNvZGVkIHNpZ25lZCA2NGJpdCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfSB2YWx1ZSBVbnNpZ25lZCB6aWd6YWcgZW5jb2RlZCBsb25nIG9yIEphdmFTY3JpcHQgbnVtYmVyXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTY0ID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUsIGZhbHNlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUsIGZhbHNlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLnVuc2lnbmVkICE9PSBmYWxzZSkgdmFsdWUgPSB2YWx1ZS50b1NpZ25lZCgpO1xuICAgICAgICAgICAgLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaFxyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuc2hpZnRSaWdodFVuc2lnbmVkKDEpLnhvcih2YWx1ZS5hbmQoTG9uZy5PTkUpLnRvU2lnbmVkKCkubmVnYXRlKCkpLnRvU2lnbmVkKCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV3JpdGVzIGEgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8TG9uZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IGB0aGlzYCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuLlxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVmFyaW50NjQgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoISh2YWx1ZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIExvbmcpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIgb3IgTG9uZylcIik7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlLCBmYWxzZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlLCBmYWxzZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZS51bnNpZ25lZCAhPT0gZmFsc2UpIHZhbHVlID0gdmFsdWUudG9TaWduZWQoKTtcbiAgICAgICAgICAgIHZhciBzaXplID0gQnl0ZUJ1ZmZlci5jYWxjdWxhdGVWYXJpbnQ2NCh2YWx1ZSksXHJcbiAgICAgICAgICAgICAgICBwYXJ0MCA9IHZhbHVlLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgICAgICBwYXJ0MSA9IHZhbHVlLnNoaWZ0UmlnaHRVbnNpZ25lZCgyOCkudG9JbnQoKSA+Pj4gMCxcclxuICAgICAgICAgICAgICAgIHBhcnQyID0gdmFsdWUuc2hpZnRSaWdodFVuc2lnbmVkKDU2KS50b0ludCgpID4+PiAwO1xyXG4gICAgICAgICAgICBvZmZzZXQgKz0gc2l6ZTtcbiAgICAgICAgICAgIHZhciBjYXBhY2l0eTExID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTExKVxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTExICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxMSA6IG9mZnNldCk7XG4gICAgICAgICAgICBvZmZzZXQgLT0gc2l6ZTtcbiAgICAgICAgICAgIHN3aXRjaCAoc2l6ZSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxMDogdGhpcy52aWV3W29mZnNldCs5XSA9IChwYXJ0MiA+Pj4gIDcpICYgMHgwMTtcclxuICAgICAgICAgICAgICAgIGNhc2UgOSA6IHRoaXMudmlld1tvZmZzZXQrOF0gPSBzaXplICE9PSA5ID8gKHBhcnQyICAgICAgICkgfCAweDgwIDogKHBhcnQyICAgICAgICkgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA4IDogdGhpcy52aWV3W29mZnNldCs3XSA9IHNpemUgIT09IDggPyAocGFydDEgPj4+IDIxKSB8IDB4ODAgOiAocGFydDEgPj4+IDIxKSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDcgOiB0aGlzLnZpZXdbb2Zmc2V0KzZdID0gc2l6ZSAhPT0gNyA/IChwYXJ0MSA+Pj4gMTQpIHwgMHg4MCA6IChwYXJ0MSA+Pj4gMTQpICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgNiA6IHRoaXMudmlld1tvZmZzZXQrNV0gPSBzaXplICE9PSA2ID8gKHBhcnQxID4+PiAgNykgfCAweDgwIDogKHBhcnQxID4+PiAgNykgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1IDogdGhpcy52aWV3W29mZnNldCs0XSA9IHNpemUgIT09IDUgPyAocGFydDEgICAgICAgKSB8IDB4ODAgOiAocGFydDEgICAgICAgKSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQgOiB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gc2l6ZSAhPT0gNCA/IChwYXJ0MCA+Pj4gMjEpIHwgMHg4MCA6IChwYXJ0MCA+Pj4gMjEpICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgMyA6IHRoaXMudmlld1tvZmZzZXQrMl0gPSBzaXplICE9PSAzID8gKHBhcnQwID4+PiAxNCkgfCAweDgwIDogKHBhcnQwID4+PiAxNCkgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAyIDogdGhpcy52aWV3W29mZnNldCsxXSA9IHNpemUgIT09IDIgPyAocGFydDAgPj4+ICA3KSB8IDB4ODAgOiAocGFydDAgPj4+ICA3KSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDEgOiB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gc2l6ZSAhPT0gMSA/IChwYXJ0MCAgICAgICApIHwgMHg4MCA6IChwYXJ0MCAgICAgICApICYgMHg3RjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ICs9IHNpemU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzaXplO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV3JpdGVzIGEgemlnLXphZyBlbmNvZGVkIDY0Yml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfExvbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSBgdGhpc2AgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbi5cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVZhcmludDY0WmlnWmFnID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy53cml0ZVZhcmludDY0KEJ5dGVCdWZmZXIuemlnWmFnRW5jb2RlNjQodmFsdWUpLCBvZmZzZXQpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlYWRzIGEgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuIFJlcXVpcmVzIExvbmcuanMuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfCF7dmFsdWU6IExvbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHZhbHVlIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHZhbHVlIHJlYWQgYW5kXHJcbiAgICAgICAgICogIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIGl0J3Mgbm90IGEgdmFsaWQgdmFyaW50XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFZhcmludDY0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDEgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMStcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHJlZjogc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2NcclxuICAgICAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgICAgICAgICAgcGFydDAgPSAwLFxyXG4gICAgICAgICAgICAgICAgcGFydDEgPSAwLFxyXG4gICAgICAgICAgICAgICAgcGFydDIgPSAwLFxyXG4gICAgICAgICAgICAgICAgYiAgPSAwO1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDAgID0gKGIgJiAweDdGKSAgICAgIDsgaWYgKCBiICYgMHg4MCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDAgfD0gKGIgJiAweDdGKSA8PCAgNzsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDAgfD0gKGIgJiAweDdGKSA8PCAxNDsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDAgfD0gKGIgJiAweDdGKSA8PCAyMTsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDEgID0gKGIgJiAweDdGKSAgICAgIDsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDEgfD0gKGIgJiAweDdGKSA8PCAgNzsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDEgfD0gKGIgJiAweDdGKSA8PCAxNDsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDEgfD0gKGIgJiAweDdGKSA8PCAyMTsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDIgID0gKGIgJiAweDdGKSAgICAgIDsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTsgcGFydDIgfD0gKGIgJiAweDdGKSA8PCAgNzsgaWYgKChiICYgMHg4MCkgfHwgKHRoaXMubm9Bc3NlcnQgJiYgdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIkJ1ZmZlciBvdmVycnVuXCIpOyB9fX19fX19fX19XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IExvbmcuZnJvbUJpdHMocGFydDAgfCAocGFydDEgPDwgMjgpLCAocGFydDEgPj4+IDQpIHwgKHBhcnQyKSA8PCAyNCwgZmFsc2UpO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAndmFsdWUnOiB2YWx1ZSxcclxuICAgICAgICAgICAgICAgICAgICAnbGVuZ3RoJzogb2Zmc2V0LXN0YXJ0XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSB6aWctemFnIGVuY29kZWQgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuIFJlcXVpcmVzIExvbmcuanMuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfCF7dmFsdWU6IExvbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHZhbHVlIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHZhbHVlIHJlYWQgYW5kXHJcbiAgICAgICAgICogIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIGl0J3Mgbm90IGEgdmFsaWQgdmFyaW50XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFZhcmludDY0WmlnWmFnID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciB2YWwgPSB0aGlzLnJlYWRWYXJpbnQ2NChvZmZzZXQpO1xyXG4gICAgICAgICAgICBpZiAodmFsICYmIHZhbFsndmFsdWUnXSBpbnN0YW5jZW9mIExvbmcpXHJcbiAgICAgICAgICAgICAgICB2YWxbXCJ2YWx1ZVwiXSA9IEJ5dGVCdWZmZXIuemlnWmFnRGVjb2RlNjQodmFsW1widmFsdWVcIl0pO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICB2YWwgPSBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTY0KHZhbCk7XHJcbiAgICAgICAgICAgIHJldHVybiB2YWw7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICB9IC8vIExvbmdcclxuXHJcblxyXG4gICAgLy8gdHlwZXMvc3RyaW5ncy9jc3RyaW5nXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSBOVUxMLXRlcm1pbmF0ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy4gRm9yIHRoaXMgdG8gd29yayB0aGUgc3BlY2lmaWVkIHN0cmluZyBtdXN0IG5vdCBjb250YWluIGFueSBOVUxMXHJcbiAgICAgKiAgY2hhcmFjdGVycyBpdHNlbGYuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgY29udGFpbmVkIGluIGBzdHJgICsgMSBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gdGhpcyBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVDU3RyaW5nID0gZnVuY3Rpb24oc3RyLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgdmFyIGksXHJcbiAgICAgICAgICAgIGsgPSBzdHIubGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgc3RyaW5nXCIpO1xyXG4gICAgICAgICAgICBmb3IgKGk9MDsgaTxrOyArK2kpIHtcclxuICAgICAgICAgICAgICAgIGlmIChzdHIuY2hhckNvZGVBdChpKSA9PT0gMClcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBzdHI6IENvbnRhaW5zIE5VTEwtY2hhcmFjdGVyc1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgLy8gVVRGOCBzdHJpbmdzIGRvIG5vdCBjb250YWluIHplcm8gYnl0ZXMgaW4gYmV0d2VlbiBleGNlcHQgZm9yIHRoZSB6ZXJvIGNoYXJhY3Rlciwgc286XHJcbiAgICAgICAgayA9IHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjgoc3RyaW5nU291cmNlKHN0cikpWzFdO1xyXG4gICAgICAgIG9mZnNldCArPSBrKzE7XG4gICAgICAgIHZhciBjYXBhY2l0eTEyID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MTIpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxMiAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MTIgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gaysxO1xuICAgICAgICB1dGZ4LmVuY29kZVVURjE2dG9VVEY4KHN0cmluZ1NvdXJjZShzdHIpLCBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrK10gPSBiO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IDA7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGs7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSBOVUxMLXRlcm1pbmF0ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy4gRm9yIHRoaXMgdG8gd29yayB0aGUgc3RyaW5nIHJlYWQgbXVzdCBub3QgY29udGFpbiBhbnkgTlVMTCBjaGFyYWN0ZXJzXHJcbiAgICAgKiAgaXRzZWxmLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8IXtzdHJpbmc6IHN0cmluZywgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgc3RyaW5nIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHN0cmluZ1xyXG4gICAgICogIHJlYWQgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZENTdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAxID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMStcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgICAgIHRlbXA7XHJcbiAgICAgICAgLy8gVVRGOCBzdHJpbmdzIGRvIG5vdCBjb250YWluIHplcm8gYnl0ZXMgaW4gYmV0d2VlbiBleGNlcHQgZm9yIHRoZSB6ZXJvIGNoYXJhY3RlciBpdHNlbGYsIHNvOlxyXG4gICAgICAgIHZhciBzZCwgYiA9IC0xO1xyXG4gICAgICAgIHV0ZnguZGVjb2RlVVRGOHRvVVRGMTYoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmIChiID09PSAwKSByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgaWYgKG9mZnNldCA+PSB0aGlzLmxpbWl0KVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IFRydW5jYXRlZCBkYXRhLCBcIitvZmZzZXQrXCIgPCBcIit0aGlzLmxpbWl0KTtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107XHJcbiAgICAgICAgICAgIHJldHVybiBiID09PSAwID8gbnVsbCA6IGI7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpLCBzZCA9IHN0cmluZ0Rlc3RpbmF0aW9uKCksIHRydWUpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHNkKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIFwic3RyaW5nXCI6IHNkKCksXHJcbiAgICAgICAgICAgICAgICBcImxlbmd0aFwiOiBvZmZzZXQgLSBzdGFydFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLy8gdHlwZXMvc3RyaW5ncy9pc3RyaW5nXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSBsZW5ndGggYXMgdWludDMyIHByZWZpeGVkIFVURjggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gYHRoaXNgIGlmIGBvZmZzZXRgIGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3dyaXRlVmFyaW50MzJcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUlTdHJpbmcgPSBmdW5jdGlvbihzdHIsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE5vdCBhIHN0cmluZ1wiKTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzdGFydCA9IG9mZnNldCxcclxuICAgICAgICAgICAgaztcclxuICAgICAgICBrID0gdXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgdGhpcy5ub0Fzc2VydClbMV07XHJcbiAgICAgICAgb2Zmc2V0ICs9IDQraztcbiAgICAgICAgdmFyIGNhcGFjaXR5MTMgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxMylcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTEzICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxMyA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSA0K2s7XG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9IChrID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChrID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChrID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICBrICAgICAgICAgJiAweEZGO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9IChrID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChrID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChrID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICBrICAgICAgICAgJiAweEZGO1xuICAgICAgICB9XG4gICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgIHV0ZnguZW5jb2RlVVRGMTZ0b1VURjgoc3RyaW5nU291cmNlKHN0ciksIGZ1bmN0aW9uKGIpIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IGI7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgICAgICBpZiAob2Zmc2V0ICE9PSBzdGFydCArIDQgKyBrKVxyXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogVHJ1bmNhdGVkIGRhdGEsIFwiK29mZnNldCtcIiA9PSBcIisob2Zmc2V0KzQraykpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvZmZzZXQgLSBzdGFydDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIGxlbmd0aCBhcyB1aW50MzIgcHJlZml4ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfCF7c3RyaW5nOiBzdHJpbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHN0cmluZyByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBzdHJpbmdcclxuICAgICAqICByZWFkIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3JlYWRWYXJpbnQzMlxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJU3RyaW5nID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgNCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzQrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0O1xyXG4gICAgICAgIHZhciBsZW4gPSB0aGlzLnJlYWRVaW50MzIob2Zmc2V0KTtcclxuICAgICAgICB2YXIgc3RyID0gdGhpcy5yZWFkVVRGOFN0cmluZyhsZW4sIEJ5dGVCdWZmZXIuTUVUUklDU19CWVRFUywgb2Zmc2V0ICs9IDQpO1xyXG4gICAgICAgIG9mZnNldCArPSBzdHJbJ2xlbmd0aCddO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHN0clsnc3RyaW5nJ107XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICdzdHJpbmcnOiBzdHJbJ3N0cmluZyddLFxyXG4gICAgICAgICAgICAgICAgJ2xlbmd0aCc6IG9mZnNldCAtIHN0YXJ0XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyB0eXBlcy9zdHJpbmdzL3V0ZjhzdHJpbmdcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldHJpY3MgcmVwcmVzZW50aW5nIG51bWJlciBvZiBVVEY4IGNoYXJhY3RlcnMuIEV2YWx1YXRlcyB0byBgY2AuXHJcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuTUVUUklDU19DSEFSUyA9ICdjJztcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ldHJpY3MgcmVwcmVzZW50aW5nIG51bWJlciBvZiBieXRlcy4gRXZhbHVhdGVzIHRvIGBiYC5cclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5NRVRSSUNTX0JZVEVTID0gJ2InO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIFVURjggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gdGhpcyBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVVRGOFN0cmluZyA9IGZ1bmN0aW9uKHN0ciwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGs7XHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0O1xyXG4gICAgICAgIGsgPSB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpKVsxXTtcclxuICAgICAgICBvZmZzZXQgKz0gaztcbiAgICAgICAgdmFyIGNhcGFjaXR5MTQgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxNClcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTE0ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxNCA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSBrO1xuICAgICAgICB1dGZ4LmVuY29kZVVURjE2dG9VVEY4KHN0cmluZ1NvdXJjZShzdHIpLCBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrK10gPSBiO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiBVVEY4IGVuY29kZWQgc3RyaW5nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlVVRGOFN0cmluZ30uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSB0aGlzIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4uXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVTdHJpbmcgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVVRGOFN0cmluZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgdGhlIG51bWJlciBvZiBVVEY4IGNoYXJhY3RlcnMgb2YgYSBzdHJpbmcuIEphdmFTY3JpcHQgaXRzZWxmIHVzZXMgVVRGLTE2LCBzbyB0aGF0IGEgc3RyaW5nJ3NcclxuICAgICAqICBgbGVuZ3RoYCBwcm9wZXJ0eSBkb2VzIG5vdCByZWZsZWN0IGl0cyBhY3R1YWwgVVRGOCBzaXplIGlmIGl0IGNvbnRhaW5zIGNvZGUgcG9pbnRzIGxhcmdlciB0aGFuIDB4RkZGRi5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNhbGN1bGF0ZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIFVURjggY2hhcmFjdGVyc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmNhbGN1bGF0ZVVURjhDaGFycyA9IGZ1bmN0aW9uKHN0cikge1xyXG4gICAgICAgIHJldHVybiB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpKVswXTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBudW1iZXIgb2YgVVRGOCBieXRlcyBvZiBhIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNhbGN1bGF0ZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIFVURjggYnl0ZXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5jYWxjdWxhdGVVVEY4Qnl0ZXMgPSBmdW5jdGlvbihzdHIpIHtcclxuICAgICAgICByZXR1cm4gdXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSlbMV07XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIFVURjggYnl0ZXMgb2YgYSBzdHJpbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIuY2FsY3VsYXRlVVRGOEJ5dGVzfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gY2FsY3VsYXRlXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgVVRGOCBieXRlc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmNhbGN1bGF0ZVN0cmluZyA9IEJ5dGVCdWZmZXIuY2FsY3VsYXRlVVRGOEJ5dGVzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gVVRGOCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgb3IgYnl0ZXMgdG8gcmVhZC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gbWV0cmljcyBNZXRyaWNzIHNwZWNpZnlpbmcgd2hhdCBgbGVuZ3RoYCBpcyBtZWFudCB0byBjb3VudC4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5NRVRSSUNTX0NIQVJTfS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfCF7c3RyaW5nOiBzdHJpbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHN0cmluZyByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBzdHJpbmdcclxuICAgICAqICByZWFkIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVVEY4U3RyaW5nID0gZnVuY3Rpb24obGVuZ3RoLCBtZXRyaWNzLCBvZmZzZXQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIG1ldHJpY3MgPT09ICdudW1iZXInKSB7XHJcbiAgICAgICAgICAgIG9mZnNldCA9IG1ldHJpY3M7XHJcbiAgICAgICAgICAgIG1ldHJpY3MgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAodHlwZW9mIG1ldHJpY3MgPT09ICd1bmRlZmluZWQnKSBtZXRyaWNzID0gQnl0ZUJ1ZmZlci5NRVRSSUNTX0NIQVJTO1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGxlbmd0aCAhPT0gJ251bWJlcicgfHwgbGVuZ3RoICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGxlbmd0aDogXCIrbGVuZ3RoK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBsZW5ndGggfD0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaSA9IDAsXHJcbiAgICAgICAgICAgIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgICAgICBzZDtcclxuICAgICAgICBpZiAobWV0cmljcyA9PT0gQnl0ZUJ1ZmZlci5NRVRSSUNTX0NIQVJTKSB7IC8vIFRoZSBzYW1lIGZvciBub2RlIGFuZCB0aGUgYnJvd3NlclxyXG4gICAgICAgICAgICBzZCA9IHN0cmluZ0Rlc3RpbmF0aW9uKCk7XHJcbiAgICAgICAgICAgIHV0ZnguZGVjb2RlVVRGOChmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpIDwgbGVuZ3RoICYmIG9mZnNldCA8IHRoaXMubGltaXQgPyB0aGlzLnZpZXdbb2Zmc2V0KytdIDogbnVsbDtcclxuICAgICAgICAgICAgfS5iaW5kKHRoaXMpLCBmdW5jdGlvbihjcCkge1xyXG4gICAgICAgICAgICAgICAgKytpOyB1dGZ4LlVURjh0b1VURjE2KGNwLCBzZCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBpZiAoaSAhPT0gbGVuZ3RoKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IFRydW5jYXRlZCBkYXRhLCBcIitpK1wiID09IFwiK2xlbmd0aCk7XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc2QoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgXCJzdHJpbmdcIjogc2QoKSxcclxuICAgICAgICAgICAgICAgICAgICBcImxlbmd0aFwiOiBvZmZzZXQgLSBzdGFydFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAobWV0cmljcyA9PT0gQnl0ZUJ1ZmZlci5NRVRSSUNTX0JZVEVTKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIGxlbmd0aCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIitsZW5ndGgrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgayA9IG9mZnNldCArIGxlbmd0aDtcclxuICAgICAgICAgICAgdXRmeC5kZWNvZGVVVEY4dG9VVEYxNihmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQgPCBrID8gdGhpcy52aWV3W29mZnNldCsrXSA6IG51bGw7XHJcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSwgc2QgPSBzdHJpbmdEZXN0aW5hdGlvbigpLCB0aGlzLm5vQXNzZXJ0KTtcclxuICAgICAgICAgICAgaWYgKG9mZnNldCAhPT0gaylcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiBUcnVuY2F0ZWQgZGF0YSwgXCIrb2Zmc2V0K1wiID09IFwiK2spO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNkKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICdzdHJpbmcnOiBzZCgpLFxyXG4gICAgICAgICAgICAgICAgICAgICdsZW5ndGgnOiBvZmZzZXQgLSBzdGFydFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJVbnN1cHBvcnRlZCBtZXRyaWNzOiBcIittZXRyaWNzKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhbiBVVEY4IGVuY29kZWQgc3RyaW5nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRVVEY4U3RyaW5nfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyBvciBieXRlcyB0byByZWFkXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG1ldHJpY3MgTWV0cmljcyBzcGVjaWZ5aW5nIHdoYXQgYG5gIGlzIG1lYW50IHRvIGNvdW50LiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLk1FVFJJQ1NfQ0hBUlN9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8IXtzdHJpbmc6IHN0cmluZywgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgc3RyaW5nIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHN0cmluZ1xyXG4gICAgICogIHJlYWQgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFN0cmluZyA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVURjhTdHJpbmc7XHJcblxyXG4gICAgLy8gdHlwZXMvc3RyaW5ncy92c3RyaW5nXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSBsZW5ndGggYXMgdmFyaW50MzIgcHJlZml4ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSBgdGhpc2AgaWYgYG9mZnNldGAgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjd3JpdGVWYXJpbnQzMlxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVlN0cmluZyA9IGZ1bmN0aW9uKHN0ciwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgc3RyaW5nXCIpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgICAgICBrLCBsO1xyXG4gICAgICAgIGsgPSB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpLCB0aGlzLm5vQXNzZXJ0KVsxXTtcclxuICAgICAgICBsID0gQnl0ZUJ1ZmZlci5jYWxjdWxhdGVWYXJpbnQzMihrKTtcclxuICAgICAgICBvZmZzZXQgKz0gbCtrO1xuICAgICAgICB2YXIgY2FwYWNpdHkxNSA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTE1KVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MTUgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTE1IDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IGwraztcbiAgICAgICAgb2Zmc2V0ICs9IHRoaXMud3JpdGVWYXJpbnQzMihrLCBvZmZzZXQpO1xyXG4gICAgICAgIHV0ZnguZW5jb2RlVVRGMTZ0b1VURjgoc3RyaW5nU291cmNlKHN0ciksIGZ1bmN0aW9uKGIpIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IGI7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgICAgICBpZiAob2Zmc2V0ICE9PSBzdGFydCtrK2wpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiBUcnVuY2F0ZWQgZGF0YSwgXCIrb2Zmc2V0K1wiID09IFwiKyhvZmZzZXQraytsKSk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgbGVuZ3RoIGFzIHZhcmludDMyIHByZWZpeGVkIFVURjggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcmVhZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ3whe3N0cmluZzogc3RyaW5nLCBsZW5ndGg6IG51bWJlcn19IFRoZSBzdHJpbmcgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgc3RyaW5nXHJcbiAgICAgKiAgcmVhZCBhbmQgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNyZWFkVmFyaW50MzJcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVlN0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDEgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisxK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzdGFydCA9IG9mZnNldDtcclxuICAgICAgICB2YXIgbGVuID0gdGhpcy5yZWFkVmFyaW50MzIob2Zmc2V0KTtcclxuICAgICAgICB2YXIgc3RyID0gdGhpcy5yZWFkVVRGOFN0cmluZyhsZW5bJ3ZhbHVlJ10sIEJ5dGVCdWZmZXIuTUVUUklDU19CWVRFUywgb2Zmc2V0ICs9IGxlblsnbGVuZ3RoJ10pO1xyXG4gICAgICAgIG9mZnNldCArPSBzdHJbJ2xlbmd0aCddO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHN0clsnc3RyaW5nJ107XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICdzdHJpbmcnOiBzdHJbJ3N0cmluZyddLFxyXG4gICAgICAgICAgICAgICAgJ2xlbmd0aCc6IG9mZnNldCAtIHN0YXJ0XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBcHBlbmRzIHNvbWUgZGF0YSB0byB0aGlzIEJ5dGVCdWZmZXIuIFRoaXMgd2lsbCBvdmVyd3JpdGUgYW55IGNvbnRlbnRzIGJlaGluZCB0aGUgc3BlY2lmaWVkIG9mZnNldCB1cCB0byB0aGUgYXBwZW5kZWRcclxuICAgICAqICBkYXRhJ3MgbGVuZ3RoLlxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcnwhQXJyYXlCdWZmZXJ8IVVpbnQ4QXJyYXl8c3RyaW5nfSBzb3VyY2UgRGF0YSB0byBhcHBlbmQuIElmIGBzb3VyY2VgIGlzIGEgQnl0ZUJ1ZmZlciwgaXRzIG9mZnNldHNcclxuICAgICAqICB3aWxsIGJlIG1vZGlmaWVkIGFjY29yZGluZyB0byB0aGUgcGVyZm9ybWVkIHJlYWQgb3BlcmF0aW9uLlxyXG4gICAgICogQHBhcmFtIHsoc3RyaW5nfG51bWJlcik9fSBlbmNvZGluZyBFbmNvZGluZyBpZiBgZGF0YWAgaXMgYSBzdHJpbmcgKFwiYmFzZTY0XCIsIFwiaGV4XCIsIFwiYmluYXJ5XCIsIGRlZmF1bHRzIHRvIFwidXRmOFwiKVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIGFwcGVuZCBhdC4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQGV4YW1wbGUgQSByZWxhdGl2ZSBgPDAxIDAyPjAzLmFwcGVuZCg8MDQgMDU+KWAgd2lsbCByZXN1bHQgaW4gYDwwMSAwMiAwNCAwNT4sIDA0IDA1fGBcclxuICAgICAqIEBleGFtcGxlIEFuIGFic29sdXRlIGA8MDEgMDI+MDMuYXBwZW5kKDA0IDA1PiwgMSlgIHdpbGwgcmVzdWx0IGluIGA8MDEgMDQ+MDUsIDA0IDA1fGBcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbihzb3VyY2UsIGVuY29kaW5nLCBvZmZzZXQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIG9mZnNldCA9IGVuY29kaW5nO1xyXG4gICAgICAgICAgICBlbmNvZGluZyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCEoc291cmNlIGluc3RhbmNlb2YgQnl0ZUJ1ZmZlcikpXHJcbiAgICAgICAgICAgIHNvdXJjZSA9IEJ5dGVCdWZmZXIud3JhcChzb3VyY2UsIGVuY29kaW5nKTtcclxuICAgICAgICB2YXIgbGVuZ3RoID0gc291cmNlLmxpbWl0IC0gc291cmNlLm9mZnNldDtcclxuICAgICAgICBpZiAobGVuZ3RoIDw9IDApIHJldHVybiB0aGlzOyAvLyBOb3RoaW5nIHRvIGFwcGVuZFxyXG4gICAgICAgIG9mZnNldCArPSBsZW5ndGg7XG4gICAgICAgIHZhciBjYXBhY2l0eTE2ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MTYpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxNiAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MTYgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gbGVuZ3RoO1xuICAgICAgICB0aGlzLnZpZXcuc2V0KHNvdXJjZS52aWV3LnN1YmFycmF5KHNvdXJjZS5vZmZzZXQsIHNvdXJjZS5saW1pdCksIG9mZnNldCk7XHJcbiAgICAgICAgc291cmNlLm9mZnNldCArPSBsZW5ndGg7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSBsZW5ndGg7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGVuZHMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMgdG8gYW5vdGhlciBCeXRlQnVmZmVyLiBUaGlzIHdpbGwgb3ZlcndyaXRlIGFueSBjb250ZW50cyBhdCBhbmQgYWZ0ZXIgdGhlXHJcbiAgICAgICAgc3BlY2lmaWVkIG9mZnNldCB1cCB0byB0aGUgbGVuZ3RoIG9mIHRoaXMgQnl0ZUJ1ZmZlcidzIGRhdGEuXHJcbiAgICAgKiBAcGFyYW0geyFCeXRlQnVmZmVyfSB0YXJnZXQgVGFyZ2V0IEJ5dGVCdWZmZXJcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byBhcHBlbmQgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNhcHBlbmRcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5hcHBlbmRUbyA9IGZ1bmN0aW9uKHRhcmdldCwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdGFyZ2V0LmFwcGVuZCh0aGlzLCBvZmZzZXQpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgYXNzZXJ0aW9ucyBvZiBhcmd1bWVudCB0eXBlcyBhbmQgb2Zmc2V0cy4gQXNzZXJ0aW9ucyBhcmUgZW5hYmxlZCBieSBkZWZhdWx0IGJ1dCB5b3UgY2FuIG9wdCB0b1xyXG4gICAgICogIGRpc2FibGUgdGhlbSBpZiB5b3VyIGNvZGUgYWxyZWFkeSBtYWtlcyBzdXJlIHRoYXQgZXZlcnl0aGluZyBpcyB2YWxpZC5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYXNzZXJ0IGB0cnVlYCB0byBlbmFibGUgYXNzZXJ0aW9ucywgb3RoZXJ3aXNlIGBmYWxzZWBcclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmFzc2VydCA9IGZ1bmN0aW9uKGFzc2VydCkge1xyXG4gICAgICAgIHRoaXMubm9Bc3NlcnQgPSAhYXNzZXJ0O1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGNhcGFjaXR5IG9mIHRoaXMgQnl0ZUJ1ZmZlcidzIGJhY2tpbmcgYnVmZmVyLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gQ2FwYWNpdHkgb2YgdGhlIGJhY2tpbmcgYnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuY2FwYWNpdHkgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIENsZWFycyB0aGlzIEJ5dGVCdWZmZXIncyBvZmZzZXRzIGJ5IHNldHRpbmcge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSB0byBgMGAgYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fSB0byB0aGVcclxuICAgICAqICBiYWNraW5nIGJ1ZmZlcidzIGNhcGFjaXR5LiBEaXNjYXJkcyB7QGxpbmsgQnl0ZUJ1ZmZlciNtYXJrZWRPZmZzZXR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB0aGlzLm9mZnNldCA9IDA7XHJcbiAgICAgICAgdGhpcy5saW1pdCA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgdGhpcy5tYXJrZWRPZmZzZXQgPSAtMTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmVkIGluc3RhbmNlIG9mIHRoaXMgQnl0ZUJ1ZmZlciwgcHJlc2V0IHdpdGggdGhpcyBCeXRlQnVmZmVyJ3MgdmFsdWVzIGZvciB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LFxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI21hcmtlZE9mZnNldH0gYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGNvcHkgV2hldGhlciB0byBjb3B5IHRoZSBiYWNraW5nIGJ1ZmZlciBvciB0byByZXR1cm4gYW5vdGhlciB2aWV3IG9uIHRoZSBzYW1lLCBkZWZhdWx0cyB0byBgZmFsc2VgXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IENsb25lZCBpbnN0YW5jZVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oY29weSkge1xyXG4gICAgICAgIHZhciBiYiA9IG5ldyBCeXRlQnVmZmVyKDAsIHRoaXMubGl0dGxlRW5kaWFuLCB0aGlzLm5vQXNzZXJ0KTtcclxuICAgICAgICBpZiAoY29weSkge1xyXG4gICAgICAgICAgICBiYi5idWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgICAgIGJiLnZpZXcgPSBuZXcgVWludDhBcnJheShiYi5idWZmZXIpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGJiLmJ1ZmZlciA9IHRoaXMuYnVmZmVyO1xyXG4gICAgICAgICAgICBiYi52aWV3ID0gdGhpcy52aWV3O1xyXG4gICAgICAgIH1cclxuICAgICAgICBiYi5vZmZzZXQgPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBiYi5tYXJrZWRPZmZzZXQgPSB0aGlzLm1hcmtlZE9mZnNldDtcclxuICAgICAgICBiYi5saW1pdCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbXBhY3RzIHRoaXMgQnl0ZUJ1ZmZlciB0byBiZSBiYWNrZWQgYnkgYSB7QGxpbmsgQnl0ZUJ1ZmZlciNidWZmZXJ9IG9mIGl0cyBjb250ZW50cycgbGVuZ3RoLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzXHJcbiAgICAgKiAgYmV0d2VlbiB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uIFdpbGwgc2V0IGBvZmZzZXQgPSAwYCBhbmQgYGxpbWl0ID0gY2FwYWNpdHlgIGFuZFxyXG4gICAgICogIGFkYXB0IHtAbGluayBCeXRlQnVmZmVyI21hcmtlZE9mZnNldH0gdG8gdGhlIHNhbWUgcmVsYXRpdmUgcG9zaXRpb24gaWYgc2V0LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gc3RhcnQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH1cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fVxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuY29tcGFjdCA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJykgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmVnaW4gIT09ICdudW1iZXInIHx8IGJlZ2luICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJlZ2luOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGJlZ2luID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kICE9PSAnbnVtYmVyJyB8fCBlbmQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgZW5kOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGVuZCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGJlZ2luID4gZW5kIHx8IGVuZCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrYmVnaW4rXCIgPD0gXCIrZW5kK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJlZ2luID09PSAwICYmIGVuZCA9PT0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7IC8vIEFscmVhZHkgY29tcGFjdGVkXHJcbiAgICAgICAgdmFyIGxlbiA9IGVuZCAtIGJlZ2luO1xyXG4gICAgICAgIGlmIChsZW4gPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBFTVBUWV9CVUZGRVI7XHJcbiAgICAgICAgICAgIHRoaXMudmlldyA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1hcmtlZE9mZnNldCA+PSAwKSB0aGlzLm1hcmtlZE9mZnNldCAtPSBiZWdpbjtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICB0aGlzLmxpbWl0ID0gMDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIobGVuKTtcclxuICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgdmlldy5zZXQodGhpcy52aWV3LnN1YmFycmF5KGJlZ2luLCBlbmQpKTtcclxuICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcclxuICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xyXG4gICAgICAgIGlmICh0aGlzLm1hcmtlZE9mZnNldCA+PSAwKSB0aGlzLm1hcmtlZE9mZnNldCAtPSBiZWdpbjtcclxuICAgICAgICB0aGlzLm9mZnNldCA9IDA7XHJcbiAgICAgICAgdGhpcy5saW1pdCA9IGxlbjtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cy4gQ29udGVudHMgYXJlIHRoZSBieXRlcyBiZXR3ZWVuIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBCZWdpbiBvZmZzZXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBFbmQgb2Zmc2V0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IENvcHlcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKSBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYmVnaW4gPT09IGVuZClcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBCeXRlQnVmZmVyKDAsIHRoaXMubGl0dGxlRW5kaWFuLCB0aGlzLm5vQXNzZXJ0KTtcclxuICAgICAgICB2YXIgY2FwYWNpdHkgPSBlbmQgLSBiZWdpbixcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcihjYXBhY2l0eSwgdGhpcy5saXR0bGVFbmRpYW4sIHRoaXMubm9Bc3NlcnQpO1xyXG4gICAgICAgIGJiLm9mZnNldCA9IDA7XHJcbiAgICAgICAgYmIubGltaXQgPSBjYXBhY2l0eTtcclxuICAgICAgICBpZiAoYmIubWFya2VkT2Zmc2V0ID49IDApIGJiLm1hcmtlZE9mZnNldCAtPSBiZWdpbjtcclxuICAgICAgICB0aGlzLmNvcHlUbyhiYiwgMCwgYmVnaW4sIGVuZCk7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvcGllcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cyB0byBhbm90aGVyIEJ5dGVCdWZmZXIuIENvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYmV0d2VlbiB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZFxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEBwYXJhbSB7IUJ5dGVCdWZmZXJ9IHRhcmdldCBUYXJnZXQgQnl0ZUJ1ZmZlclxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSB0YXJnZXRPZmZzZXQgT2Zmc2V0IHRvIGNvcHkgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB0aGUgdGFyZ2V0J3Mge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fVxyXG4gICAgICogIGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXMgY29waWVkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IHNvdXJjZU9mZnNldCBPZmZzZXQgdG8gc3RhcnQgY29weWluZyBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGVcclxuICAgICAqICBudW1iZXIgb2YgYnl0ZXMgY29waWVkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IHNvdXJjZUxpbWl0IE9mZnNldCB0byBlbmQgY29weWluZyBmcm9tLCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH1cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmNvcHlUbyA9IGZ1bmN0aW9uKHRhcmdldCwgdGFyZ2V0T2Zmc2V0LCBzb3VyY2VPZmZzZXQsIHNvdXJjZUxpbWl0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlLFxyXG4gICAgICAgICAgICB0YXJnZXRSZWxhdGl2ZTtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKCFCeXRlQnVmZmVyLmlzQnl0ZUJ1ZmZlcih0YXJnZXQpKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB0YXJnZXQ6IE5vdCBhIEJ5dGVCdWZmZXJcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRhcmdldE9mZnNldCA9ICh0YXJnZXRSZWxhdGl2ZSA9IHR5cGVvZiB0YXJnZXRPZmZzZXQgPT09ICd1bmRlZmluZWQnKSA/IHRhcmdldC5vZmZzZXQgOiB0YXJnZXRPZmZzZXQgfCAwO1xyXG4gICAgICAgIHNvdXJjZU9mZnNldCA9IChyZWxhdGl2ZSA9IHR5cGVvZiBzb3VyY2VPZmZzZXQgPT09ICd1bmRlZmluZWQnKSA/IHRoaXMub2Zmc2V0IDogc291cmNlT2Zmc2V0IHwgMDtcclxuICAgICAgICBzb3VyY2VMaW1pdCA9IHR5cGVvZiBzb3VyY2VMaW1pdCA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLmxpbWl0IDogc291cmNlTGltaXQgfCAwO1xyXG5cclxuICAgICAgICBpZiAodGFyZ2V0T2Zmc2V0IDwgMCB8fCB0YXJnZXRPZmZzZXQgPiB0YXJnZXQuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHRhcmdldCByYW5nZTogMCA8PSBcIit0YXJnZXRPZmZzZXQrXCIgPD0gXCIrdGFyZ2V0LmJ1ZmZlci5ieXRlTGVuZ3RoKTtcclxuICAgICAgICBpZiAoc291cmNlT2Zmc2V0IDwgMCB8fCBzb3VyY2VMaW1pdCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHNvdXJjZSByYW5nZTogMCA8PSBcIitzb3VyY2VPZmZzZXQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XHJcblxyXG4gICAgICAgIHZhciBsZW4gPSBzb3VyY2VMaW1pdCAtIHNvdXJjZU9mZnNldDtcclxuICAgICAgICBpZiAobGVuID09PSAwKVxyXG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0OyAvLyBOb3RoaW5nIHRvIGNvcHlcclxuXHJcbiAgICAgICAgdGFyZ2V0LmVuc3VyZUNhcGFjaXR5KHRhcmdldE9mZnNldCArIGxlbik7XHJcblxyXG4gICAgICAgIHRhcmdldC52aWV3LnNldCh0aGlzLnZpZXcuc3ViYXJyYXkoc291cmNlT2Zmc2V0LCBzb3VyY2VMaW1pdCksIHRhcmdldE9mZnNldCk7XHJcblxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gbGVuO1xyXG4gICAgICAgIGlmICh0YXJnZXRSZWxhdGl2ZSkgdGFyZ2V0Lm9mZnNldCArPSBsZW47XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ha2VzIHN1cmUgdGhhdCB0aGlzIEJ5dGVCdWZmZXIgaXMgYmFja2VkIGJ5IGEge0BsaW5rIEJ5dGVCdWZmZXIjYnVmZmVyfSBvZiBhdCBsZWFzdCB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5LiBJZiB0aGVcclxuICAgICAqICBjdXJyZW50IGNhcGFjaXR5IGlzIGV4Y2VlZGVkLCBpdCB3aWxsIGJlIGRvdWJsZWQuIElmIGRvdWJsZSB0aGUgY3VycmVudCBjYXBhY2l0eSBpcyBsZXNzIHRoYW4gdGhlIHJlcXVpcmVkIGNhcGFjaXR5LFxyXG4gICAgICogIHRoZSByZXF1aXJlZCBjYXBhY2l0eSB3aWxsIGJlIHVzZWQgaW5zdGVhZC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjYXBhY2l0eSBSZXF1aXJlZCBjYXBhY2l0eVxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuZW5zdXJlQ2FwYWNpdHkgPSBmdW5jdGlvbihjYXBhY2l0eSkge1xyXG4gICAgICAgIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgICAgICBpZiAoY3VycmVudCA8IGNhcGFjaXR5KVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZXNpemUoKGN1cnJlbnQgKj0gMikgPiBjYXBhY2l0eSA/IGN1cnJlbnQgOiBjYXBhY2l0eSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogT3ZlcndyaXRlcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cyB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWUuIENvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYmV0d2VlblxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gdmFsdWUgQnl0ZSB2YWx1ZSB0byBmaWxsIHdpdGguIElmIGdpdmVuIGFzIGEgc3RyaW5nLCB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIHVzZWQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIEJlZ2luIG9mZnNldC4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC4gZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIEVuZCBvZmZzZXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQGV4YW1wbGUgYHNvbWVCeXRlQnVmZmVyLmNsZWFyKCkuZmlsbCgwKWAgZmlsbHMgdGhlIGVudGlyZSBiYWNraW5nIGJ1ZmZlciB3aXRoIHplcm9lc1xyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbih2YWx1ZSwgYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgYmVnaW4gPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUubGVuZ3RoID4gMClcclxuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5jaGFyQ29kZUF0KDApO1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKSBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSB8PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYmVnaW4gPj0gZW5kKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpczsgLy8gTm90aGluZyB0byBmaWxsXHJcbiAgICAgICAgd2hpbGUgKGJlZ2luIDwgZW5kKSB0aGlzLnZpZXdbYmVnaW4rK10gPSB2YWx1ZTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ID0gYmVnaW47XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFrZXMgdGhpcyBCeXRlQnVmZmVyIHJlYWR5IGZvciBhIG5ldyBzZXF1ZW5jZSBvZiB3cml0ZSBvciByZWxhdGl2ZSByZWFkIG9wZXJhdGlvbnMuIFNldHMgYGxpbWl0ID0gb2Zmc2V0YCBhbmRcclxuICAgICAqICBgb2Zmc2V0ID0gMGAuIE1ha2Ugc3VyZSBhbHdheXMgdG8gZmxpcCBhIEJ5dGVCdWZmZXIgd2hlbiBhbGwgcmVsYXRpdmUgcmVhZCBvciB3cml0ZSBvcGVyYXRpb25zIGFyZSBjb21wbGV0ZS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmZsaXAgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB0aGlzLmxpbWl0ID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogTWFya3MgYW4gb2Zmc2V0IG9uIHRoaXMgQnl0ZUJ1ZmZlciB0byBiZSB1c2VkIGxhdGVyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIG1hcmsuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjcmVzZXRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5tYXJrID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgb2Zmc2V0ID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLm9mZnNldCA6IG9mZnNldDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubWFya2VkT2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgYnl0ZSBvcmRlci5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gbGl0dGxlRW5kaWFuIGB0cnVlYCBmb3IgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLCBgZmFsc2VgIGZvciBiaWcgZW5kaWFuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5vcmRlciA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGxpdHRsZUVuZGlhbiAhPT0gJ2Jvb2xlYW4nKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBsaXR0bGVFbmRpYW46IE5vdCBhIGJvb2xlYW5cIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubGl0dGxlRW5kaWFuID0gISFsaXR0bGVFbmRpYW47XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3dpdGNoZXMgKHRvKSBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gRGVmYXVsdHMgdG8gYHRydWVgLCBvdGhlcndpc2UgdXNlcyBiaWcgZW5kaWFuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5MRSA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgIHRoaXMubGl0dGxlRW5kaWFuID0gdHlwZW9mIGxpdHRsZUVuZGlhbiAhPT0gJ3VuZGVmaW5lZCcgPyAhIWxpdHRsZUVuZGlhbiA6IHRydWU7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3dpdGNoZXMgKHRvKSBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBiaWdFbmRpYW4gRGVmYXVsdHMgdG8gYHRydWVgLCBvdGhlcndpc2UgdXNlcyBsaXR0bGUgZW5kaWFuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5CRSA9IGZ1bmN0aW9uKGJpZ0VuZGlhbikge1xyXG4gICAgICAgIHRoaXMubGl0dGxlRW5kaWFuID0gdHlwZW9mIGJpZ0VuZGlhbiAhPT0gJ3VuZGVmaW5lZCcgPyAhYmlnRW5kaWFuIDogZmFsc2U7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBQcmVwZW5kcyBzb21lIGRhdGEgdG8gdGhpcyBCeXRlQnVmZmVyLiBUaGlzIHdpbGwgb3ZlcndyaXRlIGFueSBjb250ZW50cyBiZWZvcmUgdGhlIHNwZWNpZmllZCBvZmZzZXQgdXAgdG8gdGhlXHJcbiAgICAgKiAgcHJlcGVuZGVkIGRhdGEncyBsZW5ndGguIElmIHRoZXJlIGlzIG5vdCBlbm91Z2ggc3BhY2UgYXZhaWxhYmxlIGJlZm9yZSB0aGUgc3BlY2lmaWVkIGBvZmZzZXRgLCB0aGUgYmFja2luZyBidWZmZXJcclxuICAgICAqICB3aWxsIGJlIHJlc2l6ZWQgYW5kIGl0cyBjb250ZW50cyBtb3ZlZCBhY2NvcmRpbmdseS5cclxuICAgICAqIEBwYXJhbSB7IUJ5dGVCdWZmZXJ8c3RyaW5nfCFBcnJheUJ1ZmZlcn0gc291cmNlIERhdGEgdG8gcHJlcGVuZC4gSWYgYHNvdXJjZWAgaXMgYSBCeXRlQnVmZmVyLCBpdHMgb2Zmc2V0IHdpbGwgYmVcclxuICAgICAqICBtb2RpZmllZCBhY2NvcmRpbmcgdG8gdGhlIHBlcmZvcm1lZCByZWFkIG9wZXJhdGlvbi5cclxuICAgICAqIEBwYXJhbSB7KHN0cmluZ3xudW1iZXIpPX0gZW5jb2RpbmcgRW5jb2RpbmcgaWYgYGRhdGFgIGlzIGEgc3RyaW5nIChcImJhc2U2NFwiLCBcImhleFwiLCBcImJpbmFyeVwiLCBkZWZhdWx0cyB0byBcInV0ZjhcIilcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byBwcmVwZW5kIGF0LiBXaWxsIHVzZSBhbmQgZGVjcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcHJlcGVuZGVkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBleGFtcGxlIEEgcmVsYXRpdmUgYDAwPDAxIDAyIDAzPi5wcmVwZW5kKDwwNCAwNT4pYCByZXN1bHRzIGluIGA8MDQgMDUgMDEgMDIgMDM+LCAwNCAwNXxgXHJcbiAgICAgKiBAZXhhbXBsZSBBbiBhYnNvbHV0ZSBgMDA8MDEgMDIgMDM+LnByZXBlbmQoPDA0IDA1PiwgMilgIHJlc3VsdHMgaW4gYDA0PDA1IDAyIDAzPiwgMDQgMDV8YFxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnByZXBlbmQgPSBmdW5jdGlvbihzb3VyY2UsIGVuY29kaW5nLCBvZmZzZXQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIG9mZnNldCA9IGVuY29kaW5nO1xyXG4gICAgICAgICAgICBlbmNvZGluZyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCEoc291cmNlIGluc3RhbmNlb2YgQnl0ZUJ1ZmZlcikpXHJcbiAgICAgICAgICAgIHNvdXJjZSA9IEJ5dGVCdWZmZXIud3JhcChzb3VyY2UsIGVuY29kaW5nKTtcclxuICAgICAgICB2YXIgbGVuID0gc291cmNlLmxpbWl0IC0gc291cmNlLm9mZnNldDtcclxuICAgICAgICBpZiAobGVuIDw9IDApIHJldHVybiB0aGlzOyAvLyBOb3RoaW5nIHRvIHByZXBlbmRcclxuICAgICAgICB2YXIgZGlmZiA9IGxlbiAtIG9mZnNldDtcclxuICAgICAgICBpZiAoZGlmZiA+IDApIHsgLy8gTm90IGVub3VnaCBzcGFjZSBiZWZvcmUgb2Zmc2V0LCBzbyByZXNpemUgKyBtb3ZlXHJcbiAgICAgICAgICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy5idWZmZXIuYnl0ZUxlbmd0aCArIGRpZmYpO1xyXG4gICAgICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgICAgIHZpZXcuc2V0KHRoaXMudmlldy5zdWJhcnJheShvZmZzZXQsIHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpLCBsZW4pO1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcclxuICAgICAgICAgICAgdGhpcy52aWV3ID0gdmlldztcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgKz0gZGlmZjtcclxuICAgICAgICAgICAgaWYgKHRoaXMubWFya2VkT2Zmc2V0ID49IDApIHRoaXMubWFya2VkT2Zmc2V0ICs9IGRpZmY7XHJcbiAgICAgICAgICAgIHRoaXMubGltaXQgKz0gZGlmZjtcclxuICAgICAgICAgICAgb2Zmc2V0ICs9IGRpZmY7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdmFyIGFycmF5VmlldyA9IG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52aWV3LnNldChzb3VyY2Uudmlldy5zdWJhcnJheShzb3VyY2Uub2Zmc2V0LCBzb3VyY2UubGltaXQpLCBvZmZzZXQgLSBsZW4pO1xyXG5cclxuICAgICAgICBzb3VyY2Uub2Zmc2V0ID0gc291cmNlLmxpbWl0O1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSlcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgLT0gbGVuO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFByZXBlbmRzIHRoaXMgQnl0ZUJ1ZmZlciB0byBhbm90aGVyIEJ5dGVCdWZmZXIuIFRoaXMgd2lsbCBvdmVyd3JpdGUgYW55IGNvbnRlbnRzIGJlZm9yZSB0aGUgc3BlY2lmaWVkIG9mZnNldCB1cCB0byB0aGVcclxuICAgICAqICBwcmVwZW5kZWQgZGF0YSdzIGxlbmd0aC4gSWYgdGhlcmUgaXMgbm90IGVub3VnaCBzcGFjZSBhdmFpbGFibGUgYmVmb3JlIHRoZSBzcGVjaWZpZWQgYG9mZnNldGAsIHRoZSBiYWNraW5nIGJ1ZmZlclxyXG4gICAgICogIHdpbGwgYmUgcmVzaXplZCBhbmQgaXRzIGNvbnRlbnRzIG1vdmVkIGFjY29yZGluZ2x5LlxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcn0gdGFyZ2V0IFRhcmdldCBCeXRlQnVmZmVyXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcHJlcGVuZCBhdC4gV2lsbCB1c2UgYW5kIGRlY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHByZXBlbmRlZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjcHJlcGVuZFxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnByZXBlbmRUbyA9IGZ1bmN0aW9uKHRhcmdldCwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdGFyZ2V0LnByZXBlbmQodGhpcywgb2Zmc2V0KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFByaW50cyBkZWJ1ZyBpbmZvcm1hdGlvbiBhYm91dCB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cy5cclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oc3RyaW5nKT19IG91dCBPdXRwdXQgZnVuY3Rpb24gdG8gY2FsbCwgZGVmYXVsdHMgdG8gY29uc29sZS5sb2dcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5wcmludERlYnVnID0gZnVuY3Rpb24ob3V0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBvdXQgIT09ICdmdW5jdGlvbicpIG91dCA9IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSk7XHJcbiAgICAgICAgb3V0KFxyXG4gICAgICAgICAgICB0aGlzLnRvU3RyaW5nKCkrXCJcXG5cIitcclxuICAgICAgICAgICAgXCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXFxuXCIrXHJcbiAgICAgICAgICAgIHRoaXMudG9EZWJ1ZygvKiBjb2x1bW5zICovIHRydWUpXHJcbiAgICAgICAgKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgcmVtYWluaW5nIHJlYWRhYmxlIGJ5dGVzLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzIGJldHdlZW4ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmRcclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0sIHNvIHRoaXMgcmV0dXJucyBgbGltaXQgLSBvZmZzZXRgLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmVtYWluaW5nIHJlYWRhYmxlIGJ5dGVzLiBNYXkgYmUgbmVnYXRpdmUgaWYgYG9mZnNldCA+IGxpbWl0YC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZW1haW5pbmcgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5saW1pdCAtIHRoaXMub2Zmc2V0O1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVzZXRzIHRoaXMgQnl0ZUJ1ZmZlcidzIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uIElmIGFuIG9mZnNldCBoYXMgYmVlbiBtYXJrZWQgdGhyb3VnaCB7QGxpbmsgQnl0ZUJ1ZmZlciNtYXJrfVxyXG4gICAgICogIGJlZm9yZSwgYG9mZnNldGAgd2lsbCBiZSBzZXQgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbWFya2VkT2Zmc2V0fSwgd2hpY2ggd2lsbCB0aGVuIGJlIGRpc2NhcmRlZC4gSWYgbm8gb2Zmc2V0IGhhcyBiZWVuXHJcbiAgICAgKiAgbWFya2VkLCBzZXRzIGBvZmZzZXQgPSAwYC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI21hcmtcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIGlmICh0aGlzLm1hcmtlZE9mZnNldCA+PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gdGhpcy5tYXJrZWRPZmZzZXQ7XHJcbiAgICAgICAgICAgIHRoaXMubWFya2VkT2Zmc2V0ID0gLTE7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJlc2l6ZXMgdGhpcyBCeXRlQnVmZmVyIHRvIGJlIGJhY2tlZCBieSBhIGJ1ZmZlciBvZiBhdCBsZWFzdCB0aGUgZ2l2ZW4gY2FwYWNpdHkuIFdpbGwgZG8gbm90aGluZyBpZiBhbHJlYWR5IHRoYXRcclxuICAgICAqICBsYXJnZSBvciBsYXJnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2FwYWNpdHkgQ2FwYWNpdHkgcmVxdWlyZWRcclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgY2FwYWNpdHlgIGlzIG5vdCBhIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYGNhcGFjaXR5IDwgMGBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbihjYXBhY2l0eSkge1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGNhcGFjaXR5ICE9PSAnbnVtYmVyJyB8fCBjYXBhY2l0eSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBjYXBhY2l0eTogXCIrY2FwYWNpdHkrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIGNhcGFjaXR5IHw9IDA7XG4gICAgICAgICAgICBpZiAoY2FwYWNpdHkgPCAwKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgY2FwYWNpdHk6IDAgPD0gXCIrY2FwYWNpdHkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5idWZmZXIuYnl0ZUxlbmd0aCA8IGNhcGFjaXR5KSB7XHJcbiAgICAgICAgICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoY2FwYWNpdHkpO1xyXG4gICAgICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgICAgIHZpZXcuc2V0KHRoaXMudmlldyk7XHJcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyO1xyXG4gICAgICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldmVyc2VzIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gc3RhcnQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH1cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fVxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmV2ZXJzZSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJykgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmVnaW4gIT09ICdudW1iZXInIHx8IGJlZ2luICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJlZ2luOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGJlZ2luID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kICE9PSAnbnVtYmVyJyB8fCBlbmQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgZW5kOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGVuZCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGJlZ2luID4gZW5kIHx8IGVuZCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrYmVnaW4rXCIgPD0gXCIrZW5kK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJlZ2luID09PSBlbmQpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzOyAvLyBOb3RoaW5nIHRvIHJldmVyc2VcclxuICAgICAgICBBcnJheS5wcm90b3R5cGUucmV2ZXJzZS5jYWxsKHRoaXMudmlldy5zdWJhcnJheShiZWdpbiwgZW5kKSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTa2lwcyB0aGUgbmV4dCBgbGVuZ3RoYCBieXRlcy4gVGhpcyB3aWxsIGp1c3QgYWR2YW5jZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgYnl0ZXMgdG8gc2tpcC4gTWF5IGFsc28gYmUgbmVnYXRpdmUgdG8gbW92ZSB0aGUgb2Zmc2V0IGJhY2suXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5za2lwID0gZnVuY3Rpb24obGVuZ3RoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBsZW5ndGggJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgbGVuZ3RoOiBcIitsZW5ndGgrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIGxlbmd0aCB8PSAwO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMub2Zmc2V0ICsgbGVuZ3RoO1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgbGVuZ3RoOiAwIDw9IFwiK3RoaXMub2Zmc2V0K1wiICsgXCIrbGVuZ3RoK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTbGljZXMgdGhpcyBCeXRlQnVmZmVyIGJ5IGNyZWF0aW5nIGEgY2xvbmVkIGluc3RhbmNlIHdpdGggYG9mZnNldCA9IGJlZ2luYCBhbmQgYGxpbWl0ID0gZW5kYC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gQmVnaW4gb2Zmc2V0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgRW5kIG9mZnNldCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBDbG9uZSBvZiB0aGlzIEJ5dGVCdWZmZXIgd2l0aCBzbGljaW5nIGFwcGxpZWQsIGJhY2tlZCBieSB0aGUgc2FtZSB7QGxpbmsgQnl0ZUJ1ZmZlciNidWZmZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKSBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGJlZ2luICE9PSAnbnVtYmVyJyB8fCBiZWdpbiAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBiZWdpbjogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBiZWdpbiA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuZCAhPT0gJ251bWJlcicgfHwgZW5kICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGVuZDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBlbmQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBiZWdpbiA+IGVuZCB8fCBlbmQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK2JlZ2luK1wiIDw9IFwiK2VuZCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBiYiA9IHRoaXMuY2xvbmUoKTtcclxuICAgICAgICBiYi5vZmZzZXQgPSBiZWdpbjtcclxuICAgICAgICBiYi5saW1pdCA9IGVuZDtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgYmFja2luZyBidWZmZXIgdGhhdCBjb250YWlucyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cy4gQ29udGVudHMgYXJlIHRoZSBieXRlcyBiZXR3ZWVuXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmQge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gZm9yY2VDb3B5IElmIGB0cnVlYCByZXR1cm5zIGEgY29weSwgb3RoZXJ3aXNlIHJldHVybnMgYSB2aWV3IHJlZmVyZW5jaW5nIHRoZSBzYW1lIG1lbW9yeSBpZlxyXG4gICAgICogIHBvc3NpYmxlLiBEZWZhdWx0cyB0byBgZmFsc2VgXHJcbiAgICAgKiBAcmV0dXJucyB7IUFycmF5QnVmZmVyfSBDb250ZW50cyBhcyBhbiBBcnJheUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24oZm9yY2VDb3B5KSB7XHJcbiAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMub2Zmc2V0LFxyXG4gICAgICAgICAgICBsaW1pdCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGxpbWl0ICE9PSAnbnVtYmVyJyB8fCBsaW1pdCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBsaW1pdDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBsaW1pdCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBsaW1pdCB8fCBsaW1pdCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrb2Zmc2V0K1wiIDw9IFwiK2xpbWl0K1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgLy8gTk9URTogSXQncyBub3QgcG9zc2libGUgdG8gaGF2ZSBhbm90aGVyIEFycmF5QnVmZmVyIHJlZmVyZW5jZSB0aGUgc2FtZSBtZW1vcnkgYXMgdGhlIGJhY2tpbmcgYnVmZmVyLiBUaGlzIGlzXHJcbiAgICAgICAgLy8gcG9zc2libGUgd2l0aCBVaW50OEFycmF5I3N1YmFycmF5IG9ubHksIGJ1dCB3ZSBoYXZlIHRvIHJldHVybiBhbiBBcnJheUJ1ZmZlciBieSBjb250cmFjdC4gU286XHJcbiAgICAgICAgaWYgKCFmb3JjZUNvcHkgJiYgb2Zmc2V0ID09PSAwICYmIGxpbWl0ID09PSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5idWZmZXI7XHJcbiAgICAgICAgaWYgKG9mZnNldCA9PT0gbGltaXQpXHJcbiAgICAgICAgICAgIHJldHVybiBFTVBUWV9CVUZGRVI7XHJcbiAgICAgICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihsaW1pdCAtIG9mZnNldCk7XHJcbiAgICAgICAgbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKS5zZXQobmV3IFVpbnQ4QXJyYXkodGhpcy5idWZmZXIpLnN1YmFycmF5KG9mZnNldCwgbGltaXQpLCAwKTtcclxuICAgICAgICByZXR1cm4gYnVmZmVyO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSByYXcgYnVmZmVyIGNvbXBhY3RlZCB0byBjb250YWluIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzIGJldHdlZW5cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjdG9CdWZmZXJ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBmb3JjZUNvcHkgSWYgYHRydWVgIHJldHVybnMgYSBjb3B5LCBvdGhlcndpc2UgcmV0dXJucyBhIHZpZXcgcmVmZXJlbmNpbmcgdGhlIHNhbWUgbWVtb3J5LlxyXG4gICAgICogIERlZmF1bHRzIHRvIGBmYWxzZWBcclxuICAgICAqIEByZXR1cm5zIHshQXJyYXlCdWZmZXJ9IENvbnRlbnRzIGFzIGFuIEFycmF5QnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9BcnJheUJ1ZmZlciA9IEJ5dGVCdWZmZXJQcm90b3R5cGUudG9CdWZmZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyB0aGUgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzIHRvIGEgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmc9fSBlbmNvZGluZyBPdXRwdXQgZW5jb2RpbmcuIFJldHVybnMgYW4gaW5mb3JtYXRpdmUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlmIG9taXR0ZWQgYnV0IGFsc28gYWxsb3dzXHJcbiAgICAgKiAgZGlyZWN0IGNvbnZlcnNpb24gdG8gXCJ1dGY4XCIsIFwiaGV4XCIsIFwiYmFzZTY0XCIgYW5kIFwiYmluYXJ5XCIgZW5jb2RpbmcuIFwiZGVidWdcIiByZXR1cm5zIGEgaGV4IHJlcHJlc2VudGF0aW9uIHdpdGhcclxuICAgICAqICBoaWdobGlnaHRlZCBvZmZzZXRzLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gYmVnaW4gYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH1cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fVxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gU3RyaW5nIHJlcHJlc2VudGF0aW9uXHJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgYGVuY29kaW5nYCBpcyBpbnZhbGlkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihlbmNvZGluZywgYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICByZXR1cm4gXCJCeXRlQnVmZmVyQUIob2Zmc2V0PVwiK3RoaXMub2Zmc2V0K1wiLG1hcmtlZE9mZnNldD1cIit0aGlzLm1hcmtlZE9mZnNldCtcIixsaW1pdD1cIit0aGlzLmxpbWl0K1wiLGNhcGFjaXR5PVwiK3RoaXMuY2FwYWNpdHkoKStcIilcIjtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnbnVtYmVyJylcclxuICAgICAgICAgICAgZW5jb2RpbmcgPSBcInV0ZjhcIixcclxuICAgICAgICAgICAgYmVnaW4gPSBlbmNvZGluZyxcclxuICAgICAgICAgICAgZW5kID0gYmVnaW47XHJcbiAgICAgICAgc3dpdGNoIChlbmNvZGluZykge1xyXG4gICAgICAgICAgICBjYXNlIFwidXRmOFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9VVEY4KGJlZ2luLCBlbmQpO1xyXG4gICAgICAgICAgICBjYXNlIFwiYmFzZTY0XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0Jhc2U2NChiZWdpbiwgZW5kKTtcclxuICAgICAgICAgICAgY2FzZSBcImhleFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9IZXgoYmVnaW4sIGVuZCk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJiaW5hcnlcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQmluYXJ5KGJlZ2luLCBlbmQpO1xyXG4gICAgICAgICAgICBjYXNlIFwiZGVidWdcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvRGVidWcoKTtcclxuICAgICAgICAgICAgY2FzZSBcImNvbHVtbnNcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQ29sdW1ucygpO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJVbnN1cHBvcnRlZCBlbmNvZGluZzogXCIrZW5jb2RpbmcpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLy8gbHhpdi1lbWJlZGRhYmxlXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBseGl2LWVtYmVkZGFibGUgKGMpIDIwMTQgRGFuaWVsIFdpcnR6IDxkY29kZUBkY29kZS5pbz5cclxuICAgICAqIFJlbGVhc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjBcclxuICAgICAqIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vbHhpdiBmb3IgZGV0YWlsc1xyXG4gICAgICovXHJcbiAgICB2YXIgbHhpdiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIFwidXNlIHN0cmljdFwiO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBseGl2IG5hbWVzcGFjZS5cclxuICAgICAgICAgKiBAdHlwZSB7IU9iamVjdC48c3RyaW5nLCo+fVxyXG4gICAgICAgICAqIEBleHBvcnRzIGx4aXZcclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgbHhpdiA9IHt9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDaGFyYWN0ZXIgY29kZXMgZm9yIG91dHB1dC5cclxuICAgICAgICAgKiBAdHlwZSB7IUFycmF5LjxudW1iZXI+fVxyXG4gICAgICAgICAqIEBpbm5lclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHZhciBhb3V0ID0gW1xyXG4gICAgICAgICAgICA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LCA4MCxcclxuICAgICAgICAgICAgODEsIDgyLCA4MywgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsXHJcbiAgICAgICAgICAgIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSwgMTEwLCAxMTEsIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCxcclxuICAgICAgICAgICAgMTE5LCAxMjAsIDEyMSwgMTIyLCA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNDMsIDQ3XHJcbiAgICAgICAgXTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2hhcmFjdGVyIGNvZGVzIGZvciBpbnB1dC5cclxuICAgICAgICAgKiBAdHlwZSB7IUFycmF5LjxudW1iZXI+fVxyXG4gICAgICAgICAqIEBpbm5lclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHZhciBhaW4gPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBpPTAsIGs9YW91dC5sZW5ndGg7IGk8azsgKytpKVxyXG4gICAgICAgICAgICBhaW5bYW91dFtpXV0gPSBpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBFbmNvZGVzIGJ5dGVzIHRvIGJhc2U2NCBjaGFyIGNvZGVzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCk6bnVtYmVyfG51bGx9IHNyYyBCeXRlcyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgYnl0ZSByZXNwZWN0aXZlbHkgYG51bGxgIGlmXHJcbiAgICAgICAgICogIHRoZXJlIGFyZSBubyBtb3JlIGJ5dGVzIGxlZnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IENoYXJhY3RlcnMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggZWFjaCBlbmNvZGVkIGNoYXJcclxuICAgICAgICAgKiAgY29kZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBseGl2LmVuY29kZSA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHZhciBiLCB0O1xyXG4gICAgICAgICAgICB3aGlsZSAoKGIgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIGRzdChhb3V0WyhiPj4yKSYweDNmXSk7XHJcbiAgICAgICAgICAgICAgICB0ID0gKGImMHgzKTw8NDtcclxuICAgICAgICAgICAgICAgIGlmICgoYiA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHQgfD0gKGI+PjQpJjB4ZjtcclxuICAgICAgICAgICAgICAgICAgICBkc3QoYW91dFsodHwoKGI+PjQpJjB4ZikpJjB4M2ZdKTtcclxuICAgICAgICAgICAgICAgICAgICB0ID0gKGImMHhmKTw8MjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKGIgPSBzcmMoKSkgIT09IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRzdChhb3V0Wyh0fCgoYj4+NikmMHgzKSkmMHgzZl0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkc3QoYW91dFtiJjB4M2ZdKTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRzdChhb3V0W3QmMHgzZl0pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkc3QoNjEpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KGFvdXRbdCYweDNmXSksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KDYxKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoNjEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVjb2RlcyBiYXNlNjQgY2hhciBjb2RlcyB0byBieXRlcy5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbigpOm51bWJlcnxudWxsfSBzcmMgQ2hhcmFjdGVycyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY2hhciBjb2RlIHJlc3BlY3RpdmVseVxyXG4gICAgICAgICAqICBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBCeXRlcyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCB0aGUgbmV4dCBieXRlLlxyXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBhIGNoYXJhY3RlciBjb2RlIGlzIGludmFsaWRcclxuICAgICAgICAgKi9cclxuICAgICAgICBseGl2LmRlY29kZSA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHZhciBjLCB0MSwgdDI7XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGZhaWwoYykge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJJbGxlZ2FsIGNoYXJhY3RlciBjb2RlOiBcIitjKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB3aGlsZSAoKGMgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHQxID0gYWluW2NdO1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0MSA9PT0gJ3VuZGVmaW5lZCcpIGZhaWwoYyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoKGMgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICB0MiA9IGFpbltjXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHQyID09PSAndW5kZWZpbmVkJykgZmFpbChjKTtcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKHQxPDwyKT4+PjB8KHQyJjB4MzApPj40KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKGMgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdDEgPSBhaW5bY107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdDEgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT09IDYxKSBicmVhazsgZWxzZSBmYWlsKGMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkc3QoKCh0MiYweGYpPDw0KT4+PjB8KHQxJjB4M2MpPj4yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChjID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0MiA9IGFpbltjXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdDIgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjID09PSA2MSkgYnJlYWs7IGVsc2UgZmFpbChjKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdCgoKHQxJjB4Myk8PDYpPj4+MHx0Mik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUZXN0cyBpZiBhIHN0cmluZyBpcyB2YWxpZCBiYXNlNjQuXHJcbiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gdGVzdFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdmFsaWQsIG90aGVyd2lzZSBgZmFsc2VgXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbHhpdi50ZXN0ID0gZnVuY3Rpb24oc3RyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAvXig/OltBLVphLXowLTkrL117NH0pKig/OltBLVphLXowLTkrL117Mn09PXxbQS1aYS16MC05Ky9dezN9PSk/JC8udGVzdChzdHIpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiBseGl2O1xyXG4gICAgfSgpO1xyXG5cclxuICAgIC8vIGVuY29kaW5ncy9iYXNlNjRcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuY29kZXMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMgdG8gYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIE9mZnNldCB0byBiZWdpbiBhdCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEJhc2U2NCBlbmNvZGVkIHN0cmluZ1xyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYGJlZ2luYCBvciBgZW5kYCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9CYXNlNjQgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGJlZ2luID0gYmVnaW4gfCAwOyBlbmQgPSBlbmQgfCAwO1xyXG4gICAgICAgIGlmIChiZWdpbiA8IDAgfHwgZW5kID4gdGhpcy5jYXBhY2l0eSB8fCBiZWdpbiA+IGVuZClcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcImJlZ2luLCBlbmRcIik7XHJcbiAgICAgICAgdmFyIHNkOyBseGl2LmVuY29kZShmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGJlZ2luIDwgZW5kID8gdGhpcy52aWV3W2JlZ2luKytdIDogbnVsbDtcclxuICAgICAgICB9LmJpbmQodGhpcyksIHNkID0gc3RyaW5nRGVzdGluYXRpb24oKSk7XHJcbiAgICAgICAgcmV0dXJuIHNkKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZyB0byBhIEJ5dGVCdWZmZXIuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBkZWNvZGVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmZyb21CYXNlNjQgPSBmdW5jdGlvbihzdHIsIGxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwic3RyXCIpO1xyXG4gICAgICAgIHZhciBiYiA9IG5ldyBCeXRlQnVmZmVyKHN0ci5sZW5ndGgvNCozLCBsaXR0bGVFbmRpYW4pLFxyXG4gICAgICAgICAgICBpID0gMDtcclxuICAgICAgICBseGl2LmRlY29kZShzdHJpbmdTb3VyY2Uoc3RyKSwgZnVuY3Rpb24oYikge1xyXG4gICAgICAgICAgICBiYi52aWV3W2krK10gPSBiO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGJiLmxpbWl0ID0gaTtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyBhIGJpbmFyeSBzdHJpbmcgdG8gYmFzZTY0IGxpa2UgYHdpbmRvdy5idG9hYCBkb2VzLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBCaW5hcnkgc3RyaW5nXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBCYXNlNjQgZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dpbmRvdy5idG9hXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuYnRvYSA9IGZ1bmN0aW9uKHN0cikge1xyXG4gICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21CaW5hcnkoc3RyKS50b0Jhc2U2NCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY29kZXMgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gYmluYXJ5IGxpa2UgYHdpbmRvdy5hdG9iYCBkb2VzLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGI2NCBCYXNlNjQgZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEJpbmFyeSBzdHJpbmdcclxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dpbmRvdy5hdG9iXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuYXRvYiA9IGZ1bmN0aW9uKGI2NCkge1xyXG4gICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21CYXNlNjQoYjY0KS50b0JpbmFyeSgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBlbmNvZGluZ3MvYmluYXJ5XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmNvZGVzIHRoaXMgQnl0ZUJ1ZmZlciB0byBhIGJpbmFyeSBlbmNvZGVkIHN0cmluZywgdGhhdCBpcyB1c2luZyBvbmx5IGNoYXJhY3RlcnMgMHgwMC0weEZGIGFzIGJ5dGVzLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gYmVnaW4gYXQuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBPZmZzZXQgdG8gZW5kIGF0LiBEZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBCaW5hcnkgZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXQgPiBsaW1pdGBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0JpbmFyeSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgYmVnaW4gfD0gMDsgZW5kIHw9IDA7XHJcbiAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBlbmQgPiB0aGlzLmNhcGFjaXR5KCkgfHwgYmVnaW4gPiBlbmQpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJiZWdpbiwgZW5kXCIpO1xyXG4gICAgICAgIGlmIChiZWdpbiA9PT0gZW5kKVxyXG4gICAgICAgICAgICByZXR1cm4gXCJcIjtcclxuICAgICAgICB2YXIgY2hhcnMgPSBbXSxcclxuICAgICAgICAgICAgcGFydHMgPSBbXTtcclxuICAgICAgICB3aGlsZSAoYmVnaW4gPCBlbmQpIHtcclxuICAgICAgICAgICAgY2hhcnMucHVzaCh0aGlzLnZpZXdbYmVnaW4rK10pO1xyXG4gICAgICAgICAgICBpZiAoY2hhcnMubGVuZ3RoID49IDEwMjQpXHJcbiAgICAgICAgICAgICAgICBwYXJ0cy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaGFycykpLFxyXG4gICAgICAgICAgICAgICAgY2hhcnMgPSBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHBhcnRzLmpvaW4oJycpICsgU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNoYXJzKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGEgYmluYXJ5IGVuY29kZWQgc3RyaW5nLCB0aGF0IGlzIHVzaW5nIG9ubHkgY2hhcmFjdGVycyAweDAwLTB4RkYgYXMgYnl0ZXMsIHRvIGEgQnl0ZUJ1ZmZlci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGRlY29kZVxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBCeXRlQnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuZnJvbUJpbmFyeSA9IGZ1bmN0aW9uKHN0ciwgbGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxyXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJzdHJcIik7XHJcbiAgICAgICAgdmFyIGkgPSAwLFxyXG4gICAgICAgICAgICBrID0gc3RyLmxlbmd0aCxcclxuICAgICAgICAgICAgY2hhckNvZGUsXHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoaywgbGl0dGxlRW5kaWFuKTtcclxuICAgICAgICB3aGlsZSAoaTxrKSB7XHJcbiAgICAgICAgICAgIGNoYXJDb2RlID0gc3RyLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgICAgIGlmIChjaGFyQ29kZSA+IDB4ZmYpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiaWxsZWdhbCBjaGFyIGNvZGU6IFwiK2NoYXJDb2RlKTtcclxuICAgICAgICAgICAgYmIudmlld1tpKytdID0gY2hhckNvZGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJiLmxpbWl0ID0gaztcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIGVuY29kaW5ncy9kZWJ1Z1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyB0aGlzIEJ5dGVCdWZmZXIgdG8gYSBoZXggZW5jb2RlZCBzdHJpbmcgd2l0aCBtYXJrZWQgb2Zmc2V0cy4gT2Zmc2V0IHN5bWJvbHMgYXJlOlxyXG4gICAgICogKiBgPGAgOiBvZmZzZXQsXHJcbiAgICAgKiAqIGAnYCA6IG1hcmtlZE9mZnNldCxcclxuICAgICAqICogYD5gIDogbGltaXQsXHJcbiAgICAgKiAqIGB8YCA6IG9mZnNldCBhbmQgbGltaXQsXHJcbiAgICAgKiAqIGBbYCA6IG9mZnNldCBhbmQgbWFya2VkT2Zmc2V0LFxyXG4gICAgICogKiBgXWAgOiBtYXJrZWRPZmZzZXQgYW5kIGxpbWl0LFxyXG4gICAgICogKiBgIWAgOiBvZmZzZXQsIG1hcmtlZE9mZnNldCBhbmQgbGltaXRcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGNvbHVtbnMgSWYgYHRydWVgIHJldHVybnMgdHdvIGNvbHVtbnMgaGV4ICsgYXNjaWksIGRlZmF1bHRzIHRvIGBmYWxzZWBcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8IUFycmF5LjxzdHJpbmc+fSBEZWJ1ZyBzdHJpbmcgb3IgYXJyYXkgb2YgbGluZXMgaWYgYGFzQXJyYXkgPSB0cnVlYFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQGV4YW1wbGUgYD4wMCcwMSAwMjwwM2AgY29udGFpbnMgZm91ciBieXRlcyB3aXRoIGBsaW1pdD0wLCBtYXJrZWRPZmZzZXQ9MSwgb2Zmc2V0PTNgXHJcbiAgICAgKiBAZXhhbXBsZSBgMDBbMDEgMDIgMDM+YCBjb250YWlucyBmb3VyIGJ5dGVzIHdpdGggYG9mZnNldD1tYXJrZWRPZmZzZXQ9MSwgbGltaXQ9NGBcclxuICAgICAqIEBleGFtcGxlIGAwMHwwMSAwMiAwM2AgY29udGFpbnMgZm91ciBieXRlcyB3aXRoIGBvZmZzZXQ9bGltaXQ9MSwgbWFya2VkT2Zmc2V0PS0xYFxyXG4gICAgICogQGV4YW1wbGUgYHxgIGNvbnRhaW5zIHplcm8gYnl0ZXMgd2l0aCBgb2Zmc2V0PWxpbWl0PTAsIG1hcmtlZE9mZnNldD0tMWBcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0RlYnVnID0gZnVuY3Rpb24oY29sdW1ucykge1xyXG4gICAgICAgIHZhciBpID0gLTEsXHJcbiAgICAgICAgICAgIGsgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoLFxyXG4gICAgICAgICAgICBiLFxyXG4gICAgICAgICAgICBoZXggPSBcIlwiLFxyXG4gICAgICAgICAgICBhc2MgPSBcIlwiLFxyXG4gICAgICAgICAgICBvdXQgPSBcIlwiO1xyXG4gICAgICAgIHdoaWxlIChpPGspIHtcclxuICAgICAgICAgICAgaWYgKGkgIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICBiID0gdGhpcy52aWV3W2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKGIgPCAweDEwKSBoZXggKz0gXCIwXCIrYi50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaGV4ICs9IGIudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sdW1ucylcclxuICAgICAgICAgICAgICAgICAgICBhc2MgKz0gYiA+IDMyICYmIGIgPCAxMjcgPyBTdHJpbmcuZnJvbUNoYXJDb2RlKGIpIDogJy4nO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICsraTtcclxuICAgICAgICAgICAgaWYgKGNvbHVtbnMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpID4gMCAmJiBpICUgMTYgPT09IDAgJiYgaSAhPT0gaykge1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChoZXgubGVuZ3RoIDwgMyoxNiszKSBoZXggKz0gXCIgXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgb3V0ICs9IGhleCthc2MrXCJcXG5cIjtcclxuICAgICAgICAgICAgICAgICAgICBoZXggPSBhc2MgPSBcIlwiO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChpID09PSB0aGlzLm9mZnNldCAmJiBpID09PSB0aGlzLmxpbWl0KVxyXG4gICAgICAgICAgICAgICAgaGV4ICs9IGkgPT09IHRoaXMubWFya2VkT2Zmc2V0ID8gXCIhXCIgOiBcInxcIjtcclxuICAgICAgICAgICAgZWxzZSBpZiAoaSA9PT0gdGhpcy5vZmZzZXQpXHJcbiAgICAgICAgICAgICAgICBoZXggKz0gaSA9PT0gdGhpcy5tYXJrZWRPZmZzZXQgPyBcIltcIiA6IFwiPFwiO1xyXG4gICAgICAgICAgICBlbHNlIGlmIChpID09PSB0aGlzLmxpbWl0KVxyXG4gICAgICAgICAgICAgICAgaGV4ICs9IGkgPT09IHRoaXMubWFya2VkT2Zmc2V0ID8gXCJdXCIgOiBcIj5cIjtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgaGV4ICs9IGkgPT09IHRoaXMubWFya2VkT2Zmc2V0ID8gXCInXCIgOiAoY29sdW1ucyB8fCAoaSAhPT0gMCAmJiBpICE9PSBrKSA/IFwiIFwiIDogXCJcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjb2x1bW5zICYmIGhleCAhPT0gXCIgXCIpIHtcclxuICAgICAgICAgICAgd2hpbGUgKGhleC5sZW5ndGggPCAzKjE2KzMpXHJcbiAgICAgICAgICAgICAgICBoZXggKz0gXCIgXCI7XHJcbiAgICAgICAgICAgIG91dCArPSBoZXggKyBhc2MgKyBcIlxcblwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY29sdW1ucyA/IG91dCA6IGhleDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGEgaGV4IGVuY29kZWQgc3RyaW5nIHdpdGggbWFya2VkIG9mZnNldHMgdG8gYSBCeXRlQnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBEZWJ1ZyBzdHJpbmcgdG8gZGVjb2RlIChub3QgYmUgZ2VuZXJhdGVkIHdpdGggYGNvbHVtbnMgPSB0cnVlYClcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcy4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3RvRGVidWdcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5mcm9tRGVidWcgPSBmdW5jdGlvbihzdHIsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICB2YXIgayA9IHN0ci5sZW5ndGgsXHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoKChrKzEpLzMpfDAsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpO1xyXG4gICAgICAgIHZhciBpID0gMCwgaiA9IDAsIGNoLCBiLFxyXG4gICAgICAgICAgICBycyA9IGZhbHNlLCAvLyBSZXF1aXJlIHN5bWJvbCBuZXh0XHJcbiAgICAgICAgICAgIGhvID0gZmFsc2UsIGhtID0gZmFsc2UsIGhsID0gZmFsc2UsIC8vIEFscmVhZHkgaGFzIG9mZnNldCAoaG8pLCBtYXJrZWRPZmZzZXQgKGhtKSwgbGltaXQgKGhsKT9cclxuICAgICAgICAgICAgZmFpbCA9IGZhbHNlO1xyXG4gICAgICAgIHdoaWxlIChpPGspIHtcclxuICAgICAgICAgICAgc3dpdGNoIChjaCA9IHN0ci5jaGFyQXQoaSsrKSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnISc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG8gfHwgaG0gfHwgaGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaG8gPSBobSA9IGhsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gYmIubWFya2VkT2Zmc2V0ID0gYmIubGltaXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICd8JzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobyB8fCBobCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobyA9IGhsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gYmIubGltaXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdbJzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobyB8fCBobSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobyA9IGhtID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gYmIubWFya2VkT2Zmc2V0ID0gajtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnPCc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaG8gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi5vZmZzZXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICddJzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobCB8fCBobSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobCA9IGhtID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIubGltaXQgPSBiYi5tYXJrZWRPZmZzZXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICc+JzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLmxpbWl0ID0gajtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBcIidcIjpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLm1hcmtlZE9mZnNldCA9IGo7XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJyAnOlxyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGIgPSBwYXJzZUludChjaCtzdHIuY2hhckF0KGkrKyksIDE2KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihiKSB8fCBiIDwgMCB8fCBiID4gMjU1KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE5vdCBhIGRlYnVnIGVuY29kZWQgc3RyaW5nXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi52aWV3W2orK10gPSBiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZmFpbClcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBJbnZhbGlkIHN5bWJvbCBhdCBcIitpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAoIWhvIHx8ICFobClcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBNaXNzaW5nIG9mZnNldCBvciBsaW1pdFwiKTtcclxuICAgICAgICAgICAgaWYgKGo8YmIuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgZGVidWcgZW5jb2RlZCBzdHJpbmcgKGlzIGl0IGhleD8pIFwiK2orXCIgPCBcIitrKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBlbmNvZGluZ3MvaGV4XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmNvZGVzIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzIHRvIGEgaGV4IGVuY29kZWQgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gYmVnaW4gYXQuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBPZmZzZXQgdG8gZW5kIGF0LiBEZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBIZXggZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBiZWdpbiA9IHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLm9mZnNldCA6IGJlZ2luO1xyXG4gICAgICAgIGVuZCA9IHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnID8gdGhpcy5saW1pdCA6IGVuZDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgb3V0ID0gbmV3IEFycmF5KGVuZCAtIGJlZ2luKSxcclxuICAgICAgICAgICAgYjtcclxuICAgICAgICB3aGlsZSAoYmVnaW4gPCBlbmQpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tiZWdpbisrXTtcclxuICAgICAgICAgICAgaWYgKGIgPCAweDEwKVxyXG4gICAgICAgICAgICAgICAgb3V0LnB1c2goXCIwXCIsIGIudG9TdHJpbmcoMTYpKTtcclxuICAgICAgICAgICAgZWxzZSBvdXQucHVzaChiLnRvU3RyaW5nKDE2KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvdXQuam9pbignJyk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyBhIGhleCBlbmNvZGVkIHN0cmluZyB0byBhIEJ5dGVCdWZmZXIuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBkZWNvZGVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcy4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmZyb21IZXggPSBmdW5jdGlvbihzdHIsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBOb3QgYSBzdHJpbmdcIik7XHJcbiAgICAgICAgICAgIGlmIChzdHIubGVuZ3RoICUgMiAhPT0gMClcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBMZW5ndGggbm90IGEgbXVsdGlwbGUgb2YgMlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGsgPSBzdHIubGVuZ3RoLFxyXG4gICAgICAgICAgICBiYiA9IG5ldyBCeXRlQnVmZmVyKChrIC8gMikgfCAwLCBsaXR0bGVFbmRpYW4pLFxyXG4gICAgICAgICAgICBiO1xyXG4gICAgICAgIGZvciAodmFyIGk9MCwgaj0wOyBpPGs7IGkrPTIpIHtcclxuICAgICAgICAgICAgYiA9IHBhcnNlSW50KHN0ci5zdWJzdHJpbmcoaSwgaSsyKSwgMTYpO1xyXG4gICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KVxyXG4gICAgICAgICAgICAgICAgaWYgKCFpc0Zpbml0ZShiKSB8fCBiIDwgMCB8fCBiID4gMjU1KVxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBDb250YWlucyBub24taGV4IGNoYXJhY3RlcnNcIik7XHJcbiAgICAgICAgICAgIGJiLnZpZXdbaisrXSA9IGI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJiLmxpbWl0ID0gajtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIHV0ZngtZW1iZWRkYWJsZVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogdXRmeC1lbWJlZGRhYmxlIChjKSAyMDE0IERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcbiAgICAgKiBSZWxlYXNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wXHJcbiAgICAgKiBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL3V0ZnggZm9yIGRldGFpbHNcclxuICAgICAqL1xyXG4gICAgdmFyIHV0ZnggPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogdXRmeCBuYW1lc3BhY2UuXHJcbiAgICAgICAgICogQGlubmVyXHJcbiAgICAgICAgICogQHR5cGUgeyFPYmplY3QuPHN0cmluZywqPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgdXRmeCA9IHt9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBNYXhpbXVtIHZhbGlkIGNvZGUgcG9pbnQuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKiBAY29uc3RcclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4Lk1BWF9DT0RFUE9JTlQgPSAweDEwRkZGRjtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRW5jb2RlcyBVVEY4IGNvZGUgcG9pbnRzIHRvIFVURjggYnl0ZXMuXHJcbiAgICAgICAgICogQHBhcmFtIHsoIWZ1bmN0aW9uKCk6bnVtYmVyfG51bGwpIHwgbnVtYmVyfSBzcmMgQ29kZSBwb2ludHMgc291cmNlLCBlaXRoZXIgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY29kZSBwb2ludFxyXG4gICAgICAgICAqICByZXNwZWN0aXZlbHkgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBtb3JlIGNvZGUgcG9pbnRzIGxlZnQgb3IgYSBzaW5nbGUgbnVtZXJpYyBjb2RlIHBvaW50LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBCeXRlcyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCB0aGUgbmV4dCBieXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5lbmNvZGVVVEY4ID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdmFyIGNwID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzcmMgPT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICAgICAgY3AgPSBzcmMsXHJcbiAgICAgICAgICAgICAgICBzcmMgPSBmdW5jdGlvbigpIHsgcmV0dXJuIG51bGw7IH07XHJcbiAgICAgICAgICAgIHdoaWxlIChjcCAhPT0gbnVsbCB8fCAoY3AgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIGlmIChjcCA8IDB4ODApXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KGNwJjB4N0YpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY3AgPCAweDgwMClcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChjcD4+NikmMHgxRil8MHhDMCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KChjcCYweDNGKXwweDgwKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNwIDwgMHgxMDAwMClcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChjcD4+MTIpJjB4MEYpfDB4RTApLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGNwPj42KSYweDNGKXwweDgwKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKGNwJjB4M0YpfDB4ODApO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGNwPj4xOCkmMHgwNyl8MHhGMCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoY3A+PjEyKSYweDNGKXwweDgwKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChjcD4+NikmMHgzRil8MHg4MCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KChjcCYweDNGKXwweDgwKTtcclxuICAgICAgICAgICAgICAgIGNwID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlY29kZXMgVVRGOCBieXRlcyB0byBVVEY4IGNvZGUgcG9pbnRzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCk6bnVtYmVyfG51bGx9IHNyYyBCeXRlcyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgYnl0ZSByZXNwZWN0aXZlbHkgYG51bGxgIGlmIHRoZXJlXHJcbiAgICAgICAgICogIGFyZSBubyBtb3JlIGJ5dGVzIGxlZnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IENvZGUgcG9pbnRzIGRlc3RpbmF0aW9uIGFzIGEgZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIGVhY2ggZGVjb2RlZCBjb2RlIHBvaW50LlxyXG4gICAgICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGEgc3RhcnRpbmcgYnl0ZSBpcyBpbnZhbGlkIGluIFVURjhcclxuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGxhc3Qgc2VxdWVuY2UgaXMgdHJ1bmNhdGVkLiBIYXMgYW4gYXJyYXkgcHJvcGVydHkgYGJ5dGVzYCBob2xkaW5nIHRoZVxyXG4gICAgICAgICAqICByZW1haW5pbmcgYnl0ZXMuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5kZWNvZGVVVEY4ID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdmFyIGEsIGIsIGMsIGQsIGZhaWwgPSBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgICAgICBiID0gYi5zbGljZSgwLCBiLmluZGV4T2YobnVsbCkpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGVyciA9IEVycm9yKGIudG9TdHJpbmcoKSk7XHJcbiAgICAgICAgICAgICAgICBlcnIubmFtZSA9IFwiVHJ1bmNhdGVkRXJyb3JcIjtcclxuICAgICAgICAgICAgICAgIGVyclsnYnl0ZXMnXSA9IGI7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHdoaWxlICgoYSA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKChhJjB4ODApID09PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgIGRzdChhKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKChhJjB4RTApID09PSAweEMwKVxyXG4gICAgICAgICAgICAgICAgICAgICgoYiA9IHNyYygpKSA9PT0gbnVsbCkgJiYgZmFpbChbYSwgYl0pLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGEmMHgxRik8PDYpIHwgKGImMHgzRikpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKGEmMHhGMCkgPT09IDB4RTApXHJcbiAgICAgICAgICAgICAgICAgICAgKChiPXNyYygpKSA9PT0gbnVsbCB8fCAoYz1zcmMoKSkgPT09IG51bGwpICYmIGZhaWwoW2EsIGIsIGNdKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChhJjB4MEYpPDwxMikgfCAoKGImMHgzRik8PDYpIHwgKGMmMHgzRikpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKGEmMHhGOCkgPT09IDB4RjApXHJcbiAgICAgICAgICAgICAgICAgICAgKChiPXNyYygpKSA9PT0gbnVsbCB8fCAoYz1zcmMoKSkgPT09IG51bGwgfHwgKGQ9c3JjKCkpID09PSBudWxsKSAmJiBmYWlsKFthLCBiLCBjICxkXSksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoYSYweDA3KTw8MTgpIHwgKChiJjB4M0YpPDwxMikgfCAoKGMmMHgzRik8PDYpIHwgKGQmMHgzRikpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBzdGFydGluZyBieXRlOiBcIithKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENvbnZlcnRzIFVURjE2IGNoYXJhY3RlcnMgdG8gVVRGOCBjb2RlIHBvaW50cy5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbigpOm51bWJlcnxudWxsfSBzcmMgQ2hhcmFjdGVycyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY2hhciBjb2RlIHJlc3BlY3RpdmVseVxyXG4gICAgICAgICAqICBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBDb2RlIHBvaW50cyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCBlYWNoIGNvbnZlcnRlZCBjb2RlXHJcbiAgICAgICAgICogIHBvaW50LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguVVRGMTZ0b1VURjggPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB2YXIgYzEsIGMyID0gbnVsbDtcclxuICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcclxuICAgICAgICAgICAgICAgIGlmICgoYzEgPSBjMiAhPT0gbnVsbCA/IGMyIDogc3JjKCkpID09PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgaWYgKGMxID49IDB4RDgwMCAmJiBjMSA8PSAweERGRkYpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKGMyID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjMiA+PSAweERDMDAgJiYgYzIgPD0gMHhERkZGKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3QoKGMxLTB4RDgwMCkqMHg0MDArYzItMHhEQzAwKzB4MTAwMDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYzIgPSBudWxsOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGRzdChjMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGMyICE9PSBudWxsKSBkc3QoYzIpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENvbnZlcnRzIFVURjggY29kZSBwb2ludHMgdG8gVVRGMTYgY2hhcmFjdGVycy5cclxuICAgICAgICAgKiBAcGFyYW0geyghZnVuY3Rpb24oKTpudW1iZXJ8bnVsbCkgfCBudW1iZXJ9IHNyYyBDb2RlIHBvaW50cyBzb3VyY2UsIGVpdGhlciBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjb2RlIHBvaW50XHJcbiAgICAgICAgICogIHJlc3BlY3RpdmVseSBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY29kZSBwb2ludHMgbGVmdCBvciBhIHNpbmdsZSBudW1lcmljIGNvZGUgcG9pbnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IENoYXJhY3RlcnMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggZWFjaCBjb252ZXJ0ZWQgY2hhciBjb2RlLlxyXG4gICAgICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGEgY29kZSBwb2ludCBpcyBvdXQgb2YgcmFuZ2VcclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LlVURjh0b1VURjE2ID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdmFyIGNwID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzcmMgPT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICAgICAgY3AgPSBzcmMsIHNyYyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gbnVsbDsgfTtcclxuICAgICAgICAgICAgd2hpbGUgKGNwICE9PSBudWxsIHx8IChjcCA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNwIDw9IDB4RkZGRilcclxuICAgICAgICAgICAgICAgICAgICBkc3QoY3ApO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGNwIC09IDB4MTAwMDAsXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KChjcD4+MTApKzB4RDgwMCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KChjcCUweDQwMCkrMHhEQzAwKTtcclxuICAgICAgICAgICAgICAgIGNwID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENvbnZlcnRzIGFuZCBlbmNvZGVzIFVURjE2IGNoYXJhY3RlcnMgdG8gVVRGOCBieXRlcy5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbigpOm51bWJlcnxudWxsfSBzcmMgQ2hhcmFjdGVycyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY2hhciBjb2RlIHJlc3BlY3RpdmVseSBgbnVsbGBcclxuICAgICAgICAgKiAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBCeXRlcyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCB0aGUgbmV4dCBieXRlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguZW5jb2RlVVRGMTZ0b1VURjggPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB1dGZ4LlVURjE2dG9VVEY4KHNyYywgZnVuY3Rpb24oY3ApIHtcclxuICAgICAgICAgICAgICAgIHV0ZnguZW5jb2RlVVRGOChjcCwgZHN0KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVjb2RlcyBhbmQgY29udmVydHMgVVRGOCBieXRlcyB0byBVVEYxNiBjaGFyYWN0ZXJzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCk6bnVtYmVyfG51bGx9IHNyYyBCeXRlcyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgYnl0ZSByZXNwZWN0aXZlbHkgYG51bGxgIGlmIHRoZXJlXHJcbiAgICAgICAgICogIGFyZSBubyBtb3JlIGJ5dGVzIGxlZnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IENoYXJhY3RlcnMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggZWFjaCBjb252ZXJ0ZWQgY2hhciBjb2RlLlxyXG4gICAgICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGEgc3RhcnRpbmcgYnl0ZSBpcyBpbnZhbGlkIGluIFVURjhcclxuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGxhc3Qgc2VxdWVuY2UgaXMgdHJ1bmNhdGVkLiBIYXMgYW4gYXJyYXkgcHJvcGVydHkgYGJ5dGVzYCBob2xkaW5nIHRoZSByZW1haW5pbmcgYnl0ZXMuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5kZWNvZGVVVEY4dG9VVEYxNiA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHV0ZnguZGVjb2RlVVRGOChzcmMsIGZ1bmN0aW9uKGNwKSB7XHJcbiAgICAgICAgICAgICAgICB1dGZ4LlVURjh0b1VURjE2KGNwLCBkc3QpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDYWxjdWxhdGVzIHRoZSBieXRlIGxlbmd0aCBvZiBhbiBVVEY4IGNvZGUgcG9pbnQuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGNwIFVURjggY29kZSBwb2ludFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IEJ5dGUgbGVuZ3RoXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5jYWxjdWxhdGVDb2RlUG9pbnQgPSBmdW5jdGlvbihjcCkge1xyXG4gICAgICAgICAgICByZXR1cm4gKGNwIDwgMHg4MCkgPyAxIDogKGNwIDwgMHg4MDApID8gMiA6IChjcCA8IDB4MTAwMDApID8gMyA6IDQ7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIFVURjggYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgVVRGOCBjb2RlIHBvaW50cy5cclxuICAgICAgICAgKiBAcGFyYW0geyghZnVuY3Rpb24oKTpudW1iZXJ8bnVsbCl9IHNyYyBDb2RlIHBvaW50cyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY29kZSBwb2ludCByZXNwZWN0aXZlbHlcclxuICAgICAgICAgKiAgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBtb3JlIGNvZGUgcG9pbnRzIGxlZnQuXHJcbiAgICAgICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG51bWJlciBvZiBVVEY4IGJ5dGVzIHJlcXVpcmVkXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5jYWxjdWxhdGVVVEY4ID0gZnVuY3Rpb24oc3JjKSB7XHJcbiAgICAgICAgICAgIHZhciBjcCwgbD0wO1xyXG4gICAgICAgICAgICB3aGlsZSAoKGNwID0gc3JjKCkpICE9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgbCArPSAoY3AgPCAweDgwKSA/IDEgOiAoY3AgPCAweDgwMCkgPyAyIDogKGNwIDwgMHgxMDAwMCkgPyAzIDogNDtcclxuICAgICAgICAgICAgcmV0dXJuIGw7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIFVURjggY29kZSBwb2ludHMgcmVzcGVjdGl2ZWx5IFVURjggYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgVVRGMTYgY2hhciBjb2Rlcy5cclxuICAgICAgICAgKiBAcGFyYW0geyghZnVuY3Rpb24oKTpudW1iZXJ8bnVsbCl9IHNyYyBDaGFyYWN0ZXJzIHNvdXJjZSBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjaGFyIGNvZGUgcmVzcGVjdGl2ZWx5XHJcbiAgICAgICAgICogIGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gVGhlIG51bWJlciBvZiBVVEY4IGNvZGUgcG9pbnRzIGF0IGluZGV4IDAgYW5kIHRoZSBudW1iZXIgb2YgVVRGOCBieXRlcyByZXF1aXJlZCBhdCBpbmRleCAxLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjggPSBmdW5jdGlvbihzcmMpIHtcclxuICAgICAgICAgICAgdmFyIG49MCwgbD0wO1xyXG4gICAgICAgICAgICB1dGZ4LlVURjE2dG9VVEY4KHNyYywgZnVuY3Rpb24oY3ApIHtcclxuICAgICAgICAgICAgICAgICsrbjsgbCArPSAoY3AgPCAweDgwKSA/IDEgOiAoY3AgPCAweDgwMCkgPyAyIDogKGNwIDwgMHgxMDAwMCkgPyAzIDogNDtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiBbbixsXTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gdXRmeDtcclxuICAgIH0oKTtcclxuXHJcbiAgICAvLyBlbmNvZGluZ3MvdXRmOFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cyBiZXR3ZWVuIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fSB0byBhbiBVVEY4IGVuY29kZWRcclxuICAgICAqICBzdHJpbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBIZXggZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXQgPiBsaW1pdGBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b1VURjggPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKSBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGJlZ2luICE9PSAnbnVtYmVyJyB8fCBiZWdpbiAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBiZWdpbjogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBiZWdpbiA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuZCAhPT0gJ251bWJlcicgfHwgZW5kICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGVuZDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBlbmQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBiZWdpbiA+IGVuZCB8fCBlbmQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK2JlZ2luK1wiIDw9IFwiK2VuZCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzZDsgdHJ5IHtcclxuICAgICAgICAgICAgdXRmeC5kZWNvZGVVVEY4dG9VVEYxNihmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBiZWdpbiA8IGVuZCA/IHRoaXMudmlld1tiZWdpbisrXSA6IG51bGw7XHJcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSwgc2QgPSBzdHJpbmdEZXN0aW5hdGlvbigpKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGlmIChiZWdpbiAhPT0gZW5kKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IFRydW5jYXRlZCBkYXRhLCBcIitiZWdpbitcIiAhPSBcIitlbmQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2QoKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGFuIFVURjggZW5jb2RlZCBzdHJpbmcgdG8gYSBCeXRlQnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gZGVjb2RlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0Fzc2VydCBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IEJ5dGVCdWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5mcm9tVVRGOCA9IGZ1bmN0aW9uKHN0ciwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xyXG4gICAgICAgIGlmICghbm9Bc3NlcnQpXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBOb3QgYSBzdHJpbmdcIik7XHJcbiAgICAgICAgdmFyIGJiID0gbmV3IEJ5dGVCdWZmZXIodXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgdHJ1ZSlbMV0sIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpLFxyXG4gICAgICAgICAgICBpID0gMDtcclxuICAgICAgICB1dGZ4LmVuY29kZVVURjE2dG9VVEY4KHN0cmluZ1NvdXJjZShzdHIpLCBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgIGJiLnZpZXdbaSsrXSA9IGI7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgYmIubGltaXQgPSBpO1xyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgcmV0dXJuIEJ5dGVCdWZmZXI7XHJcbn0pO1xyXG4iLCJ2YXIgQnVmZmVyID0gcmVxdWlyZSg5MykuQnVmZmVyXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgxMDMpLlRyYW5zZm9ybVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKDM2KS5TdHJpbmdEZWNvZGVyXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKDY1KVxuXG5mdW5jdGlvbiBDaXBoZXJCYXNlIChoYXNoTW9kZSkge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuICB0aGlzLmhhc2hNb2RlID0gdHlwZW9mIGhhc2hNb2RlID09PSAnc3RyaW5nJ1xuICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgIHRoaXNbaGFzaE1vZGVdID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9IGVsc2Uge1xuICAgIHRoaXMuZmluYWwgPSB0aGlzLl9maW5hbE9yRGlnZXN0XG4gIH1cbiAgaWYgKHRoaXMuX2ZpbmFsKSB7XG4gICAgdGhpcy5fX2ZpbmFsID0gdGhpcy5fZmluYWxcbiAgICB0aGlzLl9maW5hbCA9IG51bGxcbiAgfVxuICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuICB0aGlzLl9lbmNvZGluZyA9IG51bGxcbn1cbmluaGVyaXRzKENpcGhlckJhc2UsIFRyYW5zZm9ybSlcblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBCdWZmZXIuZnJvbShkYXRhLCBpbnB1dEVuYylcbiAgfVxuXG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSByZXR1cm4gdGhpc1xuXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jKVxuICB9XG5cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoKSB7fVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuZ2V0QXV0aFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gZ2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QXV0aFRhZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuc2V0QUFEID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ3RyeWluZyB0byBzZXQgYWFkIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChkYXRhLCBfLCBuZXh0KSB7XG4gIHZhciBlcnJcbiAgdHJ5IHtcbiAgICBpZiAodGhpcy5oYXNoTW9kZSkge1xuICAgICAgdGhpcy5fdXBkYXRlKGRhdGEpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaCh0aGlzLl91cGRhdGUoZGF0YSkpXG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIG5leHQoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbiAoZG9uZSkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgdGhpcy5wdXNoKHRoaXMuX19maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9XG5cbiAgZG9uZShlcnIpXG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9fZmluYWwoKSB8fCBCdWZmZXIuYWxsb2MoMClcbiAgaWYgKG91dHB1dEVuYykge1xuICAgIG91dERhdGEgPSB0aGlzLl90b1N0cmluZyhvdXREYXRhLCBvdXRwdXRFbmMsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG91dERhdGFcbn1cblxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX3RvU3RyaW5nID0gZnVuY3Rpb24gKHZhbHVlLCBlbmMsIGZpbikge1xuICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICB0aGlzLl9kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKVxuICAgIHRoaXMuX2VuY29kaW5nID0gZW5jXG4gIH1cblxuICBpZiAodGhpcy5fZW5jb2RpbmcgIT09IGVuYykgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuXG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluKSB7XG4gICAgb3V0ICs9IHRoaXMuX2RlY29kZXIuZW5kKClcbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDaXBoZXJCYXNlXG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpO1xuICB9XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG4iLCIndXNlIHN0cmljdCdcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoNjUpXG52YXIgTUQ1ID0gcmVxdWlyZSg2OSlcbnZhciBSSVBFTUQxNjAgPSByZXF1aXJlKDkyKVxudmFyIHNoYSA9IHJlcXVpcmUoOTYpXG52YXIgQmFzZSA9IHJlcXVpcmUoMzkpXG5cbmZ1bmN0aW9uIEhhc2ggKGhhc2gpIHtcbiAgQmFzZS5jYWxsKHRoaXMsICdkaWdlc3QnKVxuXG4gIHRoaXMuX2hhc2ggPSBoYXNoXG59XG5cbmluaGVyaXRzKEhhc2gsIEJhc2UpXG5cbkhhc2gucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxufVxuXG5IYXNoLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLl9oYXNoLmRpZ2VzdCgpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlSGFzaCAoYWxnKSB7XG4gIGFsZyA9IGFsZy50b0xvd2VyQ2FzZSgpXG4gIGlmIChhbGcgPT09ICdtZDUnKSByZXR1cm4gbmV3IE1ENSgpXG4gIGlmIChhbGcgPT09ICdybWQxNjAnIHx8IGFsZyA9PT0gJ3JpcGVtZDE2MCcpIHJldHVybiBuZXcgUklQRU1EMTYwKClcblxuICByZXR1cm4gbmV3IEhhc2goc2hhKGFsZykpXG59XG4iLCJ2YXIgTUQ1ID0gcmVxdWlyZSg2OSlcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYnVmZmVyKSB7XG4gIHJldHVybiBuZXcgTUQ1KCkudXBkYXRlKGJ1ZmZlcikuZGlnZXN0KClcbn1cbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBMZWdhY3kgPSByZXF1aXJlKDQ0KVxudmFyIEJhc2UgPSByZXF1aXJlKDM5KVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlclxudmFyIG1kNSA9IHJlcXVpcmUoNDIpXG52YXIgUklQRU1EMTYwID0gcmVxdWlyZSg5MilcblxudmFyIHNoYSA9IHJlcXVpcmUoOTYpXG5cbnZhciBaRVJPUyA9IEJ1ZmZlci5hbGxvYygxMjgpXG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdmFyIGJsb2Nrc2l6ZSA9IChhbGcgPT09ICdzaGE1MTInIHx8IGFsZyA9PT0gJ3NoYTM4NCcpID8gMTI4IDogNjRcblxuICB0aGlzLl9hbGcgPSBhbGdcbiAgdGhpcy5fa2V5ID0ga2V5XG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAgdmFyIGhhc2ggPSBhbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKGFsZylcbiAgICBrZXkgPSBoYXNoLnVwZGF0ZShrZXkpLmRpZ2VzdCgpXG4gIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgWkVST1NdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IHRoaXMuX2lwYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuICB2YXIgb3BhZCA9IHRoaXMuX29wYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tzaXplOyBpKyspIHtcbiAgICBpcGFkW2ldID0ga2V5W2ldIF4gMHgzNlxuICAgIG9wYWRbaV0gPSBrZXlbaV0gXiAweDVDXG4gIH1cbiAgdGhpcy5faGFzaCA9IGFsZyA9PT0gJ3JtZDE2MCcgPyBuZXcgUklQRU1EMTYwKCkgOiBzaGEoYWxnKVxuICB0aGlzLl9oYXNoLnVwZGF0ZShpcGFkKVxufVxuXG5pbmhlcml0cyhIbWFjLCBCYXNlKVxuXG5IbWFjLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbn1cblxuSG1hYy5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaCA9IHRoaXMuX2hhc2guZGlnZXN0KClcbiAgdmFyIGhhc2ggPSB0aGlzLl9hbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKHRoaXMuX2FsZylcbiAgcmV0dXJuIGhhc2gudXBkYXRlKHRoaXMuX29wYWQpLnVwZGF0ZShoKS5kaWdlc3QoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhtYWMgKGFsZywga2V5KSB7XG4gIGFsZyA9IGFsZy50b0xvd2VyQ2FzZSgpXG4gIGlmIChhbGcgPT09ICdybWQxNjAnIHx8IGFsZyA9PT0gJ3JpcGVtZDE2MCcpIHtcbiAgICByZXR1cm4gbmV3IEhtYWMoJ3JtZDE2MCcsIGtleSlcbiAgfVxuICBpZiAoYWxnID09PSAnbWQ1Jykge1xuICAgIHJldHVybiBuZXcgTGVnYWN5KG1kNSwga2V5KVxuICB9XG4gIHJldHVybiBuZXcgSG1hYyhhbGcsIGtleSlcbn1cbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcblxudmFyIEJhc2UgPSByZXF1aXJlKDM5KVxuXG52YXIgWkVST1MgPSBCdWZmZXIuYWxsb2MoMTI4KVxudmFyIGJsb2Nrc2l6ZSA9IDY0XG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdGhpcy5fYWxnID0gYWxnXG4gIHRoaXMuX2tleSA9IGtleVxuXG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAga2V5ID0gYWxnKGtleSlcbiAgfSBlbHNlIGlmIChrZXkubGVuZ3RoIDwgYmxvY2tzaXplKSB7XG4gICAga2V5ID0gQnVmZmVyLmNvbmNhdChba2V5LCBaRVJPU10sIGJsb2Nrc2l6ZSlcbiAgfVxuXG4gIHZhciBpcGFkID0gdGhpcy5faXBhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG4gIHZhciBvcGFkID0gdGhpcy5fb3BhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja3NpemU7IGkrKykge1xuICAgIGlwYWRbaV0gPSBrZXlbaV0gXiAweDM2XG4gICAgb3BhZFtpXSA9IGtleVtpXSBeIDB4NUNcbiAgfVxuXG4gIHRoaXMuX2hhc2ggPSBbaXBhZF1cbn1cblxuaW5oZXJpdHMoSG1hYywgQmFzZSlcblxuSG1hYy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2hhc2gucHVzaChkYXRhKVxufVxuXG5IbWFjLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBoID0gdGhpcy5fYWxnKEJ1ZmZlci5jb25jYXQodGhpcy5faGFzaCkpXG4gIHJldHVybiB0aGlzLl9hbGcoQnVmZmVyLmNvbmNhdChbdGhpcy5fb3BhZCwgaF0pKVxufVxubW9kdWxlLmV4cG9ydHMgPSBIbWFjXG4iLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSg0NyksIHJlcXVpcmUoNDgpLCByZXF1aXJlKDUyKSwgcmVxdWlyZSg1MCksIHJlcXVpcmUoNDYpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL2VuYy1iYXNlNjRcIiwgXCIuL21kNVwiLCBcIi4vZXZwa2RmXCIsIFwiLi9jaXBoZXItY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyID0gQ19saWIuQmxvY2tDaXBoZXI7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICAvLyBMb29rdXAgdGFibGVzXG5cdCAgICB2YXIgU0JPWCA9IFtdO1xuXHQgICAgdmFyIElOVl9TQk9YID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8wID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8xID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8yID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8zID0gW107XG5cdCAgICB2YXIgSU5WX1NVQl9NSVhfMCA9IFtdO1xuXHQgICAgdmFyIElOVl9TVUJfTUlYXzEgPSBbXTtcblx0ICAgIHZhciBJTlZfU1VCX01JWF8yID0gW107XG5cdCAgICB2YXIgSU5WX1NVQl9NSVhfMyA9IFtdO1xuXG5cdCAgICAvLyBDb21wdXRlIGxvb2t1cCB0YWJsZXNcblx0ICAgIChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgLy8gQ29tcHV0ZSBkb3VibGUgdGFibGVcblx0ICAgICAgICB2YXIgZCA9IFtdO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcblx0ICAgICAgICAgICAgaWYgKGkgPCAxMjgpIHtcblx0ICAgICAgICAgICAgICAgIGRbaV0gPSBpIDw8IDE7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBkW2ldID0gKGkgPDwgMSkgXiAweDExYjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIFdhbGsgR0YoMl44KVxuXHQgICAgICAgIHZhciB4ID0gMDtcblx0ICAgICAgICB2YXIgeGkgPSAwO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBzYm94XG5cdCAgICAgICAgICAgIHZhciBzeCA9IHhpIF4gKHhpIDw8IDEpIF4gKHhpIDw8IDIpIF4gKHhpIDw8IDMpIF4gKHhpIDw8IDQpO1xuXHQgICAgICAgICAgICBzeCA9IChzeCA+Pj4gOCkgXiAoc3ggJiAweGZmKSBeIDB4NjM7XG5cdCAgICAgICAgICAgIFNCT1hbeF0gPSBzeDtcblx0ICAgICAgICAgICAgSU5WX1NCT1hbc3hdID0geDtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIG11bHRpcGxpY2F0aW9uXG5cdCAgICAgICAgICAgIHZhciB4MiA9IGRbeF07XG5cdCAgICAgICAgICAgIHZhciB4NCA9IGRbeDJdO1xuXHQgICAgICAgICAgICB2YXIgeDggPSBkW3g0XTtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIHN1YiBieXRlcywgbWl4IGNvbHVtbnMgdGFibGVzXG5cdCAgICAgICAgICAgIHZhciB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKTtcblx0ICAgICAgICAgICAgU1VCX01JWF8wW3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzFbeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzJbeF0gPSAodCA8PCA4KSAgfCAodCA+Pj4gMjQpO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzNbeF0gPSB0O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgaW52IHN1YiBieXRlcywgaW52IG1peCBjb2x1bW5zIHRhYmxlc1xuXHQgICAgICAgICAgICB2YXIgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKTtcblx0ICAgICAgICAgICAgSU5WX1NVQl9NSVhfMFtzeF0gPSAodCA8PCAyNCkgfCAodCA+Pj4gOCk7XG5cdCAgICAgICAgICAgIElOVl9TVUJfTUlYXzFbc3hdID0gKHQgPDwgMTYpIHwgKHQgPj4+IDE2KTtcblx0ICAgICAgICAgICAgSU5WX1NVQl9NSVhfMltzeF0gPSAodCA8PCA4KSAgfCAodCA+Pj4gMjQpO1xuXHQgICAgICAgICAgICBJTlZfU1VCX01JWF8zW3N4XSA9IHQ7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBuZXh0IGNvdW50ZXJcblx0ICAgICAgICAgICAgaWYgKCF4KSB7XG5cdCAgICAgICAgICAgICAgICB4ID0geGkgPSAxO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgeCA9IHgyIF4gZFtkW2RbeDggXiB4Ml1dXTtcblx0ICAgICAgICAgICAgICAgIHhpIF49IGRbZFt4aV1dO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSgpKTtcblxuXHQgICAgLy8gUHJlY29tcHV0ZWQgUmNvbiBsb29rdXBcblx0ICAgIHZhciBSQ09OID0gWzB4MDAsIDB4MDEsIDB4MDIsIDB4MDQsIDB4MDgsIDB4MTAsIDB4MjAsIDB4NDAsIDB4ODAsIDB4MWIsIDB4MzZdO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFFUyBibG9jayBjaXBoZXIgYWxnb3JpdGhtLlxuXHQgICAgICovXG5cdCAgICB2YXIgQUVTID0gQ19hbGdvLkFFUyA9IEJsb2NrQ2lwaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2tpcCByZXNldCBvZiBuUm91bmRzIGhhcyBiZWVuIHNldCBiZWZvcmUgYW5kIGtleSBkaWQgbm90IGNoYW5nZVxuXHQgICAgICAgICAgICBpZiAodGhpcy5fblJvdW5kcyAmJiB0aGlzLl9rZXlQcmlvclJlc2V0ID09PSB0aGlzLl9rZXkpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIga2V5ID0gdGhpcy5fa2V5UHJpb3JSZXNldCA9IHRoaXMuX2tleTtcblx0ICAgICAgICAgICAgdmFyIGtleVdvcmRzID0ga2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGtleS5zaWdCeXRlcyAvIDQ7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBudW1iZXIgb2Ygcm91bmRzXG5cdCAgICAgICAgICAgIHZhciBuUm91bmRzID0gdGhpcy5fblJvdW5kcyA9IGtleVNpemUgKyA2O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgbnVtYmVyIG9mIGtleSBzY2hlZHVsZSByb3dzXG5cdCAgICAgICAgICAgIHZhciBrc1Jvd3MgPSAoblJvdW5kcyArIDEpICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIGtleSBzY2hlZHVsZVxuXHQgICAgICAgICAgICB2YXIga2V5U2NoZWR1bGUgPSB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBrc1JvdyA9IDA7IGtzUm93IDwga3NSb3dzOyBrc1JvdysrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoa3NSb3cgPCBrZXlTaXplKSB7XG5cdCAgICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5V29yZHNba3NSb3ddO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgdCA9IGtleVNjaGVkdWxlW2tzUm93IC0gMV07XG5cblx0ICAgICAgICAgICAgICAgICAgICBpZiAoIShrc1JvdyAlIGtleVNpemUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJvdCB3b3JkXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAodCA8PCA4KSB8ICh0ID4+PiAyNCk7XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3ViIHdvcmRcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdCA9IChTQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsodCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3QgJiAweGZmXTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBNaXggUmNvblxuXHQgICAgICAgICAgICAgICAgICAgICAgICB0IF49IFJDT05bKGtzUm93IC8ga2V5U2l6ZSkgfCAwXSA8PCAyNDtcblx0ICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PSA0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1YiB3b3JkXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAoU0JPWFt0ID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFt0ICYgMHhmZl07XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQ7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIGludiBrZXkgc2NoZWR1bGVcblx0ICAgICAgICAgICAgdmFyIGludktleVNjaGVkdWxlID0gdGhpcy5faW52S2V5U2NoZWR1bGUgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaW52S3NSb3cgPSAwOyBpbnZLc1JvdyA8IGtzUm93czsgaW52S3NSb3crKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGtzUm93ID0ga3NSb3dzIC0gaW52S3NSb3c7XG5cblx0ICAgICAgICAgICAgICAgIGlmIChpbnZLc1JvdyAlIDQpIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgdCA9IGtleVNjaGVkdWxlW2tzUm93XTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSBrZXlTY2hlZHVsZVtrc1JvdyAtIDRdO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICBpZiAoaW52S3NSb3cgPCA0IHx8IGtzUm93IDw9IDQpIHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSB0O1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSBJTlZfU1VCX01JWF8wW1NCT1hbdCA+Pj4gMjRdXSBeIElOVl9TVUJfTUlYXzFbU0JPWFsodCA+Pj4gMTYpICYgMHhmZl1dIF5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlZfU1VCX01JWF8yW1NCT1hbKHQgPj4+IDgpICYgMHhmZl1dIF4gSU5WX1NVQl9NSVhfM1tTQk9YW3QgJiAweGZmXV07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgZW5jcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2RvQ3J5cHRCbG9jayhNLCBvZmZzZXQsIHRoaXMuX2tleVNjaGVkdWxlLCBTVUJfTUlYXzAsIFNVQl9NSVhfMSwgU1VCX01JWF8yLCBTVUJfTUlYXzMsIFNCT1gpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBkZWNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU3dhcCAybmQgYW5kIDR0aCByb3dzXG5cdCAgICAgICAgICAgIHZhciB0ID0gTVtvZmZzZXQgKyAxXTtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAxXSA9IE1bb2Zmc2V0ICsgM107XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgM10gPSB0O1xuXG5cdCAgICAgICAgICAgIHRoaXMuX2RvQ3J5cHRCbG9jayhNLCBvZmZzZXQsIHRoaXMuX2ludktleVNjaGVkdWxlLCBJTlZfU1VCX01JWF8wLCBJTlZfU1VCX01JWF8xLCBJTlZfU1VCX01JWF8yLCBJTlZfU1VCX01JWF8zLCBJTlZfU0JPWCk7XG5cblx0ICAgICAgICAgICAgLy8gSW52IHN3YXAgMm5kIGFuZCA0dGggcm93c1xuXHQgICAgICAgICAgICB2YXIgdCA9IE1bb2Zmc2V0ICsgMV07XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSBNW29mZnNldCArIDNdO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDNdID0gdDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvQ3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCwga2V5U2NoZWR1bGUsIFNVQl9NSVhfMCwgU1VCX01JWF8xLCBTVUJfTUlYXzIsIFNVQl9NSVhfMywgU0JPWCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgblJvdW5kcyA9IHRoaXMuX25Sb3VuZHM7XG5cblx0ICAgICAgICAgICAgLy8gR2V0IGlucHV0LCBhZGQgcm91bmQga2V5XG5cdCAgICAgICAgICAgIHZhciBzMCA9IE1bb2Zmc2V0XSAgICAgXiBrZXlTY2hlZHVsZVswXTtcblx0ICAgICAgICAgICAgdmFyIHMxID0gTVtvZmZzZXQgKyAxXSBeIGtleVNjaGVkdWxlWzFdO1xuXHQgICAgICAgICAgICB2YXIgczIgPSBNW29mZnNldCArIDJdIF4ga2V5U2NoZWR1bGVbMl07XG5cdCAgICAgICAgICAgIHZhciBzMyA9IE1bb2Zmc2V0ICsgM10gXiBrZXlTY2hlZHVsZVszXTtcblxuXHQgICAgICAgICAgICAvLyBLZXkgc2NoZWR1bGUgcm93IGNvdW50ZXJcblx0ICAgICAgICAgICAgdmFyIGtzUm93ID0gNDtcblxuXHQgICAgICAgICAgICAvLyBSb3VuZHNcblx0ICAgICAgICAgICAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IG5Sb3VuZHM7IHJvdW5kKyspIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNoaWZ0IHJvd3MsIHN1YiBieXRlcywgbWl4IGNvbHVtbnMsIGFkZCByb3VuZCBrZXlcblx0ICAgICAgICAgICAgICAgIHZhciB0MCA9IFNVQl9NSVhfMFtzMCA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMSA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MzICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MSA9IFNVQl9NSVhfMFtzMSA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMiA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMzID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MwICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MiA9IFNVQl9NSVhfMFtzMiA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMyA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MxICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MyA9IFNVQl9NSVhfMFtzMyA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMCA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MyICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblxuXHQgICAgICAgICAgICAgICAgLy8gVXBkYXRlIHN0YXRlXG5cdCAgICAgICAgICAgICAgICBzMCA9IHQwO1xuXHQgICAgICAgICAgICAgICAgczEgPSB0MTtcblx0ICAgICAgICAgICAgICAgIHMyID0gdDI7XG5cdCAgICAgICAgICAgICAgICBzMyA9IHQzO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gU2hpZnQgcm93cywgc3ViIGJ5dGVzLCBhZGQgcm91bmQga2V5XG5cdCAgICAgICAgICAgIHZhciB0MCA9ICgoU0JPWFtzMCA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMSA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMyID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMyAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdO1xuXHQgICAgICAgICAgICB2YXIgdDEgPSAoKFNCT1hbczEgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczIgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMyA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczAgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgdmFyIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgIHZhciB0MyA9ICgoU0JPWFtzMyA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMxID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMiAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdO1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBvdXRwdXRcblx0ICAgICAgICAgICAgTVtvZmZzZXRdICAgICA9IHQwO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDFdID0gdDE7XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgMl0gPSB0Mjtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAzXSA9IHQzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBrZXlTaXplOiAyNTYvMzJcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9ucyB0byB0aGUgY2lwaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgY2lwaGVydGV4dCA9IENyeXB0b0pTLkFFUy5lbmNyeXB0KG1lc3NhZ2UsIGtleSwgY2ZnKTtcblx0ICAgICAqICAgICB2YXIgcGxhaW50ZXh0ICA9IENyeXB0b0pTLkFFUy5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTtcblx0ICAgICAqL1xuXHQgICAgQy5BRVMgPSBCbG9ja0NpcGhlci5fY3JlYXRlSGVscGVyKEFFUyk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuQUVTO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoNDcpLCByZXF1aXJlKDUwKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9ldnBrZGZcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdC8qKlxuXHQgKiBDaXBoZXIgY29yZSBjb21wb25lbnRzLlxuXHQgKi9cblx0Q3J5cHRvSlMubGliLkNpcGhlciB8fCAoZnVuY3Rpb24gKHVuZGVmaW5lZCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBDX2xpYi5CdWZmZXJlZEJsb2NrQWxnb3JpdGhtO1xuXHQgICAgdmFyIENfZW5jID0gQy5lbmM7XG5cdCAgICB2YXIgVXRmOCA9IENfZW5jLlV0Zjg7XG5cdCAgICB2YXIgQmFzZTY0ID0gQ19lbmMuQmFzZTY0O1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblx0ICAgIHZhciBFdnBLREYgPSBDX2FsZ28uRXZwS0RGO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFic3RyYWN0IGJhc2UgY2lwaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBrZXlTaXplIFRoaXMgY2lwaGVyJ3Mga2V5IHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKVxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGl2U2l6ZSBUaGlzIGNpcGhlcidzIElWIHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKVxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9FTkNfWEZPUk1fTU9ERSBBIGNvbnN0YW50IHJlcHJlc2VudGluZyBlbmNyeXB0aW9uIG1vZGUuXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX0RFQ19YRk9STV9NT0RFIEEgY29uc3RhbnQgcmVwcmVzZW50aW5nIGRlY3J5cHRpb24gbW9kZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENpcGhlciA9IENfbGliLkNpcGhlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gaXYgVGhlIElWIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyB0aGlzIGNpcGhlciBpbiBlbmNyeXB0aW9uIG1vZGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlcn0gQSBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXIgPSBDcnlwdG9KUy5hbGdvLkFFUy5jcmVhdGVFbmNyeXB0b3Ioa2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVFbmNyeXB0b3I6IGZ1bmN0aW9uIChrZXksIGNmZykge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUodGhpcy5fRU5DX1hGT1JNX01PREUsIGtleSwgY2ZnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyB0aGlzIGNpcGhlciBpbiBkZWNyeXB0aW9uIG1vZGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlcn0gQSBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXIgPSBDcnlwdG9KUy5hbGdvLkFFUy5jcmVhdGVEZWNyeXB0b3Ioa2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVEZWNyeXB0b3I6IGZ1bmN0aW9uIChrZXksIGNmZykge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUodGhpcy5fREVDX1hGT1JNX01PREUsIGtleSwgY2ZnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIGNpcGhlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4Zm9ybU1vZGUgRWl0aGVyIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gdHJhbnNvcm1hdGlvbiBtb2RlIGNvbnN0YW50LlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVyID0gQ3J5cHRvSlMuYWxnby5BRVMuY3JlYXRlKENyeXB0b0pTLmFsZ28uQUVTLl9FTkNfWEZPUk1fTU9ERSwga2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoeGZvcm1Nb2RlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBTdG9yZSB0cmFuc2Zvcm0gbW9kZSBhbmQga2V5XG5cdCAgICAgICAgICAgIHRoaXMuX3hmb3JtTW9kZSA9IHhmb3JtTW9kZTtcblx0ICAgICAgICAgICAgdGhpcy5fa2V5ID0ga2V5O1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFJlc2V0cyB0aGlzIGNpcGhlciB0byBpdHMgaW5pdGlhbCBzdGF0ZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgY2lwaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gUmVzZXQgZGF0YSBidWZmZXJcblx0ICAgICAgICAgICAgQnVmZmVyZWRCbG9ja0FsZ29yaXRobS5yZXNldC5jYWxsKHRoaXMpO1xuXG5cdCAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljXG5cdCAgICAgICAgICAgIHRoaXMuX2RvUmVzZXQoKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQWRkcyBkYXRhIHRvIGJlIGVuY3J5cHRlZCBvciBkZWNyeXB0ZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGRhdGFVcGRhdGUgVGhlIGRhdGEgdG8gZW5jcnlwdCBvciBkZWNyeXB0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGF0YSBhZnRlciBwcm9jZXNzaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgZW5jcnlwdGVkID0gY2lwaGVyLnByb2Nlc3MoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5wcm9jZXNzKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcHJvY2VzczogZnVuY3Rpb24gKGRhdGFVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gQXBwZW5kXG5cdCAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTtcblxuXHQgICAgICAgICAgICAvLyBQcm9jZXNzIGF2YWlsYWJsZSBibG9ja3Ncblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3MoKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRmluYWxpemVzIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gcHJvY2Vzcy5cblx0ICAgICAgICAgKiBOb3RlIHRoYXQgdGhlIGZpbmFsaXplIG9wZXJhdGlvbiBpcyBlZmZlY3RpdmVseSBhIGRlc3RydWN0aXZlLCByZWFkLW9uY2Ugb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhVXBkYXRlIFRoZSBmaW5hbCBkYXRhIHRvIGVuY3J5cHQgb3IgZGVjcnlwdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRhdGEgYWZ0ZXIgZmluYWwgcHJvY2Vzc2luZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5maW5hbGl6ZSgpO1xuXHQgICAgICAgICAqICAgICB2YXIgZW5jcnlwdGVkID0gY2lwaGVyLmZpbmFsaXplKCdkYXRhJyk7XG5cdCAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmaW5hbGl6ZTogZnVuY3Rpb24gKGRhdGFVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gRmluYWwgZGF0YSB1cGRhdGVcblx0ICAgICAgICAgICAgaWYgKGRhdGFVcGRhdGUpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljXG5cdCAgICAgICAgICAgIHZhciBmaW5hbFByb2Nlc3NlZERhdGEgPSB0aGlzLl9kb0ZpbmFsaXplKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGZpbmFsUHJvY2Vzc2VkRGF0YTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAga2V5U2l6ZTogMTI4LzMyLFxuXG5cdCAgICAgICAgaXZTaXplOiAxMjgvMzIsXG5cblx0ICAgICAgICBfRU5DX1hGT1JNX01PREU6IDEsXG5cblx0ICAgICAgICBfREVDX1hGT1JNX01PREU6IDIsXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIHNob3J0Y3V0IGZ1bmN0aW9ucyB0byBhIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgdG8gY3JlYXRlIGEgaGVscGVyIGZvci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gQW4gb2JqZWN0IHdpdGggZW5jcnlwdCBhbmQgZGVjcnlwdCBzaG9ydGN1dCBmdW5jdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBBRVMgPSBDcnlwdG9KUy5saWIuQ2lwaGVyLl9jcmVhdGVIZWxwZXIoQ3J5cHRvSlMuYWxnby5BRVMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9jcmVhdGVIZWxwZXI6IChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIGZ1bmN0aW9uIHNlbGVjdENpcGhlclN0cmF0ZWd5KGtleSkge1xuXHQgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBrZXkgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGFzc3dvcmRCYXNlZENpcGhlcjtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNlcmlhbGl6YWJsZUNpcGhlcjtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoY2lwaGVyKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGVuY3J5cHQ6IGZ1bmN0aW9uIChtZXNzYWdlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0Q2lwaGVyU3RyYXRlZ3koa2V5KS5lbmNyeXB0KGNpcGhlciwgbWVzc2FnZSwga2V5LCBjZmcpO1xuXHQgICAgICAgICAgICAgICAgICAgIH0sXG5cblx0ICAgICAgICAgICAgICAgICAgICBkZWNyeXB0OiBmdW5jdGlvbiAoY2lwaGVydGV4dCwga2V5LCBjZmcpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdENpcGhlclN0cmF0ZWd5KGtleSkuZGVjcnlwdChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH0oKSlcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFic3RyYWN0IGJhc2Ugc3RyZWFtIGNpcGhlciB0ZW1wbGF0ZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgY2lwaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiAxICgzMiBiaXRzKVxuXHQgICAgICovXG5cdCAgICB2YXIgU3RyZWFtQ2lwaGVyID0gQ19saWIuU3RyZWFtQ2lwaGVyID0gQ2lwaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gUHJvY2VzcyBwYXJ0aWFsIGJsb2Nrc1xuXHQgICAgICAgICAgICB2YXIgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKCEhJ2ZsdXNoJyk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGZpbmFsUHJvY2Vzc2VkQmxvY2tzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBibG9ja1NpemU6IDFcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIE1vZGUgbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19tb2RlID0gQy5tb2RlID0ge307XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYmFzZSBibG9jayBjaXBoZXIgbW9kZSB0ZW1wbGF0ZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyTW9kZSA9IENfbGliLkJsb2NrQ2lwaGVyTW9kZSA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIHRoaXMgbW9kZSBmb3IgZW5jcnlwdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgQSBibG9jayBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtBcnJheX0gaXYgVGhlIElWIHdvcmRzLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgbW9kZSA9IENyeXB0b0pTLm1vZGUuQ0JDLmNyZWF0ZUVuY3J5cHRvcihjaXBoZXIsIGl2LndvcmRzKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVFbmNyeXB0b3I6IGZ1bmN0aW9uIChjaXBoZXIsIGl2KSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLkVuY3J5cHRvci5jcmVhdGUoY2lwaGVyLCBpdik7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENyZWF0ZXMgdGhpcyBtb2RlIGZvciBkZWNyeXB0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBBIGJsb2NrIGNpcGhlciBpbnN0YW5jZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBpdiBUaGUgSVYgd29yZHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBtb2RlID0gQ3J5cHRvSlMubW9kZS5DQkMuY3JlYXRlRGVjcnlwdG9yKGNpcGhlciwgaXYud29yZHMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNyZWF0ZURlY3J5cHRvcjogZnVuY3Rpb24gKGNpcGhlciwgaXYpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuRGVjcnlwdG9yLmNyZWF0ZShjaXBoZXIsIGl2KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG1vZGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIEEgYmxvY2sgY2lwaGVyIGluc3RhbmNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGl2IFRoZSBJViB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIG1vZGUgPSBDcnlwdG9KUy5tb2RlLkNCQy5FbmNyeXB0b3IuY3JlYXRlKGNpcGhlciwgaXYud29yZHMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjaXBoZXIsIGl2KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2NpcGhlciA9IGNpcGhlcjtcblx0ICAgICAgICAgICAgdGhpcy5faXYgPSBpdjtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENCQyA9IENfbW9kZS5DQkMgPSAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEFic3RyYWN0IGJhc2UgQ0JDIG1vZGUuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdmFyIENCQyA9IEJsb2NrQ2lwaGVyTW9kZS5leHRlbmQoKTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENCQyBlbmNyeXB0b3IuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgQ0JDLkVuY3J5cHRvciA9IENCQy5leHRlbmQoe1xuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogUHJvY2Vzc2VzIHRoZSBkYXRhIGJsb2NrIGF0IG9mZnNldC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgVGhlIGRhdGEgd29yZHMgdG8gb3BlcmF0ZSBvbi5cblx0ICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBUaGUgb2Zmc2V0IHdoZXJlIHRoZSBibG9jayBzdGFydHMuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBtb2RlLnByb2Nlc3NCbG9jayhkYXRhLndvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyO1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZSA9IGNpcGhlci5ibG9ja1NpemU7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFhPUiBhbmQgZW5jcnlwdFxuXHQgICAgICAgICAgICAgICAgeG9yQmxvY2suY2FsbCh0aGlzLCB3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUpO1xuXHQgICAgICAgICAgICAgICAgY2lwaGVyLmVuY3J5cHRCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhpcyBibG9jayB0byB1c2Ugd2l0aCBuZXh0IGJsb2NrXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9wcmV2QmxvY2sgPSB3b3Jkcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGJsb2NrU2l6ZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENCQyBkZWNyeXB0b3IuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgQ0JDLkRlY3J5cHRvciA9IENCQy5leHRlbmQoe1xuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogUHJvY2Vzc2VzIHRoZSBkYXRhIGJsb2NrIGF0IG9mZnNldC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgVGhlIGRhdGEgd29yZHMgdG8gb3BlcmF0ZSBvbi5cblx0ICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBUaGUgb2Zmc2V0IHdoZXJlIHRoZSBibG9jayBzdGFydHMuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBtb2RlLnByb2Nlc3NCbG9jayhkYXRhLndvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyO1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZSA9IGNpcGhlci5ibG9ja1NpemU7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoaXMgYmxvY2sgdG8gdXNlIHdpdGggbmV4dCBibG9ja1xuXHQgICAgICAgICAgICAgICAgdmFyIHRoaXNCbG9jayA9IHdvcmRzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmxvY2tTaXplKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gRGVjcnlwdCBhbmQgWE9SXG5cdCAgICAgICAgICAgICAgICBjaXBoZXIuZGVjcnlwdEJsb2NrKHdvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgICAgeG9yQmxvY2suY2FsbCh0aGlzLCB3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBUaGlzIGJsb2NrIGJlY29tZXMgdGhlIHByZXZpb3VzIGJsb2NrXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9wcmV2QmxvY2sgPSB0aGlzQmxvY2s7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblxuXHQgICAgICAgIGZ1bmN0aW9uIHhvckJsb2NrKHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLl9pdjtcblxuXHQgICAgICAgICAgICAvLyBDaG9vc2UgbWl4aW5nIGJsb2NrXG5cdCAgICAgICAgICAgIGlmIChpdikge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gaXY7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBJViBmb3Igc3Vic2VxdWVudCBibG9ja3Ncblx0ICAgICAgICAgICAgICAgIHRoaXMuX2l2ID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gdGhpcy5fcHJldkJsb2NrO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gWE9SIGJsb2Nrc1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrU2l6ZTsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tvZmZzZXQgKyBpXSBePSBibG9ja1tpXTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBDQkM7XG5cdCAgICB9KCkpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFBhZGRpbmcgbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19wYWQgPSBDLnBhZCA9IHt9O1xuXG5cdCAgICAvKipcblx0ICAgICAqIFBLQ1MgIzUvNyBwYWRkaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgUGtjczcgPSBDX3BhZC5Qa2NzNyA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBQYWRzIGRhdGEgdXNpbmcgdGhlIGFsZ29yaXRobSBkZWZpbmVkIGluIFBLQ1MgIzUvNy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBkYXRhIFRoZSBkYXRhIHRvIHBhZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gYmxvY2tTaXplIFRoZSBtdWx0aXBsZSB0aGF0IHRoZSBkYXRhIHNob3VsZCBiZSBwYWRkZWQgdG8uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIENyeXB0b0pTLnBhZC5Qa2NzNy5wYWQod29yZEFycmF5LCA0KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBwYWRkaW5nIGJ5dGVzXG5cdCAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gYmxvY2tTaXplQnl0ZXMgLSBkYXRhLnNpZ0J5dGVzICUgYmxvY2tTaXplQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIHBhZGRpbmcgd29yZFxuXHQgICAgICAgICAgICB2YXIgcGFkZGluZ1dvcmQgPSAoblBhZGRpbmdCeXRlcyA8PCAyNCkgfCAoblBhZGRpbmdCeXRlcyA8PCAxNikgfCAoblBhZGRpbmdCeXRlcyA8PCA4KSB8IG5QYWRkaW5nQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIHBhZGRpbmdcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmdXb3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5QYWRkaW5nQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgcGFkZGluZ1dvcmRzLnB1c2gocGFkZGluZ1dvcmQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nID0gV29yZEFycmF5LmNyZWF0ZShwYWRkaW5nV29yZHMsIG5QYWRkaW5nQnl0ZXMpO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGEuY29uY2F0KHBhZGRpbmcpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBVbnBhZHMgZGF0YSB0aGF0IGhhZCBiZWVuIHBhZGRlZCB1c2luZyB0aGUgYWxnb3JpdGhtIGRlZmluZWQgaW4gUEtDUyAjNS83LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGRhdGEgVGhlIGRhdGEgdG8gdW5wYWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIENyeXB0b0pTLnBhZC5Qa2NzNy51bnBhZCh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHVucGFkOiBmdW5jdGlvbiAoZGF0YSkge1xuXHQgICAgICAgICAgICAvLyBHZXQgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgZnJvbSBsYXN0IGJ5dGVcblx0ICAgICAgICAgICAgdmFyIG5QYWRkaW5nQnl0ZXMgPSBkYXRhLndvcmRzWyhkYXRhLnNpZ0J5dGVzIC0gMSkgPj4+IDJdICYgMHhmZjtcblxuXHQgICAgICAgICAgICAvLyBSZW1vdmUgcGFkZGluZ1xuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzIC09IG5QYWRkaW5nQnl0ZXM7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBYnN0cmFjdCBiYXNlIGJsb2NrIGNpcGhlciB0ZW1wbGF0ZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgY2lwaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiA0ICgxMjggYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyID0gQ19saWIuQmxvY2tDaXBoZXIgPSBDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge01vZGV9IG1vZGUgVGhlIGJsb2NrIG1vZGUgdG8gdXNlLiBEZWZhdWx0OiBDQkNcblx0ICAgICAgICAgKiBAcHJvcGVydHkge1BhZGRpbmd9IHBhZGRpbmcgVGhlIHBhZGRpbmcgc3RyYXRlZ3kgdG8gdXNlLiBEZWZhdWx0OiBQa2NzN1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogQ2lwaGVyLmNmZy5leHRlbmQoe1xuXHQgICAgICAgICAgICBtb2RlOiBDQkMsXG5cdCAgICAgICAgICAgIHBhZGRpbmc6IFBrY3M3XG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBSZXNldCBjaXBoZXJcblx0ICAgICAgICAgICAgQ2lwaGVyLnJlc2V0LmNhbGwodGhpcyk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBjZmcgPSB0aGlzLmNmZztcblx0ICAgICAgICAgICAgdmFyIGl2ID0gY2ZnLml2O1xuXHQgICAgICAgICAgICB2YXIgbW9kZSA9IGNmZy5tb2RlO1xuXG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGJsb2NrIG1vZGVcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3hmb3JtTW9kZSA9PSB0aGlzLl9FTkNfWEZPUk1fTU9ERSkge1xuXHQgICAgICAgICAgICAgICAgdmFyIG1vZGVDcmVhdG9yID0gbW9kZS5jcmVhdGVFbmNyeXB0b3I7XG5cdCAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqLyB7XG5cdCAgICAgICAgICAgICAgICB2YXIgbW9kZUNyZWF0b3IgPSBtb2RlLmNyZWF0ZURlY3J5cHRvcjtcblx0ICAgICAgICAgICAgICAgIC8vIEtlZXAgYXQgbGVhc3Qgb25lIGJsb2NrIGluIHRoZSBidWZmZXIgZm9yIHVucGFkZGluZ1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fbWluQnVmZmVyU2l6ZSA9IDE7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBpZiAodGhpcy5fbW9kZSAmJiB0aGlzLl9tb2RlLl9fY3JlYXRvciA9PSBtb2RlQ3JlYXRvcikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fbW9kZS5pbml0KHRoaXMsIGl2ICYmIGl2LndvcmRzKTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX21vZGUgPSBtb2RlQ3JlYXRvci5jYWxsKG1vZGUsIHRoaXMsIGl2ICYmIGl2LndvcmRzKTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX21vZGUuX19jcmVhdG9yID0gbW9kZUNyZWF0b3I7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICB0aGlzLl9tb2RlLnByb2Nlc3NCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmcgPSB0aGlzLmNmZy5wYWRkaW5nO1xuXG5cdCAgICAgICAgICAgIC8vIEZpbmFsaXplXG5cdCAgICAgICAgICAgIGlmICh0aGlzLl94Zm9ybU1vZGUgPT0gdGhpcy5fRU5DX1hGT1JNX01PREUpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFBhZCBkYXRhXG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nLnBhZCh0aGlzLl9kYXRhLCB0aGlzLmJsb2NrU2l6ZSk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgICAgICB2YXIgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKCEhJ2ZsdXNoJyk7XG5cdCAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqLyB7XG5cdCAgICAgICAgICAgICAgICAvLyBQcm9jZXNzIGZpbmFsIGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkQmxvY2tzID0gdGhpcy5fcHJvY2VzcyghISdmbHVzaCcpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBVbnBhZCBkYXRhXG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nLnVucGFkKGZpbmFsUHJvY2Vzc2VkQmxvY2tzKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBmaW5hbFByb2Nlc3NlZEJsb2Nrcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgYmxvY2tTaXplOiAxMjgvMzJcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEEgY29sbGVjdGlvbiBvZiBjaXBoZXIgcGFyYW1ldGVycy5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gY2lwaGVydGV4dCBUaGUgcmF3IGNpcGhlcnRleHQuXG5cdCAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkgdG8gdGhpcyBjaXBoZXJ0ZXh0LlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IGl2IFRoZSBJViB1c2VkIGluIHRoZSBjaXBoZXJpbmcgb3BlcmF0aW9uLlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IHNhbHQgVGhlIHNhbHQgdXNlZCB3aXRoIGEga2V5IGRlcml2YXRpb24gZnVuY3Rpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge0NpcGhlcn0gYWxnb3JpdGhtIFRoZSBjaXBoZXIgYWxnb3JpdGhtLlxuXHQgICAgICogQHByb3BlcnR5IHtNb2RlfSBtb2RlIFRoZSBibG9jayBtb2RlIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge1BhZGRpbmd9IHBhZGRpbmcgVGhlIHBhZGRpbmcgc2NoZW1lIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBibG9jayBzaXplIG9mIHRoZSBjaXBoZXIuXG5cdCAgICAgKiBAcHJvcGVydHkge0Zvcm1hdH0gZm9ybWF0dGVyIFRoZSBkZWZhdWx0IGZvcm1hdHRpbmcgc3RyYXRlZ3kgdG8gY29udmVydCB0aGlzIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGEgc3RyaW5nLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ2lwaGVyUGFyYW1zID0gQ19saWIuQ2lwaGVyUGFyYW1zID0gQmFzZS5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjaXBoZXJQYXJhbXMgQW4gb2JqZWN0IHdpdGggYW55IG9mIHRoZSBwb3NzaWJsZSBjaXBoZXIgcGFyYW1ldGVycy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlclBhcmFtcyA9IENyeXB0b0pTLmxpYi5DaXBoZXJQYXJhbXMuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIGNpcGhlcnRleHQ6IGNpcGhlcnRleHRXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBrZXk6IGtleVdvcmRBcnJheSxcblx0ICAgICAgICAgKiAgICAgICAgIGl2OiBpdldvcmRBcnJheSxcblx0ICAgICAgICAgKiAgICAgICAgIHNhbHQ6IHNhbHRXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBhbGdvcml0aG06IENyeXB0b0pTLmFsZ28uQUVTLFxuXHQgICAgICAgICAqICAgICAgICAgbW9kZTogQ3J5cHRvSlMubW9kZS5DQkMsXG5cdCAgICAgICAgICogICAgICAgICBwYWRkaW5nOiBDcnlwdG9KUy5wYWQuUEtDUzcsXG5cdCAgICAgICAgICogICAgICAgICBibG9ja1NpemU6IDQsXG5cdCAgICAgICAgICogICAgICAgICBmb3JtYXR0ZXI6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMXG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjaXBoZXJQYXJhbXMpIHtcblx0ICAgICAgICAgICAgdGhpcy5taXhJbihjaXBoZXJQYXJhbXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtGb3JtYXR9IGZvcm1hdHRlciAoT3B0aW9uYWwpIFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIHVzZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIGNpcGhlciBwYXJhbXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAdGhyb3dzIEVycm9yIElmIG5laXRoZXIgdGhlIGZvcm1hdHRlciBub3IgdGhlIGRlZmF1bHQgZm9ybWF0dGVyIGlzIHNldC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IGNpcGhlclBhcmFtcyArICcnO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zLnRvU3RyaW5nKCk7XG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSBjaXBoZXJQYXJhbXMudG9TdHJpbmcoQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRvU3RyaW5nOiBmdW5jdGlvbiAoZm9ybWF0dGVyKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAoZm9ybWF0dGVyIHx8IHRoaXMuZm9ybWF0dGVyKS5zdHJpbmdpZnkodGhpcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogRm9ybWF0IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZm9ybWF0ID0gQy5mb3JtYXQgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBPcGVuU1NMIGZvcm1hdHRpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBPcGVuU1NMRm9ybWF0dGVyID0gQ19mb3JtYXQuT3BlblNTTCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc30gY2lwaGVyUGFyYW1zIFRoZSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBvcGVuU1NMU3RyaW5nID0gQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wuc3RyaW5naWZ5KGNpcGhlclBhcmFtcyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IGNpcGhlclBhcmFtcy5jaXBoZXJ0ZXh0O1xuXHQgICAgICAgICAgICB2YXIgc2FsdCA9IGNpcGhlclBhcmFtcy5zYWx0O1xuXG5cdCAgICAgICAgICAgIC8vIEZvcm1hdFxuXHQgICAgICAgICAgICBpZiAoc2FsdCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheSA9IFdvcmRBcnJheS5jcmVhdGUoWzB4NTM2MTZjNzQsIDB4NjU2NDVmNWZdKS5jb25jYXQoc2FsdCkuY29uY2F0KGNpcGhlcnRleHQpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheSA9IGNpcGhlcnRleHQ7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gd29yZEFycmF5LnRvU3RyaW5nKEJhc2U2NCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcgdG8gYSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVuU1NMU3RyIFRoZSBPcGVuU1NMLWNvbXBhdGlibGUgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgY2lwaGVyIHBhcmFtcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJQYXJhbXMgPSBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTC5wYXJzZShvcGVuU1NMU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKG9wZW5TU0xTdHIpIHtcblx0ICAgICAgICAgICAgLy8gUGFyc2UgYmFzZTY0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0ID0gQmFzZTY0LnBhcnNlKG9wZW5TU0xTdHIpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0V29yZHMgPSBjaXBoZXJ0ZXh0LndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFRlc3QgZm9yIHNhbHRcblx0ICAgICAgICAgICAgaWYgKGNpcGhlcnRleHRXb3Jkc1swXSA9PSAweDUzNjE2Yzc0ICYmIGNpcGhlcnRleHRXb3Jkc1sxXSA9PSAweDY1NjQ1ZjVmKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IHNhbHRcblx0ICAgICAgICAgICAgICAgIHZhciBzYWx0ID0gV29yZEFycmF5LmNyZWF0ZShjaXBoZXJ0ZXh0V29yZHMuc2xpY2UoMiwgNCkpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgc2FsdCBmcm9tIGNpcGhlcnRleHRcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHRXb3Jkcy5zcGxpY2UoMCwgNCk7XG5cdCAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0LnNpZ0J5dGVzIC09IDE2O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoeyBjaXBoZXJ0ZXh0OiBjaXBoZXJ0ZXh0LCBzYWx0OiBzYWx0IH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQSBjaXBoZXIgd3JhcHBlciB0aGF0IHJldHVybnMgY2lwaGVydGV4dCBhcyBhIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAqL1xuXHQgICAgdmFyIFNlcmlhbGl6YWJsZUNpcGhlciA9IENfbGliLlNlcmlhbGl6YWJsZUNpcGhlciA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0Zvcm1hdHRlcn0gZm9ybWF0IFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIGNvbnZlcnQgY2lwaGVyIHBhcmFtIG9iamVjdHMgdG8gYW5kIGZyb20gYSBzdHJpbmcuIERlZmF1bHQ6IE9wZW5TU0xcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjZmc6IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgZm9ybWF0OiBPcGVuU1NMRm9ybWF0dGVyXG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBFbmNyeXB0cyBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gZW5jcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gQSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuU2VyaWFsaXphYmxlQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsIGtleSk7XG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBtZXNzYWdlLCBrZXksIHsgaXY6IGl2IH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5TZXJpYWxpemFibGVDaXBoZXIuZW5jcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgbWVzc2FnZSwga2V5LCB7IGl2OiBpdiwgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgZW5jcnlwdG9yID0gY2lwaGVyLmNyZWF0ZUVuY3J5cHRvcihrZXksIGNmZyk7XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0ID0gZW5jcnlwdG9yLmZpbmFsaXplKG1lc3NhZ2UpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJDZmcgPSBlbmNyeXB0b3IuY2ZnO1xuXG5cdCAgICAgICAgICAgIC8vIENyZWF0ZSBhbmQgcmV0dXJuIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zXG5cdCAgICAgICAgICAgIHJldHVybiBDaXBoZXJQYXJhbXMuY3JlYXRlKHtcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHQ6IGNpcGhlcnRleHQsXG5cdCAgICAgICAgICAgICAgICBrZXk6IGtleSxcblx0ICAgICAgICAgICAgICAgIGl2OiBjaXBoZXJDZmcuaXYsXG5cdCAgICAgICAgICAgICAgICBhbGdvcml0aG06IGNpcGhlcixcblx0ICAgICAgICAgICAgICAgIG1vZGU6IGNpcGhlckNmZy5tb2RlLFxuXHQgICAgICAgICAgICAgICAgcGFkZGluZzogY2lwaGVyQ2ZnLnBhZGRpbmcsXG5cdCAgICAgICAgICAgICAgICBibG9ja1NpemU6IGNpcGhlci5ibG9ja1NpemUsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IGNmZy5mb3JtYXRcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlY3J5cHRzIHNlcmlhbGl6ZWQgY2lwaGVydGV4dC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfHN0cmluZ30gY2lwaGVydGV4dCBUaGUgY2lwaGVydGV4dCB0byBkZWNyeXB0LlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcGxhaW50ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0IHN0cmluZyB0byBDaXBoZXJQYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dCA9IHRoaXMuX3BhcnNlKGNpcGhlcnRleHQsIGNmZy5mb3JtYXQpO1xuXG5cdCAgICAgICAgICAgIC8vIERlY3J5cHRcblx0ICAgICAgICAgICAgdmFyIHBsYWludGV4dCA9IGNpcGhlci5jcmVhdGVEZWNyeXB0b3Ioa2V5LCBjZmcpLmZpbmFsaXplKGNpcGhlcnRleHQuY2lwaGVydGV4dCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHRvIENpcGhlclBhcmFtcyxcblx0ICAgICAgICAgKiBlbHNlIGFzc3VtZWQgQ2lwaGVyUGFyYW1zIGFscmVhZHkgYW5kIHJldHVybnMgY2lwaGVydGV4dCB1bmNoYW5nZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtGb3JtYXR0ZXJ9IGZvcm1hdCBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byB1c2UgdG8gcGFyc2Ugc2VyaWFsaXplZCBjaXBoZXJ0ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgdW5zZXJpYWxpemVkIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5fcGFyc2UoY2lwaGVydGV4dFN0cmluZ09yUGFyYW1zLCBmb3JtYXQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wYXJzZTogZnVuY3Rpb24gKGNpcGhlcnRleHQsIGZvcm1hdCkge1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXQucGFyc2UoY2lwaGVydGV4dCwgdGhpcyk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfa2RmID0gQy5rZGYgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBPcGVuU1NMIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uLlxuXHQgICAgICovXG5cdCAgICB2YXIgT3BlblNTTEtkZiA9IENfa2RmLk9wZW5TU0wgPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVyaXZlcyBhIGtleSBhbmQgSVYgZnJvbSBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZCB0byBkZXJpdmUgZnJvbS5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0ga2V5U2l6ZSBUaGUgc2l6ZSBpbiB3b3JkcyBvZiB0aGUga2V5IHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpdlNpemUgVGhlIHNpemUgaW4gd29yZHMgb2YgdGhlIElWIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gc2FsdCAoT3B0aW9uYWwpIEEgNjQtYml0IHNhbHQgdG8gdXNlLiBJZiBvbWl0dGVkLCBhIHNhbHQgd2lsbCBiZSBnZW5lcmF0ZWQgcmFuZG9tbHkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IEEgY2lwaGVyIHBhcmFtcyBvYmplY3Qgd2l0aCB0aGUga2V5LCBJViwgYW5kIHNhbHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMik7XG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMiwgJ3NhbHRzYWx0Jyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZXhlY3V0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBrZXlTaXplLCBpdlNpemUsIHNhbHQpIHtcblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUgcmFuZG9tIHNhbHRcblx0ICAgICAgICAgICAgaWYgKCFzYWx0KSB7XG5cdCAgICAgICAgICAgICAgICBzYWx0ID0gV29yZEFycmF5LnJhbmRvbSg2NC84KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIERlcml2ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBrZXkgPSBFdnBLREYuY3JlYXRlKHsga2V5U2l6ZToga2V5U2l6ZSArIGl2U2l6ZSB9KS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTtcblxuXHQgICAgICAgICAgICAvLyBTZXBhcmF0ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBpdiA9IFdvcmRBcnJheS5jcmVhdGUoa2V5LndvcmRzLnNsaWNlKGtleVNpemUpLCBpdlNpemUgKiA0KTtcblx0ICAgICAgICAgICAga2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gUmV0dXJuIHBhcmFtc1xuXHQgICAgICAgICAgICByZXR1cm4gQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7IGtleToga2V5LCBpdjogaXYsIHNhbHQ6IHNhbHQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBIHNlcmlhbGl6YWJsZSBjaXBoZXIgd3JhcHBlciB0aGF0IGRlcml2ZXMgdGhlIGtleSBmcm9tIGEgcGFzc3dvcmQsXG5cdCAgICAgKiBhbmQgcmV0dXJucyBjaXBoZXJ0ZXh0IGFzIGEgc2VyaWFsaXphYmxlIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICovXG5cdCAgICB2YXIgUGFzc3dvcmRCYXNlZENpcGhlciA9IENfbGliLlBhc3N3b3JkQmFzZWRDaXBoZXIgPSBTZXJpYWxpemFibGVDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0tERn0ga2RmIFRoZSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbiB0byB1c2UgdG8gZ2VuZXJhdGUgYSBrZXkgYW5kIElWIGZyb20gYSBwYXNzd29yZC4gRGVmYXVsdDogT3BlblNTTFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogU2VyaWFsaXphYmxlQ2lwaGVyLmNmZy5leHRlbmQoe1xuXHQgICAgICAgICAgICBrZGY6IE9wZW5TU0xLZGZcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEVuY3J5cHRzIGEgbWVzc2FnZSB1c2luZyBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBUaGUgY2lwaGVyIGFsZ29yaXRobSB0byB1c2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGVuY3J5cHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBBIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcpO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcsIHsgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBwYXNzd29yZCwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplKTtcblxuXHQgICAgICAgICAgICAvLyBBZGQgSVYgdG8gY29uZmlnXG5cdCAgICAgICAgICAgIGNmZy5pdiA9IGRlcml2ZWRQYXJhbXMuaXY7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IFNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0LmNhbGwodGhpcywgY2lwaGVyLCBtZXNzYWdlLCBkZXJpdmVkUGFyYW1zLmtleSwgY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBNaXggaW4gZGVyaXZlZCBwYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dC5taXhJbihkZXJpdmVkUGFyYW1zKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVjcnlwdHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHVzaW5nIGEgcGFzc3dvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQgdG8gZGVjcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmQgVGhlIHBhc3N3b3JkLlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwbGFpbnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZGVjcnlwdDogZnVuY3Rpb24gKGNpcGhlciwgY2lwaGVydGV4dCwgcGFzc3dvcmQsIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gQ2lwaGVyUGFyYW1zXG5cdCAgICAgICAgICAgIGNpcGhlcnRleHQgPSB0aGlzLl9wYXJzZShjaXBoZXJ0ZXh0LCBjZmcuZm9ybWF0KTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplLCBjaXBoZXJ0ZXh0LnNhbHQpO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBJViB0byBjb25maWdcblx0ICAgICAgICAgICAgY2ZnLml2ID0gZGVyaXZlZFBhcmFtcy5pdjtcblxuXHQgICAgICAgICAgICAvLyBEZWNyeXB0XG5cdCAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBTZXJpYWxpemFibGVDaXBoZXIuZGVjcnlwdC5jYWxsKHRoaXMsIGNpcGhlciwgY2lwaGVydGV4dCwgZGVyaXZlZFBhcmFtcy5rZXksIGNmZyk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0fSgpKTtcblxuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdHJvb3QuQ3J5cHRvSlMgPSBmYWN0b3J5KCk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuXG5cdC8qKlxuXHQgKiBDcnlwdG9KUyBjb3JlIGNvbXBvbmVudHMuXG5cdCAqL1xuXHR2YXIgQ3J5cHRvSlMgPSBDcnlwdG9KUyB8fCAoZnVuY3Rpb24gKE1hdGgsIHVuZGVmaW5lZCkge1xuXHQgICAgLypcblx0ICAgICAqIExvY2FsIHBvbHlmaWwgb2YgT2JqZWN0LmNyZWF0ZVxuXHQgICAgICovXG5cdCAgICB2YXIgY3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGZ1bmN0aW9uIEYoKSB7fTtcblxuXHQgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7XG5cdCAgICAgICAgICAgIHZhciBzdWJ0eXBlO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gb2JqO1xuXG5cdCAgICAgICAgICAgIHN1YnR5cGUgPSBuZXcgRigpO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gbnVsbDtcblxuXHQgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICB9O1xuXHQgICAgfSgpKVxuXG5cdCAgICAvKipcblx0ICAgICAqIENyeXB0b0pTIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBMaWJyYXJ5IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfbGliID0gQy5saWIgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBCYXNlIG9iamVjdCBmb3IgcHJvdG90eXBhbCBpbmhlcml0YW5jZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlID0gKGZ1bmN0aW9uICgpIHtcblxuXG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGlzIG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG92ZXJyaWRlcyBQcm9wZXJ0aWVzIHRvIGNvcHkgaW50byB0aGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiAgICAgdmFyIE15VHlwZSA9IENyeXB0b0pTLmxpYi5CYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgZmllbGQ6ICd2YWx1ZScsXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgfVxuXHQgICAgICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBleHRlbmQ6IGZ1bmN0aW9uIChvdmVycmlkZXMpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNwYXduXG5cdCAgICAgICAgICAgICAgICB2YXIgc3VidHlwZSA9IGNyZWF0ZSh0aGlzKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gQXVnbWVudFxuXHQgICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlcykge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1YnR5cGUubWl4SW4ob3ZlcnJpZGVzKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGRlZmF1bHQgaW5pdGlhbGl6ZXJcblx0ICAgICAgICAgICAgICAgIGlmICghc3VidHlwZS5oYXNPd25Qcm9wZXJ0eSgnaW5pdCcpIHx8IHRoaXMuaW5pdCA9PT0gc3VidHlwZS5pbml0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgc3VidHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlci5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZXIncyBwcm90b3R5cGUgaXMgdGhlIHN1YnR5cGUgb2JqZWN0XG5cdCAgICAgICAgICAgICAgICBzdWJ0eXBlLmluaXQucHJvdG90eXBlID0gc3VidHlwZTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVmZXJlbmNlIHN1cGVydHlwZVxuXHQgICAgICAgICAgICAgICAgc3VidHlwZS4kc3VwZXIgPSB0aGlzO1xuXG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogRXh0ZW5kcyB0aGlzIG9iamVjdCBhbmQgcnVucyB0aGUgaW5pdCBtZXRob2QuXG5cdCAgICAgICAgICAgICAqIEFyZ3VtZW50cyB0byBjcmVhdGUoKSB3aWxsIGJlIHBhc3NlZCB0byBpbml0KCkuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIG5ldyBvYmplY3QuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBpbnN0YW5jZSA9IE15VHlwZS5jcmVhdGUoKTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gdGhpcy5leHRlbmQoKTtcblx0ICAgICAgICAgICAgICAgIGluc3RhbmNlLmluaXQuYXBwbHkoaW5zdGFuY2UsIGFyZ3VtZW50cyk7XG5cblx0ICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG9iamVjdC5cblx0ICAgICAgICAgICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gYWRkIHNvbWUgbG9naWMgd2hlbiB5b3VyIG9iamVjdHMgYXJlIGNyZWF0ZWQuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICB2YXIgTXlUeXBlID0gQ3J5cHRvSlMubGliLkJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgICogICAgICAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgICAgIC8vIC4uLlxuXHQgICAgICAgICAgICAgKiAgICAgICAgIH1cblx0ICAgICAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB9LFxuXG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBDb3BpZXMgcHJvcGVydGllcyBpbnRvIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBUaGUgcHJvcGVydGllcyB0byBtaXggaW4uXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBNeVR5cGUubWl4SW4oe1xuXHQgICAgICAgICAgICAgKiAgICAgICAgIGZpZWxkOiAndmFsdWUnXG5cdCAgICAgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIG1peEluOiBmdW5jdGlvbiAocHJvcGVydGllcykge1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcGVydHlOYW1lIGluIHByb3BlcnRpZXMpIHtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcHJvcGVydHlOYW1lXSA9IHByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIC8vIElFIHdvbid0IGNvcHkgdG9TdHJpbmcgdXNpbmcgdGhlIGxvb3AgYWJvdmVcblx0ICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KCd0b1N0cmluZycpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy50b1N0cmluZyA9IHByb3BlcnRpZXMudG9TdHJpbmc7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0sXG5cblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IGluc3RhbmNlLmNsb25lKCk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5pdC5wcm90b3R5cGUuZXh0ZW5kKHRoaXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH0oKSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiAzMi1iaXQgd29yZHMuXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gc2lnQnl0ZXMgVGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBieXRlcyBpbiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgKi9cblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyAoT3B0aW9uYWwpIEFuIGFycmF5IG9mIDMyLWJpdCB3b3Jkcy5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gc2lnQnl0ZXMgKE9wdGlvbmFsKSBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoZSB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKCk7XG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbMHgwMDAxMDIwMywgMHgwNDA1MDYwN10pO1xuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoWzB4MDAwMTAyMDMsIDB4MDQwNTA2MDddLCA2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAod29yZHMsIHNpZ0J5dGVzKSB7XG5cdCAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdO1xuXG5cdCAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSBzaWdCeXRlcztcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSB3b3Jkcy5sZW5ndGggKiA0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIHRoaXMgd29yZCBhcnJheSB0byBhIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlciAoT3B0aW9uYWwpIFRoZSBlbmNvZGluZyBzdHJhdGVneSB0byB1c2UuIERlZmF1bHQ6IENyeXB0b0pTLmVuYy5IZXhcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkgKyAnJztcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IHdvcmRBcnJheS50b1N0cmluZygpO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gd29yZEFycmF5LnRvU3RyaW5nKENyeXB0b0pTLmVuYy5VdGY4KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0b1N0cmluZzogZnVuY3Rpb24gKGVuY29kZXIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIChlbmNvZGVyIHx8IEhleCkuc3RyaW5naWZ5KHRoaXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25jYXRlbmF0ZXMgYSB3b3JkIGFycmF5IHRvIHRoaXMgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheTEuY29uY2F0KHdvcmRBcnJheTIpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbmNhdDogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHRoaXNXb3JkcyA9IHRoaXMud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGF0V29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGlzU2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXHQgICAgICAgICAgICB2YXIgdGhhdFNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzXG5cdCAgICAgICAgICAgIHRoaXMuY2xhbXAoKTtcblxuXHQgICAgICAgICAgICAvLyBDb25jYXRcblx0ICAgICAgICAgICAgaWYgKHRoaXNTaWdCeXRlcyAlIDQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIENvcHkgb25lIGJ5dGUgYXQgYSB0aW1lXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoYXRTaWdCeXRlczsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHRoYXRCeXRlID0gKHRoYXRXb3Jkc1tpID4+PiAyXSA+Pj4gKDI0IC0gKGkgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpc1dvcmRzWyh0aGlzU2lnQnl0ZXMgKyBpKSA+Pj4gMl0gfD0gdGhhdEJ5dGUgPDwgKDI0IC0gKCh0aGlzU2lnQnl0ZXMgKyBpKSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBDb3B5IG9uZSB3b3JkIGF0IGEgdGltZVxuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGF0U2lnQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXNXb3Jkc1sodGhpc1NpZ0J5dGVzICsgaSkgPj4+IDJdID0gdGhhdFdvcmRzW2kgPj4+IDJdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgKz0gdGhhdFNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVtb3ZlcyBpbnNpZ25pZmljYW50IGJpdHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheS5jbGFtcCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsYW1wOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB0aGlzLndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wXG5cdCAgICAgICAgICAgIHdvcmRzW3NpZ0J5dGVzID4+PiAyXSAmPSAweGZmZmZmZmZmIDw8ICgzMiAtIChzaWdCeXRlcyAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIHdvcmRzLmxlbmd0aCA9IE1hdGguY2VpbChzaWdCeXRlcyAvIDQpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gd29yZEFycmF5LmNsb25lKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gQmFzZS5jbG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICBjbG9uZS53b3JkcyA9IHRoaXMud29yZHMuc2xpY2UoMCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgd29yZCBhcnJheSBmaWxsZWQgd2l0aCByYW5kb20gYnl0ZXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbkJ5dGVzIFRoZSBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcmFuZG9tIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSgxNik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcmFuZG9tOiBmdW5jdGlvbiAobkJ5dGVzKSB7XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXG5cdCAgICAgICAgICAgIHZhciByID0gKGZ1bmN0aW9uIChtX3cpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBtX3cgPSBtX3c7XG5cdCAgICAgICAgICAgICAgICB2YXIgbV96ID0gMHgzYWRlNjhiMTtcblx0ICAgICAgICAgICAgICAgIHZhciBtYXNrID0gMHhmZmZmZmZmZjtcblxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgICAgICBtX3ogPSAoMHg5MDY5ICogKG1feiAmIDB4RkZGRikgKyAobV96ID4+IDB4MTApKSAmIG1hc2s7XG5cdCAgICAgICAgICAgICAgICAgICAgbV93ID0gKDB4NDY1MCAqIChtX3cgJiAweEZGRkYpICsgKG1fdyA+PiAweDEwKSkgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSAoKG1feiA8PCAweDEwKSArIG1fdykgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAvPSAweDEwMDAwMDAwMDtcblx0ICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gMC41O1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgKiAoTWF0aC5yYW5kb20oKSA+IC41ID8gMSA6IC0xKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIHJjYWNoZTsgaSA8IG5CeXRlczsgaSArPSA0KSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgX3IgPSByKChyY2FjaGUgfHwgTWF0aC5yYW5kb20oKSkgKiAweDEwMDAwMDAwMCk7XG5cblx0ICAgICAgICAgICAgICAgIHJjYWNoZSA9IF9yKCkgKiAweDNhZGU2N2I3O1xuXHQgICAgICAgICAgICAgICAgd29yZHMucHVzaCgoX3IoKSAqIDB4MTAwMDAwMDAwKSB8IDApO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBXb3JkQXJyYXkuaW5pdCh3b3JkcywgbkJ5dGVzKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBFbmNvZGVyIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZW5jID0gQy5lbmMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBIZXggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBIZXggPSBDX2VuYy5IZXggPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBoZXggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGV4U3RyaW5nID0gQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IHdvcmRBcnJheS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgdmFyIGhleENoYXJzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJpdGUgPSAod29yZHNbaSA+Pj4gMl0gPj4+ICgyNCAtIChpICUgNCkgKiA4KSkgJiAweGZmO1xuXHQgICAgICAgICAgICAgICAgaGV4Q2hhcnMucHVzaCgoYml0ZSA+Pj4gNCkudG9TdHJpbmcoMTYpKTtcblx0ICAgICAgICAgICAgICAgIGhleENoYXJzLnB1c2goKGJpdGUgJiAweDBmKS50b1N0cmluZygxNikpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhleENoYXJzLmpvaW4oJycpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGhleFN0ciBUaGUgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGhleFN0cmluZyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChoZXhTdHIpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhleFN0ckxlbmd0aCA9IGhleFN0ci5sZW5ndGg7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXhTdHJMZW5ndGg7IGkgKz0gMikge1xuXHQgICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gM10gfD0gcGFyc2VJbnQoaGV4U3RyLnN1YnN0cihpLCAyKSwgMTYpIDw8ICgyNCAtIChpICUgOCkgKiA0KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQod29yZHMsIGhleFN0ckxlbmd0aCAvIDIpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogTGF0aW4xIGVuY29kaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgTGF0aW4xID0gQ19lbmMuTGF0aW4xID0ge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIExhdGluMSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgTGF0aW4xIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGxhdGluMVN0cmluZyA9IENyeXB0b0pTLmVuYy5MYXRpbjEuc3RyaW5naWZ5KHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlcztcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciBsYXRpbjFDaGFycyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBiaXRlID0gKHdvcmRzW2kgPj4+IDJdID4+PiAoMjQgLSAoaSAlIDQpICogOCkpICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIGxhdGluMUNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShiaXRlKSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbGF0aW4xQ2hhcnMuam9pbignJyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgTGF0aW4xIHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF0aW4xU3RyIFRoZSBMYXRpbjEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5MYXRpbjEucGFyc2UobGF0aW4xU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKGxhdGluMVN0cikge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgbGF0aW4xU3RyTGVuZ3RoID0gbGF0aW4xU3RyLmxlbmd0aDtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhdGluMVN0ckxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAyXSB8PSAobGF0aW4xU3RyLmNoYXJDb2RlQXQoaSkgJiAweGZmKSA8PCAoMjQgLSAoaSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBsYXRpbjFTdHJMZW5ndGgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogVVRGLTggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmOCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBVVEYtOCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgdXRmOFN0cmluZyA9IENyeXB0b0pTLmVuYy5VdGY4LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUoTGF0aW4xLnN0cmluZ2lmeSh3b3JkQXJyYXkpKSk7XG5cdCAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWFsZm9ybWVkIFVURi04IGRhdGEnKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi04IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXRmOFN0ciBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5VdGY4LnBhcnNlKHV0ZjhTdHJpbmcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmOFN0cikge1xuXHQgICAgICAgICAgICByZXR1cm4gTGF0aW4xLnBhcnNlKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudCh1dGY4U3RyKSkpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYnVmZmVyZWQgYmxvY2sgYWxnb3JpdGhtIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIFRoZSBwcm9wZXJ0eSBibG9ja1NpemUgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiBhIGNvbmNyZXRlIHN1YnR5cGUuXG5cdCAgICAgKlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9taW5CdWZmZXJTaXplIFRoZSBudW1iZXIgb2YgYmxvY2tzIHRoYXQgc2hvdWxkIGJlIGtlcHQgdW5wcm9jZXNzZWQgaW4gdGhlIGJ1ZmZlci4gRGVmYXVsdDogMFxuXHQgICAgICovXG5cdCAgICB2YXIgQnVmZmVyZWRCbG9ja0FsZ29yaXRobSA9IENfbGliLkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVzZXRzIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgZGF0YSBidWZmZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLl9kYXRhID0gbmV3IFdvcmRBcnJheS5pbml0KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX25EYXRhQnl0ZXMgPSAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBZGRzIG5ldyBkYXRhIHRvIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgYnVmZmVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGFwcGVuZC4gU3RyaW5ncyBhcmUgY29udmVydGVkIHRvIGEgV29yZEFycmF5IHVzaW5nIFVURi04LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9hcHBlbmQoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fYXBwZW5kKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2FwcGVuZDogZnVuY3Rpb24gKGRhdGEpIHtcblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIGRhdGEgPSBVdGY4LnBhcnNlKGRhdGEpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQXBwZW5kXG5cdCAgICAgICAgICAgIHRoaXMuX2RhdGEuY29uY2F0KGRhdGEpO1xuXHQgICAgICAgICAgICB0aGlzLl9uRGF0YUJ5dGVzICs9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFByb2Nlc3NlcyBhdmFpbGFibGUgZGF0YSBibG9ja3MuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIF9kb1Byb2Nlc3NCbG9jayhvZmZzZXQpLCB3aGljaCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGEgY29uY3JldGUgc3VidHlwZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9GbHVzaCBXaGV0aGVyIGFsbCBibG9ja3MgYW5kIHBhcnRpYWwgYmxvY2tzIHNob3VsZCBiZSBwcm9jZXNzZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwcm9jZXNzZWQgZGF0YS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHByb2Nlc3NlZERhdGEgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9wcm9jZXNzKCk7XG5cdCAgICAgICAgICogICAgIHZhciBwcm9jZXNzZWREYXRhID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fcHJvY2VzcyghISdmbHVzaCcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wcm9jZXNzOiBmdW5jdGlvbiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIGRhdGFTaWdCeXRlcyA9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSB0aGlzLmJsb2NrU2l6ZTtcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBibG9ja3MgcmVhZHlcblx0ICAgICAgICAgICAgdmFyIG5CbG9ja3NSZWFkeSA9IGRhdGFTaWdCeXRlcyAvIGJsb2NrU2l6ZUJ5dGVzO1xuXHQgICAgICAgICAgICBpZiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAgICAgLy8gUm91bmQgdXAgdG8gaW5jbHVkZSBwYXJ0aWFsIGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgbkJsb2Nrc1JlYWR5ID0gTWF0aC5jZWlsKG5CbG9ja3NSZWFkeSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBSb3VuZCBkb3duIHRvIGluY2x1ZGUgb25seSBmdWxsIGJsb2Nrcyxcblx0ICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhlIG51bWJlciBvZiBibG9ja3MgdGhhdCBtdXN0IHJlbWFpbiBpbiB0aGUgYnVmZmVyXG5cdCAgICAgICAgICAgICAgICBuQmxvY2tzUmVhZHkgPSBNYXRoLm1heCgobkJsb2Nrc1JlYWR5IHwgMCkgLSB0aGlzLl9taW5CdWZmZXJTaXplLCAwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIENvdW50IHdvcmRzIHJlYWR5XG5cdCAgICAgICAgICAgIHZhciBuV29yZHNSZWFkeSA9IG5CbG9ja3NSZWFkeSAqIGJsb2NrU2l6ZTtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBieXRlcyByZWFkeVxuXHQgICAgICAgICAgICB2YXIgbkJ5dGVzUmVhZHkgPSBNYXRoLm1pbihuV29yZHNSZWFkeSAqIDQsIGRhdGFTaWdCeXRlcyk7XG5cblx0ICAgICAgICAgICAgLy8gUHJvY2VzcyBibG9ja3Ncblx0ICAgICAgICAgICAgaWYgKG5Xb3Jkc1JlYWR5KSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBvZmZzZXQgPSAwOyBvZmZzZXQgPCBuV29yZHNSZWFkeTsgb2Zmc2V0ICs9IGJsb2NrU2l6ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtYWxnb3JpdGhtIGxvZ2ljXG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fZG9Qcm9jZXNzQmxvY2soZGF0YVdvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgICAgICB2YXIgcHJvY2Vzc2VkV29yZHMgPSBkYXRhV29yZHMuc3BsaWNlKDAsIG5Xb3Jkc1JlYWR5KTtcblx0ICAgICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgLT0gbkJ5dGVzUmVhZHk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQocHJvY2Vzc2VkV29yZHMsIG5CeXRlc1JlYWR5KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5jbG9uZSgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBjbG9uZSA9IEJhc2UuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2RhdGEgPSB0aGlzLl9kYXRhLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfbWluQnVmZmVyU2l6ZTogMFxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgaGFzaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBoYXNoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDE2ICg1MTIgYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBoYXNoIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaGVyID0gQ3J5cHRvSlMuYWxnby5TSEEyNTYuY3JlYXRlKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgaW5pdDogZnVuY3Rpb24gKGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXNldHMgdGhpcyBoYXNoZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGRhdGEgYnVmZmVyXG5cdCAgICAgICAgICAgIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQuY2FsbCh0aGlzKTtcblxuXHQgICAgICAgICAgICAvLyBQZXJmb3JtIGNvbmNyZXRlLWhhc2hlciBsb2dpY1xuXHQgICAgICAgICAgICB0aGlzLl9kb1Jlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFVwZGF0ZXMgdGhpcyBoYXNoZXIgd2l0aCBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgVGhlIG1lc3NhZ2UgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7SGFzaGVyfSBUaGlzIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICBoYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBBcHBlbmRcblx0ICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgaGFzaFxuXHQgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2hhaW5hYmxlXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIGhhc2ggY29tcHV0YXRpb24uXG5cdCAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSAoT3B0aW9uYWwpIEEgZmluYWwgbWVzc2FnZSB1cGRhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBGaW5hbCBtZXNzYWdlIHVwZGF0ZVxuXHQgICAgICAgICAgICBpZiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1oYXNoZXIgbG9naWNcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9kb0ZpbmFsaXplKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhhc2g7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogNTEyLzMyLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIHNob3J0Y3V0IGZ1bmN0aW9uIHRvIGEgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7SGFzaGVyfSBoYXNoZXIgVGhlIGhhc2hlciB0byBjcmVhdGUgYSBoZWxwZXIgZm9yLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIFNIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhlbHBlcihDcnlwdG9KUy5hbGdvLlNIQTI1Nik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2NyZWF0ZUhlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGNmZykge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBoYXNoZXIuaW5pdChjZmcpLmZpbmFsaXplKG1lc3NhZ2UpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgc2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZSBpbiB0aGlzIEhNQUMgaGVscGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIEhtYWNTSEEyNTYgPSBDcnlwdG9KUy5saWIuSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKENyeXB0b0pTLmFsZ28uU0hBMjU2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBfY3JlYXRlSG1hY0hlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGtleSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDX2FsZ28uSE1BQy5pbml0KGhhc2hlciwga2V5KS5maW5hbGl6ZShtZXNzYWdlKTtcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBbGdvcml0aG0gbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvID0ge307XG5cblx0ICAgIHJldHVybiBDO1xuXHR9KE1hdGgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoNDcpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgQ19lbmMgPSBDLmVuYztcblxuXHQgICAgLyoqXG5cdCAgICAgKiBCYXNlNjQgZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBCYXNlNjQgPSBDX2VuYy5CYXNlNjQgPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgQmFzZTY0IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBCYXNlNjQgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgYmFzZTY0U3RyaW5nID0gQ3J5cHRvSlMuZW5jLkJhc2U2NC5zdHJpbmdpZnkod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IHdvcmRBcnJheS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXHQgICAgICAgICAgICB2YXIgbWFwID0gdGhpcy5fbWFwO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzXG5cdCAgICAgICAgICAgIHdvcmRBcnJheS5jbGFtcCgpO1xuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgdmFyIGJhc2U2NENoYXJzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkgKz0gMykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJ5dGUxID0gKHdvcmRzW2kgPj4+IDJdICAgICAgID4+PiAoMjQgLSAoaSAlIDQpICogOCkpICAgICAgICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIHZhciBieXRlMiA9ICh3b3Jkc1soaSArIDEpID4+PiAyXSA+Pj4gKDI0IC0gKChpICsgMSkgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cdCAgICAgICAgICAgICAgICB2YXIgYnl0ZTMgPSAod29yZHNbKGkgKyAyKSA+Pj4gMl0gPj4+ICgyNCAtICgoaSArIDIpICUgNCkgKiA4KSkgJiAweGZmO1xuXG5cdCAgICAgICAgICAgICAgICB2YXIgdHJpcGxldCA9IChieXRlMSA8PCAxNikgfCAoYnl0ZTIgPDwgOCkgfCBieXRlMztcblxuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IChqIDwgNCkgJiYgKGkgKyBqICogMC43NSA8IHNpZ0J5dGVzKTsgaisrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYmFzZTY0Q2hhcnMucHVzaChtYXAuY2hhckF0KCh0cmlwbGV0ID4+PiAoNiAqICgzIC0gaikpKSAmIDB4M2YpKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nQ2hhciA9IG1hcC5jaGFyQXQoNjQpO1xuXHQgICAgICAgICAgICBpZiAocGFkZGluZ0NoYXIpIHtcblx0ICAgICAgICAgICAgICAgIHdoaWxlIChiYXNlNjRDaGFycy5sZW5ndGggJSA0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYmFzZTY0Q2hhcnMucHVzaChwYWRkaW5nQ2hhcik7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gYmFzZTY0Q2hhcnMuam9pbignJyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgQmFzZTY0IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZTY0U3RyIFRoZSBCYXNlNjQgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5CYXNlNjQucGFyc2UoYmFzZTY0U3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKGJhc2U2NFN0cikge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGJhc2U2NFN0ckxlbmd0aCA9IGJhc2U2NFN0ci5sZW5ndGg7XG5cdCAgICAgICAgICAgIHZhciBtYXAgPSB0aGlzLl9tYXA7XG5cdCAgICAgICAgICAgIHZhciByZXZlcnNlTWFwID0gdGhpcy5fcmV2ZXJzZU1hcDtcblxuXHQgICAgICAgICAgICBpZiAoIXJldmVyc2VNYXApIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXZlcnNlTWFwID0gdGhpcy5fcmV2ZXJzZU1hcCA9IFtdO1xuXHQgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWFwLmxlbmd0aDsgaisrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldmVyc2VNYXBbbWFwLmNoYXJDb2RlQXQoaildID0gajtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBJZ25vcmUgcGFkZGluZ1xuXHQgICAgICAgICAgICB2YXIgcGFkZGluZ0NoYXIgPSBtYXAuY2hhckF0KDY0KTtcblx0ICAgICAgICAgICAgaWYgKHBhZGRpbmdDaGFyKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0luZGV4ID0gYmFzZTY0U3RyLmluZGV4T2YocGFkZGluZ0NoYXIpO1xuXHQgICAgICAgICAgICAgICAgaWYgKHBhZGRpbmdJbmRleCAhPT0gLTEpIHtcblx0ICAgICAgICAgICAgICAgICAgICBiYXNlNjRTdHJMZW5ndGggPSBwYWRkaW5nSW5kZXg7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHJldHVybiBwYXJzZUxvb3AoYmFzZTY0U3RyLCBiYXNlNjRTdHJMZW5ndGgsIHJldmVyc2VNYXApO1xuXG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9tYXA6ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPSdcblx0ICAgIH07XG5cblx0ICAgIGZ1bmN0aW9uIHBhcnNlTG9vcChiYXNlNjRTdHIsIGJhc2U2NFN0ckxlbmd0aCwgcmV2ZXJzZU1hcCkge1xuXHQgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgdmFyIG5CeXRlcyA9IDA7XG5cdCAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmFzZTY0U3RyTGVuZ3RoOyBpKyspIHtcblx0ICAgICAgICAgIGlmIChpICUgNCkge1xuXHQgICAgICAgICAgICAgIHZhciBiaXRzMSA9IHJldmVyc2VNYXBbYmFzZTY0U3RyLmNoYXJDb2RlQXQoaSAtIDEpXSA8PCAoKGkgJSA0KSAqIDIpO1xuXHQgICAgICAgICAgICAgIHZhciBiaXRzMiA9IHJldmVyc2VNYXBbYmFzZTY0U3RyLmNoYXJDb2RlQXQoaSldID4+PiAoNiAtIChpICUgNCkgKiAyKTtcblx0ICAgICAgICAgICAgICB3b3Jkc1tuQnl0ZXMgPj4+IDJdIHw9IChiaXRzMSB8IGJpdHMyKSA8PCAoMjQgLSAobkJ5dGVzICUgNCkgKiA4KTtcblx0ICAgICAgICAgICAgICBuQnl0ZXMrKztcblx0ICAgICAgICAgIH1cblx0ICAgICAgfVxuXHQgICAgICByZXR1cm4gV29yZEFycmF5LmNyZWF0ZSh3b3JkcywgbkJ5dGVzKTtcblx0ICAgIH1cblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5lbmMuQmFzZTY0O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSg0NykpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0cmV0dXJuIENyeXB0b0pTLmVuYy5IZXg7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSg0NyksIHJlcXVpcmUoNTMpLCByZXF1aXJlKDUxKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9zaGExXCIsIFwiLi9obWFjXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblx0ICAgIHZhciBNRDUgPSBDX2FsZ28uTUQ1O1xuXG5cdCAgICAvKipcblx0ICAgICAqIFRoaXMga2V5IGRlcml2YXRpb24gZnVuY3Rpb24gaXMgbWVhbnQgdG8gY29uZm9ybSB3aXRoIEVWUF9CeXRlc1RvS2V5LlxuXHQgICAgICogd3d3Lm9wZW5zc2wub3JnL2RvY3MvY3J5cHRvL0VWUF9CeXRlc1RvS2V5Lmh0bWxcblx0ICAgICAqL1xuXHQgICAgdmFyIEV2cEtERiA9IENfYWxnby5FdnBLREYgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGtleVNpemUgVGhlIGtleSBzaXplIGluIHdvcmRzIHRvIGdlbmVyYXRlLiBEZWZhdWx0OiA0ICgxMjggYml0cylcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuIERlZmF1bHQ6IE1ENVxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpdGVyYXRpb25zIFRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucyB0byBwZXJmb3JtLiBEZWZhdWx0OiAxXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgIGtleVNpemU6IDEyOC8zMixcblx0ICAgICAgICAgICAgaGFzaGVyOiBNRDUsXG5cdCAgICAgICAgICAgIGl0ZXJhdGlvbnM6IDFcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhlIGRlcml2YXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoKTtcblx0ICAgICAgICAgKiAgICAgdmFyIGtkZiA9IENyeXB0b0pTLmFsZ28uRXZwS0RGLmNyZWF0ZSh7IGtleVNpemU6IDggfSk7XG5cdCAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjZmcpIHtcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVyaXZlcyBhIGtleSBmcm9tIGEgcGFzc3dvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBrZXkgPSBrZGYuY29tcHV0ZShwYXNzd29yZCwgc2FsdCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY29tcHV0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjZmcgPSB0aGlzLmNmZztcblxuXHQgICAgICAgICAgICAvLyBJbml0IGhhc2hlclxuXHQgICAgICAgICAgICB2YXIgaGFzaGVyID0gY2ZnLmhhc2hlci5jcmVhdGUoKTtcblxuXHQgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB2YXIgZGVyaXZlZEtleSA9IFdvcmRBcnJheS5jcmVhdGUoKTtcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRLZXlXb3JkcyA9IGRlcml2ZWRLZXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBrZXlTaXplID0gY2ZnLmtleVNpemU7XG5cdCAgICAgICAgICAgIHZhciBpdGVyYXRpb25zID0gY2ZnLml0ZXJhdGlvbnM7XG5cblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUga2V5XG5cdCAgICAgICAgICAgIHdoaWxlIChkZXJpdmVkS2V5V29yZHMubGVuZ3RoIDwga2V5U2l6ZSkge1xuXHQgICAgICAgICAgICAgICAgaWYgKGJsb2NrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaGFzaGVyLnVwZGF0ZShibG9jayk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB2YXIgYmxvY2sgPSBoYXNoZXIudXBkYXRlKHBhc3N3b3JkKS5maW5hbGl6ZShzYWx0KTtcblx0ICAgICAgICAgICAgICAgIGhhc2hlci5yZXNldCgpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBJdGVyYXRpb25zXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGl0ZXJhdGlvbnM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgICAgIGJsb2NrID0gaGFzaGVyLmZpbmFsaXplKGJsb2NrKTtcblx0ICAgICAgICAgICAgICAgICAgICBoYXNoZXIucmVzZXQoKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgZGVyaXZlZEtleS5jb25jYXQoYmxvY2spO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGRlcml2ZWRLZXkuc2lnQnl0ZXMgPSBrZXlTaXplICogNDtcblxuXHQgICAgICAgICAgICByZXR1cm4gZGVyaXZlZEtleTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXJpdmVzIGEga2V5IGZyb20gYSBwYXNzd29yZC5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gc2FsdCBBIHNhbHQuXG5cdCAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgY29tcHV0YXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBrZXkgPSBDcnlwdG9KUy5FdnBLREYocGFzc3dvcmQsIHNhbHQpO1xuXHQgICAgICogICAgIHZhciBrZXkgPSBDcnlwdG9KUy5FdnBLREYocGFzc3dvcmQsIHNhbHQsIHsga2V5U2l6ZTogOCB9KTtcblx0ICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDgsIGl0ZXJhdGlvbnM6IDEwMDAgfSk7XG5cdCAgICAgKi9cblx0ICAgIEMuRXZwS0RGID0gZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0LCBjZmcpIHtcblx0ICAgICAgICByZXR1cm4gRXZwS0RGLmNyZWF0ZShjZmcpLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpO1xuXHQgICAgfTtcblx0fSgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5FdnBLREY7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKDQ3KSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgQ19lbmMgPSBDLmVuYztcblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmODtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8qKlxuXHQgICAgICogSE1BQyBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBITUFDID0gQ19hbGdvLkhNQUMgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIEhNQUMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBobWFjSGFzaGVyID0gQ3J5cHRvSlMuYWxnby5ITUFDLmNyZWF0ZShDcnlwdG9KUy5hbGdvLlNIQTI1Niwga2V5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoaGFzaGVyLCBrZXkpIHtcblx0ICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXJcblx0ICAgICAgICAgICAgaGFzaGVyID0gdGhpcy5faGFzaGVyID0gbmV3IGhhc2hlci5pbml0KCk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGtleSA9PSAnc3RyaW5nJykge1xuXHQgICAgICAgICAgICAgICAga2V5ID0gVXRmOC5wYXJzZShrZXkpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBoYXNoZXJCbG9ja1NpemUgPSBoYXNoZXIuYmxvY2tTaXplO1xuXHQgICAgICAgICAgICB2YXIgaGFzaGVyQmxvY2tTaXplQnl0ZXMgPSBoYXNoZXJCbG9ja1NpemUgKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEFsbG93IGFyYml0cmFyeSBsZW5ndGgga2V5c1xuXHQgICAgICAgICAgICBpZiAoa2V5LnNpZ0J5dGVzID4gaGFzaGVyQmxvY2tTaXplQnl0ZXMpIHtcblx0ICAgICAgICAgICAgICAgIGtleSA9IGhhc2hlci5maW5hbGl6ZShrZXkpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQ2xhbXAgZXhjZXNzIGJpdHNcblx0ICAgICAgICAgICAga2V5LmNsYW1wKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2xvbmUga2V5IGZvciBpbm5lciBhbmQgb3V0ZXIgcGFkc1xuXHQgICAgICAgICAgICB2YXIgb0tleSA9IHRoaXMuX29LZXkgPSBrZXkuY2xvbmUoKTtcblx0ICAgICAgICAgICAgdmFyIGlLZXkgPSB0aGlzLl9pS2V5ID0ga2V5LmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBvS2V5V29yZHMgPSBvS2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgaUtleVdvcmRzID0gaUtleS53b3JkcztcblxuXHQgICAgICAgICAgICAvLyBYT1Iga2V5cyB3aXRoIHBhZCBjb25zdGFudHNcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoZXJCbG9ja1NpemU7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgb0tleVdvcmRzW2ldIF49IDB4NWM1YzVjNWM7XG5cdCAgICAgICAgICAgICAgICBpS2V5V29yZHNbaV0gXj0gMHgzNjM2MzYzNjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBvS2V5LnNpZ0J5dGVzID0gaUtleS5zaWdCeXRlcyA9IGhhc2hlckJsb2NrU2l6ZUJ5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFJlc2V0cyB0aGlzIEhNQUMgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgaGFzaGVyID0gdGhpcy5faGFzaGVyO1xuXG5cdCAgICAgICAgICAgIC8vIFJlc2V0XG5cdCAgICAgICAgICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAgICBoYXNoZXIudXBkYXRlKHRoaXMuX2lLZXkpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBVcGRhdGVzIHRoaXMgSE1BQyB3aXRoIGEgbWVzc2FnZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSBUaGUgbWVzc2FnZSB0byBhcHBlbmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtITUFDfSBUaGlzIEhNQUMgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKCdtZXNzYWdlJyk7XG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoZXIudXBkYXRlKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRmluYWxpemVzIHRoZSBITUFDIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqIE5vdGUgdGhhdCB0aGUgZmluYWxpemUgb3BlcmF0aW9uIGlzIGVmZmVjdGl2ZWx5IGEgZGVzdHJ1Y3RpdmUsIHJlYWQtb25jZSBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgKE9wdGlvbmFsKSBBIGZpbmFsIG1lc3NhZ2UgdXBkYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBobWFjSGFzaGVyLmZpbmFsaXplKCk7XG5cdCAgICAgICAgICogICAgIHZhciBobWFjID0gaG1hY0hhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaG1hYyA9IGhtYWNIYXNoZXIuZmluYWxpemUod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmaW5hbGl6ZTogZnVuY3Rpb24gKG1lc3NhZ2VVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhhc2hlciA9IHRoaXMuX2hhc2hlcjtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIEhNQUNcblx0ICAgICAgICAgICAgdmFyIGlubmVySGFzaCA9IGhhc2hlci5maW5hbGl6ZShtZXNzYWdlVXBkYXRlKTtcblx0ICAgICAgICAgICAgaGFzaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICAgIHZhciBobWFjID0gaGFzaGVyLmZpbmFsaXplKHRoaXMuX29LZXkuY2xvbmUoKS5jb25jYXQoaW5uZXJIYXNoKSk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhtYWM7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdH0oKSk7XG5cblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoNDcpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoTWF0aCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlcjtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8vIENvbnN0YW50cyB0YWJsZVxuXHQgICAgdmFyIFQgPSBbXTtcblxuXHQgICAgLy8gQ29tcHV0ZSBjb25zdGFudHNcblx0ICAgIChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA2NDsgaSsrKSB7XG5cdCAgICAgICAgICAgIFRbaV0gPSAoTWF0aC5hYnMoTWF0aC5zaW4oaSArIDEpKSAqIDB4MTAwMDAwMDAwKSB8IDA7XG5cdCAgICAgICAgfVxuXHQgICAgfSgpKTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBNRDUgaGFzaCBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBNRDUgPSBDX2FsZ28uTUQ1ID0gSGFzaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbXG5cdCAgICAgICAgICAgICAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LFxuXHQgICAgICAgICAgICAgICAgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3NlxuXHQgICAgICAgICAgICBdKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIC8vIFN3YXAgZW5kaWFuXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0X2kgPSBvZmZzZXQgKyBpO1xuXHQgICAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0X2kgPSBNW29mZnNldF9pXTtcblxuXHQgICAgICAgICAgICAgICAgTVtvZmZzZXRfaV0gPSAoXG5cdCAgICAgICAgICAgICAgICAgICAgKCgoTV9vZmZzZXRfaSA8PCA4KSAgfCAoTV9vZmZzZXRfaSA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICAgICAoKChNX29mZnNldF9pIDw8IDI0KSB8IChNX29mZnNldF9pID4+PiA4KSkgICYgMHhmZjAwZmYwMClcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIEggPSB0aGlzLl9oYXNoLndvcmRzO1xuXG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8wICA9IE1bb2Zmc2V0ICsgMF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xICA9IE1bb2Zmc2V0ICsgMV07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8yICA9IE1bb2Zmc2V0ICsgMl07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8zICA9IE1bb2Zmc2V0ICsgM107XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF80ICA9IE1bb2Zmc2V0ICsgNF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF81ICA9IE1bb2Zmc2V0ICsgNV07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF82ICA9IE1bb2Zmc2V0ICsgNl07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF83ICA9IE1bb2Zmc2V0ICsgN107XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF84ICA9IE1bb2Zmc2V0ICsgOF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF85ICA9IE1bb2Zmc2V0ICsgOV07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xMCA9IE1bb2Zmc2V0ICsgMTBdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTEgPSBNW29mZnNldCArIDExXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEyID0gTVtvZmZzZXQgKyAxMl07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xMyA9IE1bb2Zmc2V0ICsgMTNdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTQgPSBNW29mZnNldCArIDE0XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzE1ID0gTVtvZmZzZXQgKyAxNV07XG5cblx0ICAgICAgICAgICAgLy8gV29ya2luZyB2YXJpYWxiZXNcblx0ICAgICAgICAgICAgdmFyIGEgPSBIWzBdO1xuXHQgICAgICAgICAgICB2YXIgYiA9IEhbMV07XG5cdCAgICAgICAgICAgIHZhciBjID0gSFsyXTtcblx0ICAgICAgICAgICAgdmFyIGQgPSBIWzNdO1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGF0aW9uXG5cdCAgICAgICAgICAgIGEgPSBGRihhLCBiLCBjLCBkLCBNX29mZnNldF8wLCAgNywgIFRbMF0pO1xuXHQgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMSwgIDEyLCBUWzFdKTtcblx0ICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzIsICAxNywgVFsyXSk7XG5cdCAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8zLCAgMjIsIFRbM10pO1xuXHQgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfNCwgIDcsICBUWzRdKTtcblx0ICAgICAgICAgICAgZCA9IEZGKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzUsICAxMiwgVFs1XSk7XG5cdCAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF82LCAgMTcsIFRbNl0pO1xuXHQgICAgICAgICAgICBiID0gRkYoYiwgYywgZCwgYSwgTV9vZmZzZXRfNywgIDIyLCBUWzddKTtcblx0ICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzgsICA3LCAgVFs4XSk7XG5cdCAgICAgICAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBNX29mZnNldF85LCAgMTIsIFRbOV0pO1xuXHQgICAgICAgICAgICBjID0gRkYoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTAsIDE3LCBUWzEwXSk7XG5cdCAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8xMSwgMjIsIFRbMTFdKTtcblx0ICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEyLCA3LCAgVFsxMl0pO1xuXHQgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTMsIDEyLCBUWzEzXSk7XG5cdCAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF8xNCwgMTcsIFRbMTRdKTtcblx0ICAgICAgICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzE1LCAyMiwgVFsxNV0pO1xuXG5cdCAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF8xLCAgNSwgIFRbMTZdKTtcblx0ICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzYsICA5LCAgVFsxN10pO1xuXHQgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfMTEsIDE0LCBUWzE4XSk7XG5cdCAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF8wLCAgMjAsIFRbMTldKTtcblx0ICAgICAgICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzUsICA1LCAgVFsyMF0pO1xuXHQgICAgICAgICAgICBkID0gR0coZCwgYSwgYiwgYywgTV9vZmZzZXRfMTAsIDksICBUWzIxXSk7XG5cdCAgICAgICAgICAgIGMgPSBHRyhjLCBkLCBhLCBiLCBNX29mZnNldF8xNSwgMTQsIFRbMjJdKTtcblx0ICAgICAgICAgICAgYiA9IEdHKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzQsICAyMCwgVFsyM10pO1xuXHQgICAgICAgICAgICBhID0gR0coYSwgYiwgYywgZCwgTV9vZmZzZXRfOSwgIDUsICBUWzI0XSk7XG5cdCAgICAgICAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBNX29mZnNldF8xNCwgOSwgIFRbMjVdKTtcblx0ICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzMsICAxNCwgVFsyNl0pO1xuXHQgICAgICAgICAgICBiID0gR0coYiwgYywgZCwgYSwgTV9vZmZzZXRfOCwgIDIwLCBUWzI3XSk7XG5cdCAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF8xMywgNSwgIFRbMjhdKTtcblx0ICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzIsICA5LCAgVFsyOV0pO1xuXHQgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfNywgIDE0LCBUWzMwXSk7XG5cdCAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF8xMiwgMjAsIFRbMzFdKTtcblxuXHQgICAgICAgICAgICBhID0gSEgoYSwgYiwgYywgZCwgTV9vZmZzZXRfNSwgIDQsICBUWzMyXSk7XG5cdCAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF84LCAgMTEsIFRbMzNdKTtcblx0ICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzExLCAxNiwgVFszNF0pO1xuXHQgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfMTQsIDIzLCBUWzM1XSk7XG5cdCAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF8xLCAgNCwgIFRbMzZdKTtcblx0ICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzQsICAxMSwgVFszN10pO1xuXHQgICAgICAgICAgICBjID0gSEgoYywgZCwgYSwgYiwgTV9vZmZzZXRfNywgIDE2LCBUWzM4XSk7XG5cdCAgICAgICAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBNX29mZnNldF8xMCwgMjMsIFRbMzldKTtcblx0ICAgICAgICAgICAgYSA9IEhIKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEzLCA0LCAgVFs0MF0pO1xuXHQgICAgICAgICAgICBkID0gSEgoZCwgYSwgYiwgYywgTV9vZmZzZXRfMCwgIDExLCBUWzQxXSk7XG5cdCAgICAgICAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBNX29mZnNldF8zLCAgMTYsIFRbNDJdKTtcblx0ICAgICAgICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzYsICAyMywgVFs0M10pO1xuXHQgICAgICAgICAgICBhID0gSEgoYSwgYiwgYywgZCwgTV9vZmZzZXRfOSwgIDQsICBUWzQ0XSk7XG5cdCAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF8xMiwgMTEsIFRbNDVdKTtcblx0ICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE1LCAxNiwgVFs0Nl0pO1xuXHQgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfMiwgIDIzLCBUWzQ3XSk7XG5cblx0ICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzAsICA2LCAgVFs0OF0pO1xuXHQgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfNywgIDEwLCBUWzQ5XSk7XG5cdCAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8xNCwgMTUsIFRbNTBdKTtcblx0ICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzUsICAyMSwgVFs1MV0pO1xuXHQgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTIsIDYsICBUWzUyXSk7XG5cdCAgICAgICAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBNX29mZnNldF8zLCAgMTAsIFRbNTNdKTtcblx0ICAgICAgICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzEwLCAxNSwgVFs1NF0pO1xuXHQgICAgICAgICAgICBiID0gSUkoYiwgYywgZCwgYSwgTV9vZmZzZXRfMSwgIDIxLCBUWzU1XSk7XG5cdCAgICAgICAgICAgIGEgPSBJSShhLCBiLCBjLCBkLCBNX29mZnNldF84LCAgNiwgIFRbNTZdKTtcblx0ICAgICAgICAgICAgZCA9IElJKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzE1LCAxMCwgVFs1N10pO1xuXHQgICAgICAgICAgICBjID0gSUkoYywgZCwgYSwgYiwgTV9vZmZzZXRfNiwgIDE1LCBUWzU4XSk7XG5cdCAgICAgICAgICAgIGIgPSBJSShiLCBjLCBkLCBhLCBNX29mZnNldF8xMywgMjEsIFRbNTldKTtcblx0ICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzQsICA2LCAgVFs2MF0pO1xuXHQgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTEsIDEwLCBUWzYxXSk7XG5cdCAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8yLCAgMTUsIFRbNjJdKTtcblx0ICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzksICAyMSwgVFs2M10pO1xuXG5cdCAgICAgICAgICAgIC8vIEludGVybWVkaWF0ZSBoYXNoIHZhbHVlXG5cdCAgICAgICAgICAgIEhbMF0gPSAoSFswXSArIGEpIHwgMDtcblx0ICAgICAgICAgICAgSFsxXSA9IChIWzFdICsgYikgfCAwO1xuXHQgICAgICAgICAgICBIWzJdID0gKEhbMl0gKyBjKSB8IDA7XG5cdCAgICAgICAgICAgIEhbM10gPSAoSFszXSArIGQpIHwgMDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTtcblx0ICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7XG5cblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWwgPSB0aGlzLl9uRGF0YUJ5dGVzICogODtcblx0ICAgICAgICAgICAgdmFyIG5CaXRzTGVmdCA9IGRhdGEuc2lnQnl0ZXMgKiA4O1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1tuQml0c0xlZnQgPj4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbkJpdHNMZWZ0ICUgMzIpO1xuXG5cdCAgICAgICAgICAgIHZhciBuQml0c1RvdGFsSCA9IE1hdGguZmxvb3IobkJpdHNUb3RhbCAvIDB4MTAwMDAwMDAwKTtcblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWxMID0gbkJpdHNUb3RhbDtcblx0ICAgICAgICAgICAgZGF0YVdvcmRzWygoKG5CaXRzTGVmdCArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNV0gPSAoXG5cdCAgICAgICAgICAgICAgICAoKChuQml0c1RvdGFsSCA8PCA4KSAgfCAobkJpdHNUb3RhbEggPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG5cdCAgICAgICAgICAgICAgICAoKChuQml0c1RvdGFsSCA8PCAyNCkgfCAobkJpdHNUb3RhbEggPj4+IDgpKSAgJiAweGZmMDBmZjAwKVxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IChcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxMIDw8IDgpICB8IChuQml0c1RvdGFsTCA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxMIDw8IDI0KSB8IChuQml0c1RvdGFsTCA+Pj4gOCkpICAmIDB4ZmYwMGZmMDApXG5cdCAgICAgICAgICAgICk7XG5cblx0ICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IChkYXRhV29yZHMubGVuZ3RoICsgMSkgKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEhhc2ggZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTtcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoO1xuXHQgICAgICAgICAgICB2YXIgSCA9IGhhc2gud29yZHM7XG5cblx0ICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgICAgICB2YXIgSF9pID0gSFtpXTtcblxuXHQgICAgICAgICAgICAgICAgSFtpXSA9ICgoKEhfaSA8PCA4KSAgfCAoSF9pID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICAgICgoKEhfaSA8PCAyNCkgfCAoSF9pID4+PiA4KSkgICYgMHhmZjAwZmYwMCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaFxuXHQgICAgICAgICAgICByZXR1cm4gaGFzaDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gSGFzaGVyLmNsb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBjbG9uZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgZnVuY3Rpb24gRkYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArICgoYiAmIGMpIHwgKH5iICYgZCkpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gR0coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArICgoYiAmIGQpIHwgKGMgJiB+ZCkpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gSEgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArIChiIF4gYyBeIGQpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgZnVuY3Rpb24gSUkoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuXHQgICAgICAgIHZhciBuID0gYSArIChjIF4gKGIgfCB+ZCkpICsgeCArIHQ7XG5cdCAgICAgICAgcmV0dXJuICgobiA8PCBzKSB8IChuID4+PiAoMzIgLSBzKSkpICsgYjtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLk1ENSgnbWVzc2FnZScpO1xuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuTUQ1KHdvcmRBcnJheSk7XG5cdCAgICAgKi9cblx0ICAgIEMuTUQ1ID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoTUQ1KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNNRDUobWVzc2FnZSwga2V5KTtcblx0ICAgICAqL1xuXHQgICAgQy5IbWFjTUQ1ID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKE1ENSk7XG5cdH0oTWF0aCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLk1ENTtcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoNDcpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyO1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblxuXHQgICAgLy8gUmV1c2FibGUgb2JqZWN0XG5cdCAgICB2YXIgVyA9IFtdO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNIQS0xIGhhc2ggYWxnb3JpdGhtLlxuXHQgICAgICovXG5cdCAgICB2YXIgU0hBMSA9IENfYWxnby5TSEExID0gSGFzaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbXG5cdCAgICAgICAgICAgICAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LFxuXHQgICAgICAgICAgICAgICAgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3Nixcblx0ICAgICAgICAgICAgICAgIDB4YzNkMmUxZjBcblx0ICAgICAgICAgICAgXSk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgSCA9IHRoaXMuX2hhc2gud29yZHM7XG5cblx0ICAgICAgICAgICAgLy8gV29ya2luZyB2YXJpYWJsZXNcblx0ICAgICAgICAgICAgdmFyIGEgPSBIWzBdO1xuXHQgICAgICAgICAgICB2YXIgYiA9IEhbMV07XG5cdCAgICAgICAgICAgIHZhciBjID0gSFsyXTtcblx0ICAgICAgICAgICAgdmFyIGQgPSBIWzNdO1xuXHQgICAgICAgICAgICB2YXIgZSA9IEhbNF07XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0YXRpb25cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4MDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoaSA8IDE2KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgV1tpXSA9IE1bb2Zmc2V0ICsgaV0gfCAwO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgbiA9IFdbaSAtIDNdIF4gV1tpIC0gOF0gXiBXW2kgLSAxNF0gXiBXW2kgLSAxNl07XG5cdCAgICAgICAgICAgICAgICAgICAgV1tpXSA9IChuIDw8IDEpIHwgKG4gPj4+IDMxKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgdmFyIHQgPSAoKGEgPDwgNSkgfCAoYSA+Pj4gMjcpKSArIGUgKyBXW2ldO1xuXHQgICAgICAgICAgICAgICAgaWYgKGkgPCAyMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHQgKz0gKChiICYgYykgfCAofmIgJiBkKSkgKyAweDVhODI3OTk5O1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpIDwgNDApIHtcblx0ICAgICAgICAgICAgICAgICAgICB0ICs9IChiIF4gYyBeIGQpICsgMHg2ZWQ5ZWJhMTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDYwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdCArPSAoKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpKSAtIDB4NzBlNDQzMjQ7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2UgLyogaWYgKGkgPCA4MCkgKi8ge1xuXHQgICAgICAgICAgICAgICAgICAgIHQgKz0gKGIgXiBjIF4gZCkgLSAweDM1OWQzZTJhO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICBlID0gZDtcblx0ICAgICAgICAgICAgICAgIGQgPSBjO1xuXHQgICAgICAgICAgICAgICAgYyA9IChiIDw8IDMwKSB8IChiID4+PiAyKTtcblx0ICAgICAgICAgICAgICAgIGIgPSBhO1xuXHQgICAgICAgICAgICAgICAgYSA9IHQ7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBJbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZVxuXHQgICAgICAgICAgICBIWzBdID0gKEhbMF0gKyBhKSB8IDA7XG5cdCAgICAgICAgICAgIEhbMV0gPSAoSFsxXSArIGIpIHwgMDtcblx0ICAgICAgICAgICAgSFsyXSA9IChIWzJdICsgYykgfCAwO1xuXHQgICAgICAgICAgICBIWzNdID0gKEhbM10gKyBkKSB8IDA7XG5cdCAgICAgICAgICAgIEhbNF0gPSAoSFs0XSArIGUpIHwgMDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTtcblx0ICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7XG5cblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWwgPSB0aGlzLl9uRGF0YUJ5dGVzICogODtcblx0ICAgICAgICAgICAgdmFyIG5CaXRzTGVmdCA9IGRhdGEuc2lnQnl0ZXMgKiA4O1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1tuQml0c0xlZnQgPj4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbkJpdHNMZWZ0ICUgMzIpO1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IE1hdGguZmxvb3IobkJpdHNUb3RhbCAvIDB4MTAwMDAwMDAwKTtcblx0ICAgICAgICAgICAgZGF0YVdvcmRzWygoKG5CaXRzTGVmdCArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNV0gPSBuQml0c1RvdGFsO1xuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzID0gZGF0YVdvcmRzLmxlbmd0aCAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gSGFzaCBmaW5hbCBibG9ja3Ncblx0ICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpO1xuXG5cdCAgICAgICAgICAgIC8vIFJldHVybiBmaW5hbCBjb21wdXRlZCBoYXNoXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYXNoO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2hhc2ggPSB0aGlzLl9oYXNoLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMSgnbWVzc2FnZScpO1xuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMSh3b3JkQXJyYXkpO1xuXHQgICAgICovXG5cdCAgICBDLlNIQTEgPSBIYXNoZXIuX2NyZWF0ZUhlbHBlcihTSEExKTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNTSEExKG1lc3NhZ2UsIGtleSk7XG5cdCAgICAgKi9cblx0ICAgIEMuSG1hY1NIQTEgPSBIYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoU0hBMSk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuU0hBMTtcblxufSkpOyIsInZhciBwU2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgb2JqZWN0S2V5cyA9IHJlcXVpcmUoNTYpO1xudmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSg1NSk7XG5cbnZhciBkZWVwRXF1YWwgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChhY3R1YWwsIGV4cGVjdGVkLCBvcHRzKSB7XG4gIGlmICghb3B0cykgb3B0cyA9IHt9O1xuICAvLyA3LjEuIEFsbCBpZGVudGljYWwgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcblxuICB9IGVsc2UgaWYgKGFjdHVhbCBpbnN0YW5jZW9mIERhdGUgJiYgZXhwZWN0ZWQgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5nZXRUaW1lKCkgPT09IGV4cGVjdGVkLmdldFRpbWUoKTtcblxuICAvLyA3LjMuIE90aGVyIHBhaXJzIHRoYXQgZG8gbm90IGJvdGggcGFzcyB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcsXG4gIC8vIGVxdWl2YWxlbmNlIGlzIGRldGVybWluZWQgYnkgPT0uXG4gIH0gZWxzZSBpZiAoIWFjdHVhbCB8fCAhZXhwZWN0ZWQgfHwgdHlwZW9mIGFjdHVhbCAhPSAnb2JqZWN0JyAmJiB0eXBlb2YgZXhwZWN0ZWQgIT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gb3B0cy5zdHJpY3QgPyBhY3R1YWwgPT09IGV4cGVjdGVkIDogYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIDcuNC4gRm9yIGFsbCBvdGhlciBPYmplY3QgcGFpcnMsIGluY2x1ZGluZyBBcnJheSBvYmplY3RzLCBlcXVpdmFsZW5jZSBpc1xuICAvLyBkZXRlcm1pbmVkIGJ5IGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoYXMgdmVyaWZpZWRcbiAgLy8gd2l0aCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwpLCB0aGUgc2FtZSBzZXQgb2Yga2V5c1xuICAvLyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSwgZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5XG4gIC8vIGNvcnJlc3BvbmRpbmcga2V5LCBhbmQgYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LiBOb3RlOiB0aGlzXG4gIC8vIGFjY291bnRzIGZvciBib3RoIG5hbWVkIGFuZCBpbmRleGVkIHByb3BlcnRpZXMgb24gQXJyYXlzLlxuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmpFcXVpdihhY3R1YWwsIGV4cGVjdGVkLCBvcHRzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZE9yTnVsbCh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaXNCdWZmZXIgKHgpIHtcbiAgaWYgKCF4IHx8IHR5cGVvZiB4ICE9PSAnb2JqZWN0JyB8fCB0eXBlb2YgeC5sZW5ndGggIT09ICdudW1iZXInKSByZXR1cm4gZmFsc2U7XG4gIGlmICh0eXBlb2YgeC5jb3B5ICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiB4LnNsaWNlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh4Lmxlbmd0aCA+IDAgJiYgdHlwZW9mIHhbMF0gIT09ICdudW1iZXInKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBvYmpFcXVpdihhLCBiLCBvcHRzKSB7XG4gIHZhciBpLCBrZXk7XG4gIGlmIChpc1VuZGVmaW5lZE9yTnVsbChhKSB8fCBpc1VuZGVmaW5lZE9yTnVsbChiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS5cbiAgaWYgKGEucHJvdG90eXBlICE9PSBiLnByb3RvdHlwZSkgcmV0dXJuIGZhbHNlO1xuICAvL35+fkkndmUgbWFuYWdlZCB0byBicmVhayBPYmplY3Qua2V5cyB0aHJvdWdoIHNjcmV3eSBhcmd1bWVudHMgcGFzc2luZy5cbiAgLy8gICBDb252ZXJ0aW5nIHRvIGFycmF5IHNvbHZlcyB0aGUgcHJvYmxlbS5cbiAgaWYgKGlzQXJndW1lbnRzKGEpKSB7XG4gICAgaWYgKCFpc0FyZ3VtZW50cyhiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBkZWVwRXF1YWwoYSwgYiwgb3B0cyk7XG4gIH1cbiAgaWYgKGlzQnVmZmVyKGEpKSB7XG4gICAgaWYgKCFpc0J1ZmZlcihiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhW2ldICE9PSBiW2ldKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHRyeSB7XG4gICAgdmFyIGthID0gb2JqZWN0S2V5cyhhKSxcbiAgICAgICAga2IgPSBvYmplY3RLZXlzKGIpO1xuICB9IGNhdGNoIChlKSB7Ly9oYXBwZW5zIHdoZW4gb25lIGlzIGEgc3RyaW5nIGxpdGVyYWwgYW5kIHRoZSBvdGhlciBpc24ndFxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGtleXMgaW5jb3Jwb3JhdGVzXG4gIC8vIGhhc093blByb3BlcnR5KVxuICBpZiAoa2EubGVuZ3RoICE9IGtiLmxlbmd0aClcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vdGhlIHNhbWUgc2V0IG9mIGtleXMgKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksXG4gIGthLnNvcnQoKTtcbiAga2Iuc29ydCgpO1xuICAvL35+fmNoZWFwIGtleSB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGthW2ldICE9IGtiW2ldKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5IGNvcnJlc3BvbmRpbmcga2V5LCBhbmRcbiAgLy9+fn5wb3NzaWJseSBleHBlbnNpdmUgZGVlcCB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5ID0ga2FbaV07XG4gICAgaWYgKCFkZWVwRXF1YWwoYVtrZXldLCBiW2tleV0sIG9wdHMpKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHR5cGVvZiBhID09PSB0eXBlb2YgYjtcbn1cbiIsInZhciBzdXBwb3J0c0FyZ3VtZW50c0NsYXNzID0gKGZ1bmN0aW9uKCl7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJndW1lbnRzKVxufSkoKSA9PSAnW29iamVjdCBBcmd1bWVudHNdJztcblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gc3VwcG9ydHNBcmd1bWVudHNDbGFzcyA/IHN1cHBvcnRlZCA6IHVuc3VwcG9ydGVkO1xuXG5leHBvcnRzLnN1cHBvcnRlZCA9IHN1cHBvcnRlZDtcbmZ1bmN0aW9uIHN1cHBvcnRlZChvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xufTtcblxuZXhwb3J0cy51bnN1cHBvcnRlZCA9IHVuc3VwcG9ydGVkO1xuZnVuY3Rpb24gdW5zdXBwb3J0ZWQob2JqZWN0KXtcbiAgcmV0dXJuIG9iamVjdCAmJlxuICAgIHR5cGVvZiBvYmplY3QgPT0gJ29iamVjdCcgJiZcbiAgICB0eXBlb2Ygb2JqZWN0Lmxlbmd0aCA9PSAnbnVtYmVyJyAmJlxuICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsICdjYWxsZWUnKSAmJlxuICAgICFPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCAnY2FsbGVlJykgfHxcbiAgICBmYWxzZTtcbn07XG4iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbidcbiAgPyBPYmplY3Qua2V5cyA6IHNoaW07XG5cbmV4cG9ydHMuc2hpbSA9IHNoaW07XG5mdW5jdGlvbiBzaGltIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikga2V5cy5wdXNoKGtleSk7XG4gIHJldHVybiBrZXlzO1xufVxuIiwidmFyIGFzc2VydCA9IHJlcXVpcmUoMjcpXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoMzIpXG5cbnZhciBQb2ludCA9IHJlcXVpcmUoNjEpXG5cbmZ1bmN0aW9uIEN1cnZlIChwLCBhLCBiLCBHeCwgR3ksIG4sIGgpIHtcbiAgdGhpcy5wID0gcFxuICB0aGlzLmEgPSBhXG4gIHRoaXMuYiA9IGJcbiAgdGhpcy5HID0gUG9pbnQuZnJvbUFmZmluZSh0aGlzLCBHeCwgR3kpXG4gIHRoaXMubiA9IG5cbiAgdGhpcy5oID0gaFxuXG4gIHRoaXMuaW5maW5pdHkgPSBuZXcgUG9pbnQodGhpcywgbnVsbCwgbnVsbCwgQmlnSW50ZWdlci5aRVJPKVxuXG4gIC8vIHJlc3VsdCBjYWNoaW5nXG4gIHRoaXMucE92ZXJGb3VyID0gcC5hZGQoQmlnSW50ZWdlci5PTkUpLnNoaWZ0UmlnaHQoMilcblxuICAvLyBkZXRlcm1pbmUgc2l6ZSBvZiBwIGluIGJ5dGVzXG4gIHRoaXMucExlbmd0aCA9IE1hdGguZmxvb3IoKHRoaXMucC5iaXRMZW5ndGgoKSArIDcpIC8gOClcbn1cblxuQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVggPSBmdW5jdGlvbiAoaXNPZGQsIHgpIHtcbiAgdmFyIGFscGhhID0geC5wb3coMykuYWRkKHRoaXMuYS5tdWx0aXBseSh4KSkuYWRkKHRoaXMuYikubW9kKHRoaXMucClcbiAgdmFyIGJldGEgPSBhbHBoYS5tb2RQb3codGhpcy5wT3ZlckZvdXIsIHRoaXMucCkgLy8gWFhYOiBub3QgY29tcGF0aWJsZSB3aXRoIGFsbCBjdXJ2ZXNcblxuICB2YXIgeSA9IGJldGFcbiAgaWYgKGJldGEuaXNFdmVuKCkgXiAhaXNPZGQpIHtcbiAgICB5ID0gdGhpcy5wLnN1YnRyYWN0KHkpIC8vIC15ICUgcFxuICB9XG5cbiAgcmV0dXJuIFBvaW50LmZyb21BZmZpbmUodGhpcywgeCwgeSlcbn1cblxuQ3VydmUucHJvdG90eXBlLmlzSW5maW5pdHkgPSBmdW5jdGlvbiAoUSkge1xuICBpZiAoUSA9PT0gdGhpcy5pbmZpbml0eSkgcmV0dXJuIHRydWVcblxuICByZXR1cm4gUS56LnNpZ251bSgpID09PSAwICYmIFEueS5zaWdudW0oKSAhPT0gMFxufVxuXG5DdXJ2ZS5wcm90b3R5cGUuaXNPbkN1cnZlID0gZnVuY3Rpb24gKFEpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eShRKSkgcmV0dXJuIHRydWVcblxuICB2YXIgeCA9IFEuYWZmaW5lWFxuICB2YXIgeSA9IFEuYWZmaW5lWVxuICB2YXIgYSA9IHRoaXMuYVxuICB2YXIgYiA9IHRoaXMuYlxuICB2YXIgcCA9IHRoaXMucFxuXG4gIC8vIENoZWNrIHRoYXQgeFEgYW5kIHlRIGFyZSBpbnRlZ2VycyBpbiB0aGUgaW50ZXJ2YWwgWzAsIHAgLSAxXVxuICBpZiAoeC5zaWdudW0oKSA8IDAgfHwgeC5jb21wYXJlVG8ocCkgPj0gMCkgcmV0dXJuIGZhbHNlXG4gIGlmICh5LnNpZ251bSgpIDwgMCB8fCB5LmNvbXBhcmVUbyhwKSA+PSAwKSByZXR1cm4gZmFsc2VcblxuICAvLyBhbmQgY2hlY2sgdGhhdCB5XjIgPSB4XjMgKyBheCArIGIgKG1vZCBwKVxuICB2YXIgbGhzID0geS5zcXVhcmUoKS5tb2QocClcbiAgdmFyIHJocyA9IHgucG93KDMpLmFkZChhLm11bHRpcGx5KHgpKS5hZGQoYikubW9kKHApXG4gIHJldHVybiBsaHMuZXF1YWxzKHJocylcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBhbiBlbGxpcHRpYyBjdXJ2ZSBwb2ludC5cbiAqXG4gKiBTZWUgU0VDIDEsIHNlY3Rpb24gMy4yLjIuMTogRWxsaXB0aWMgQ3VydmUgUHVibGljIEtleSBWYWxpZGF0aW9uIFByaW1pdGl2ZVxuICovXG5DdXJ2ZS5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbiAoUSkge1xuICAvLyBDaGVjayBRICE9IE9cbiAgYXNzZXJ0KCF0aGlzLmlzSW5maW5pdHkoUSksICdQb2ludCBpcyBhdCBpbmZpbml0eScpXG4gIGFzc2VydCh0aGlzLmlzT25DdXJ2ZShRKSwgJ1BvaW50IGlzIG5vdCBvbiB0aGUgY3VydmUnKVxuXG4gIC8vIENoZWNrIG5RID0gTyAod2hlcmUgUSBpcyBhIHNjYWxhciBtdWx0aXBsZSBvZiBHKVxuICB2YXIgblEgPSBRLm11bHRpcGx5KHRoaXMubilcbiAgYXNzZXJ0KHRoaXMuaXNJbmZpbml0eShuUSksICdQb2ludCBpcyBub3QgYSBzY2FsYXIgbXVsdGlwbGUgb2YgRycpXG5cbiAgcmV0dXJuIHRydWVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDdXJ2ZVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInNlY3AxMjhyMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZcIixcbiAgICBcImFcIjogXCJmZmZmZmZmZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY1wiLFxuICAgIFwiYlwiOiBcImU4NzU3OWMxMTA3OWY0M2RkODI0OTkzYzJjZWU1ZWQzXCIsXG4gICAgXCJuXCI6IFwiZmZmZmZmZmUwMDAwMDAwMDc1YTMwZDFiOTAzOGExMTVcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCIxNjFmZjc1MjhiODk5YjJkMGMyODYwN2NhNTJjNWI4NlwiLFxuICAgIFwiR3lcIjogXCJjZjVhYzgzOTViYWZlYjEzYzAyZGEyOTJkZGVkN2E4M1wiXG4gIH0sXG4gIFwic2VjcDE2MGsxXCI6IHtcbiAgICBcInBcIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWZmZmZhYzczXCIsXG4gICAgXCJhXCI6IFwiMDBcIixcbiAgICBcImJcIjogXCIwN1wiLFxuICAgIFwiblwiOiBcIjAxMDAwMDAwMDAwMDAwMDAwMDAwMDFiOGZhMTZkZmFiOWFjYTE2YjZiM1wiLFxuICAgIFwiaFwiOiBcIjAxXCIsXG4gICAgXCJHeFwiOiBcIjNiNGMzODJjZTM3YWExOTJhNDAxOWU3NjMwMzZmNGY1ZGQ0ZDdlYmJcIixcbiAgICBcIkd5XCI6IFwiOTM4Y2Y5MzUzMThmZGNlZDZiYzI4Mjg2NTMxNzMzYzNmMDNjNGZlZVwiXG4gIH0sXG4gIFwic2VjcDE2MHIxXCI6IHtcbiAgICBcInBcIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjdmZmZmZmZmXCIsXG4gICAgXCJhXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY3ZmZmZmZmY1wiLFxuICAgIFwiYlwiOiBcIjFjOTdiZWZjNTRiZDdhOGI2NWFjZjg5ZjgxZDRkNGFkYzU2NWZhNDVcIixcbiAgICBcIm5cIjogXCIwMTAwMDAwMDAwMDAwMDAwMDAwMDAxZjRjOGY5MjdhZWQzY2E3NTIyNTdcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCI0YTk2YjU2ODhlZjU3MzI4NDY2NDY5ODk2OGMzOGJiOTEzY2JmYzgyXCIsXG4gICAgXCJHeVwiOiBcIjIzYTYyODU1MzE2ODk0N2Q1OWRjYzkxMjA0MjM1MTM3N2FjNWZiMzJcIlxuICB9LFxuICBcInNlY3AxOTJrMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWZmZmZlZTM3XCIsXG4gICAgXCJhXCI6IFwiMDBcIixcbiAgICBcImJcIjogXCIwM1wiLFxuICAgIFwiblwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZTI2ZjJmYzE3MGY2OTQ2NmE3NGRlZmQ4ZFwiLFxuICAgIFwiaFwiOiBcIjAxXCIsXG4gICAgXCJHeFwiOiBcImRiNGZmMTBlYzA1N2U5YWUyNmIwN2QwMjgwYjdmNDM0MWRhNWQxYjFlYWUwNmM3ZFwiLFxuICAgIFwiR3lcIjogXCI5YjJmMmY2ZDljNTYyOGE3ODQ0MTYzZDAxNWJlODYzNDQwODJhYTg4ZDk1ZTJmOWRcIlxuICB9LFxuICBcInNlY3AxOTJyMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZmZmZmZmZmZmZmZmXCIsXG4gICAgXCJhXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZmZmZmZmZmZmZmZjXCIsXG4gICAgXCJiXCI6IFwiNjQyMTA1MTllNTljODBlNzBmYTdlOWFiNzIyNDMwNDlmZWI4ZGVlY2MxNDZiOWIxXCIsXG4gICAgXCJuXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmOTlkZWY4MzYxNDZiYzliMWI0ZDIyODMxXCIsXG4gICAgXCJoXCI6IFwiMDFcIixcbiAgICBcIkd4XCI6IFwiMTg4ZGE4MGViMDMwOTBmNjdjYmYyMGViNDNhMTg4MDBmNGZmMGFmZDgyZmYxMDEyXCIsXG4gICAgXCJHeVwiOiBcIjA3MTkyYjk1ZmZjOGRhNzg2MzEwMTFlZDZiMjRjZGQ1NzNmOTc3YTExZTc5NDgxMVwiXG4gIH0sXG4gIFwic2VjcDI1NmsxXCI6IHtcbiAgICBcInBcIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWZmZmZmYzJmXCIsXG4gICAgXCJhXCI6IFwiMDBcIixcbiAgICBcImJcIjogXCIwN1wiLFxuICAgIFwiblwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlYmFhZWRjZTZhZjQ4YTAzYmJmZDI1ZThjZDAzNjQxNDFcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCI3OWJlNjY3ZWY5ZGNiYmFjNTVhMDYyOTVjZTg3MGIwNzAyOWJmY2RiMmRjZTI4ZDk1OWYyODE1YjE2ZjgxNzk4XCIsXG4gICAgXCJHeVwiOiBcIjQ4M2FkYTc3MjZhM2M0NjU1ZGE0ZmJmYzBlMTEwOGE4ZmQxN2I0NDhhNjg1NTQxOTljNDdkMDhmZmIxMGQ0YjhcIlxuICB9LFxuICBcInNlY3AyNTZyMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmYwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlwiLFxuICAgIFwiYVwiOiBcImZmZmZmZmZmMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmNcIixcbiAgICBcImJcIjogXCI1YWM2MzVkOGFhM2E5M2U3YjNlYmJkNTU3Njk4ODZiYzY1MWQwNmIwY2M1M2IwZjYzYmNlM2MzZTI3ZDI2MDRiXCIsXG4gICAgXCJuXCI6IFwiZmZmZmZmZmYwMDAwMDAwMGZmZmZmZmZmZmZmZmZmZmZiY2U2ZmFhZGE3MTc5ZTg0ZjNiOWNhYzJmYzYzMjU1MVwiLFxuICAgIFwiaFwiOiBcIjAxXCIsXG4gICAgXCJHeFwiOiBcIjZiMTdkMWYyZTEyYzQyNDdmOGJjZTZlNTYzYTQ0MGYyNzcwMzdkODEyZGViMzNhMGY0YTEzOTQ1ZDg5OGMyOTZcIixcbiAgICBcIkd5XCI6IFwiNGZlMzQyZTJmZTFhN2Y5YjhlZTdlYjRhN2MwZjllMTYyYmNlMzM1NzZiMzE1ZWNlY2JiNjQwNjgzN2JmNTFmNVwiXG4gIH1cbn1cbiIsInZhciBQb2ludCA9IHJlcXVpcmUoNjEpXG52YXIgQ3VydmUgPSByZXF1aXJlKDU3KVxuXG52YXIgZ2V0Q3VydmVCeU5hbWUgPSByZXF1aXJlKDYwKVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQ3VydmU6IEN1cnZlLFxuICBQb2ludDogUG9pbnQsXG4gIGdldEN1cnZlQnlOYW1lOiBnZXRDdXJ2ZUJ5TmFtZVxufVxuIiwidmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKDMyKVxuXG52YXIgY3VydmVzID0gcmVxdWlyZSg1OClcbnZhciBDdXJ2ZSA9IHJlcXVpcmUoNTcpXG5cbmZ1bmN0aW9uIGdldEN1cnZlQnlOYW1lIChuYW1lKSB7XG4gIHZhciBjdXJ2ZSA9IGN1cnZlc1tuYW1lXVxuICBpZiAoIWN1cnZlKSByZXR1cm4gbnVsbFxuXG4gIHZhciBwID0gbmV3IEJpZ0ludGVnZXIoY3VydmUucCwgMTYpXG4gIHZhciBhID0gbmV3IEJpZ0ludGVnZXIoY3VydmUuYSwgMTYpXG4gIHZhciBiID0gbmV3IEJpZ0ludGVnZXIoY3VydmUuYiwgMTYpXG4gIHZhciBuID0gbmV3IEJpZ0ludGVnZXIoY3VydmUubiwgMTYpXG4gIHZhciBoID0gbmV3IEJpZ0ludGVnZXIoY3VydmUuaCwgMTYpXG4gIHZhciBHeCA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLkd4LCAxNilcbiAgdmFyIEd5ID0gbmV3IEJpZ0ludGVnZXIoY3VydmUuR3ksIDE2KVxuXG4gIHJldHVybiBuZXcgQ3VydmUocCwgYSwgYiwgR3gsIEd5LCBuLCBoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldEN1cnZlQnlOYW1lXG4iLCJ2YXIgYXNzZXJ0ID0gcmVxdWlyZSgyNylcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgzMilcblxudmFyIFRIUkVFID0gQmlnSW50ZWdlci52YWx1ZU9mKDMpXG5cbmZ1bmN0aW9uIFBvaW50IChjdXJ2ZSwgeCwgeSwgeikge1xuICBhc3NlcnQubm90U3RyaWN0RXF1YWwoeiwgdW5kZWZpbmVkLCAnTWlzc2luZyBaIGNvb3JkaW5hdGUnKVxuXG4gIHRoaXMuY3VydmUgPSBjdXJ2ZVxuICB0aGlzLnggPSB4XG4gIHRoaXMueSA9IHlcbiAgdGhpcy56ID0gelxuICB0aGlzLl96SW52ID0gbnVsbFxuXG4gIHRoaXMuY29tcHJlc3NlZCA9IHRydWVcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFBvaW50LnByb3RvdHlwZSwgJ3pJbnYnLCB7XG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLl96SW52ID09PSBudWxsKSB7XG4gICAgICB0aGlzLl96SW52ID0gdGhpcy56Lm1vZEludmVyc2UodGhpcy5jdXJ2ZS5wKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl96SW52XG4gIH1cbn0pXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShQb2ludC5wcm90b3R5cGUsICdhZmZpbmVYJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy54Lm11bHRpcGx5KHRoaXMuekludikubW9kKHRoaXMuY3VydmUucClcbiAgfVxufSlcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFBvaW50LnByb3RvdHlwZSwgJ2FmZmluZVknLCB7XG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnkubXVsdGlwbHkodGhpcy56SW52KS5tb2QodGhpcy5jdXJ2ZS5wKVxuICB9XG59KVxuXG5Qb2ludC5mcm9tQWZmaW5lID0gZnVuY3Rpb24gKGN1cnZlLCB4LCB5KSB7XG4gIHJldHVybiBuZXcgUG9pbnQoY3VydmUsIHgsIHksIEJpZ0ludGVnZXIuT05FKVxufVxuXG5Qb2ludC5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIGlmIChvdGhlciA9PT0gdGhpcykgcmV0dXJuIHRydWVcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eSh0aGlzKSkgcmV0dXJuIHRoaXMuY3VydmUuaXNJbmZpbml0eShvdGhlcilcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eShvdGhlcikpIHJldHVybiB0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcylcblxuICAvLyB1ID0gWTIgKiBaMSAtIFkxICogWjJcbiAgdmFyIHUgPSBvdGhlci55Lm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QodGhpcy55Lm11bHRpcGx5KG90aGVyLnopKS5tb2QodGhpcy5jdXJ2ZS5wKVxuXG4gIGlmICh1LnNpZ251bSgpICE9PSAwKSByZXR1cm4gZmFsc2VcblxuICAvLyB2ID0gWDIgKiBaMSAtIFgxICogWjJcbiAgdmFyIHYgPSBvdGhlci54Lm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QodGhpcy54Lm11bHRpcGx5KG90aGVyLnopKS5tb2QodGhpcy5jdXJ2ZS5wKVxuXG4gIHJldHVybiB2LnNpZ251bSgpID09PSAwXG59XG5cblBvaW50LnByb3RvdHlwZS5uZWdhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB5ID0gdGhpcy5jdXJ2ZS5wLnN1YnRyYWN0KHRoaXMueSlcblxuICByZXR1cm4gbmV3IFBvaW50KHRoaXMuY3VydmUsIHRoaXMueCwgeSwgdGhpcy56KVxufVxuXG5Qb2ludC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGIpIHtcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eSh0aGlzKSkgcmV0dXJuIGJcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eShiKSkgcmV0dXJuIHRoaXNcblxuICB2YXIgeDEgPSB0aGlzLnhcbiAgdmFyIHkxID0gdGhpcy55XG4gIHZhciB4MiA9IGIueFxuICB2YXIgeTIgPSBiLnlcblxuICAvLyB1ID0gWTIgKiBaMSAtIFkxICogWjJcbiAgdmFyIHUgPSB5Mi5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHkxLm11bHRpcGx5KGIueikpLm1vZCh0aGlzLmN1cnZlLnApXG4gIC8vIHYgPSBYMiAqIFoxIC0gWDEgKiBaMlxuICB2YXIgdiA9IHgyLm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QoeDEubXVsdGlwbHkoYi56KSkubW9kKHRoaXMuY3VydmUucClcblxuICBpZiAodi5zaWdudW0oKSA9PT0gMCkge1xuICAgIGlmICh1LnNpZ251bSgpID09PSAwKSB7XG4gICAgICByZXR1cm4gdGhpcy50d2ljZSgpIC8vIHRoaXMgPT0gYiwgc28gZG91YmxlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuaW5maW5pdHkgLy8gdGhpcyA9IC1iLCBzbyBpbmZpbml0eVxuICB9XG5cbiAgdmFyIHYyID0gdi5zcXVhcmUoKVxuICB2YXIgdjMgPSB2Mi5tdWx0aXBseSh2KVxuICB2YXIgeDF2MiA9IHgxLm11bHRpcGx5KHYyKVxuICB2YXIgenUyID0gdS5zcXVhcmUoKS5tdWx0aXBseSh0aGlzLnopXG5cbiAgLy8geDMgPSB2ICogKHoyICogKHoxICogdV4yIC0gMiAqIHgxICogdl4yKSAtIHZeMylcbiAgdmFyIHgzID0genUyLnN1YnRyYWN0KHgxdjIuc2hpZnRMZWZ0KDEpKS5tdWx0aXBseShiLnopLnN1YnRyYWN0KHYzKS5tdWx0aXBseSh2KS5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB5MyA9IHoyICogKDMgKiB4MSAqIHUgKiB2XjIgLSB5MSAqIHZeMyAtIHoxICogdV4zKSArIHUgKiB2XjNcbiAgdmFyIHkzID0geDF2Mi5tdWx0aXBseShUSFJFRSkubXVsdGlwbHkodSkuc3VidHJhY3QoeTEubXVsdGlwbHkodjMpKS5zdWJ0cmFjdCh6dTIubXVsdGlwbHkodSkpLm11bHRpcGx5KGIueikuYWRkKHUubXVsdGlwbHkodjMpKS5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB6MyA9IHZeMyAqIHoxICogejJcbiAgdmFyIHozID0gdjMubXVsdGlwbHkodGhpcy56KS5tdWx0aXBseShiLnopLm1vZCh0aGlzLmN1cnZlLnApXG5cbiAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLmN1cnZlLCB4MywgeTMsIHozKVxufVxuXG5Qb2ludC5wcm90b3R5cGUudHdpY2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcykpIHJldHVybiB0aGlzXG4gIGlmICh0aGlzLnkuc2lnbnVtKCkgPT09IDApIHJldHVybiB0aGlzLmN1cnZlLmluZmluaXR5XG5cbiAgdmFyIHgxID0gdGhpcy54XG4gIHZhciB5MSA9IHRoaXMueVxuXG4gIHZhciB5MXoxID0geTEubXVsdGlwbHkodGhpcy56KS5tb2QodGhpcy5jdXJ2ZS5wKVxuICB2YXIgeTFzcXoxID0geTF6MS5tdWx0aXBseSh5MSkubW9kKHRoaXMuY3VydmUucClcbiAgdmFyIGEgPSB0aGlzLmN1cnZlLmFcblxuICAvLyB3ID0gMyAqIHgxXjIgKyBhICogejFeMlxuICB2YXIgdyA9IHgxLnNxdWFyZSgpLm11bHRpcGx5KFRIUkVFKVxuXG4gIGlmIChhLnNpZ251bSgpICE9PSAwKSB7XG4gICAgdyA9IHcuYWRkKHRoaXMuei5zcXVhcmUoKS5tdWx0aXBseShhKSlcbiAgfVxuXG4gIHcgPSB3Lm1vZCh0aGlzLmN1cnZlLnApXG4gIC8vIHgzID0gMiAqIHkxICogejEgKiAod14yIC0gOCAqIHgxICogeTFeMiAqIHoxKVxuICB2YXIgeDMgPSB3LnNxdWFyZSgpLnN1YnRyYWN0KHgxLnNoaWZ0TGVmdCgzKS5tdWx0aXBseSh5MXNxejEpKS5zaGlmdExlZnQoMSkubXVsdGlwbHkoeTF6MSkubW9kKHRoaXMuY3VydmUucClcbiAgLy8geTMgPSA0ICogeTFeMiAqIHoxICogKDMgKiB3ICogeDEgLSAyICogeTFeMiAqIHoxKSAtIHdeM1xuICB2YXIgeTMgPSB3Lm11bHRpcGx5KFRIUkVFKS5tdWx0aXBseSh4MSkuc3VidHJhY3QoeTFzcXoxLnNoaWZ0TGVmdCgxKSkuc2hpZnRMZWZ0KDIpLm11bHRpcGx5KHkxc3F6MSkuc3VidHJhY3Qody5wb3coMykpLm1vZCh0aGlzLmN1cnZlLnApXG4gIC8vIHozID0gOCAqICh5MSAqIHoxKV4zXG4gIHZhciB6MyA9IHkxejEucG93KDMpLnNoaWZ0TGVmdCgzKS5tb2QodGhpcy5jdXJ2ZS5wKVxuXG4gIHJldHVybiBuZXcgUG9pbnQodGhpcy5jdXJ2ZSwgeDMsIHkzLCB6Mylcbn1cblxuLy8gU2ltcGxlIE5BRiAoTm9uLUFkamFjZW50IEZvcm0pIG11bHRpcGxpY2F0aW9uIGFsZ29yaXRobVxuLy8gVE9ETzogbW9kdWxhcml6ZSB0aGUgbXVsdGlwbGljYXRpb24gYWxnb3JpdGhtXG5Qb2ludC5wcm90b3R5cGUubXVsdGlwbHkgPSBmdW5jdGlvbiAoaykge1xuICBpZiAodGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpKSByZXR1cm4gdGhpc1xuICBpZiAoay5zaWdudW0oKSA9PT0gMCkgcmV0dXJuIHRoaXMuY3VydmUuaW5maW5pdHlcblxuICB2YXIgZSA9IGtcbiAgdmFyIGggPSBlLm11bHRpcGx5KFRIUkVFKVxuXG4gIHZhciBuZWcgPSB0aGlzLm5lZ2F0ZSgpXG4gIHZhciBSID0gdGhpc1xuXG4gIGZvciAodmFyIGkgPSBoLmJpdExlbmd0aCgpIC0gMjsgaSA+IDA7IC0taSkge1xuICAgIHZhciBoQml0ID0gaC50ZXN0Qml0KGkpXG4gICAgdmFyIGVCaXQgPSBlLnRlc3RCaXQoaSlcblxuICAgIFIgPSBSLnR3aWNlKClcblxuICAgIGlmIChoQml0ICE9PSBlQml0KSB7XG4gICAgICBSID0gUi5hZGQoaEJpdCA/IHRoaXMgOiBuZWcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIFJcbn1cblxuLy8gQ29tcHV0ZSB0aGlzKmogKyB4KmsgKHNpbXVsdGFuZW91cyBtdWx0aXBsaWNhdGlvbilcblBvaW50LnByb3RvdHlwZS5tdWx0aXBseVR3byA9IGZ1bmN0aW9uIChqLCB4LCBrKSB7XG4gIHZhciBpID0gTWF0aC5tYXgoai5iaXRMZW5ndGgoKSwgay5iaXRMZW5ndGgoKSkgLSAxXG4gIHZhciBSID0gdGhpcy5jdXJ2ZS5pbmZpbml0eVxuICB2YXIgYm90aCA9IHRoaXMuYWRkKHgpXG5cbiAgd2hpbGUgKGkgPj0gMCkge1xuICAgIHZhciBqQml0ID0gai50ZXN0Qml0KGkpXG4gICAgdmFyIGtCaXQgPSBrLnRlc3RCaXQoaSlcblxuICAgIFIgPSBSLnR3aWNlKClcblxuICAgIGlmIChqQml0KSB7XG4gICAgICBpZiAoa0JpdCkge1xuICAgICAgICBSID0gUi5hZGQoYm90aClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIFIgPSBSLmFkZCh0aGlzKVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoa0JpdCkge1xuICAgICAgUiA9IFIuYWRkKHgpXG4gICAgfVxuICAgIC0taVxuICB9XG5cbiAgcmV0dXJuIFJcbn1cblxuUG9pbnQucHJvdG90eXBlLmdldEVuY29kZWQgPSBmdW5jdGlvbiAoY29tcHJlc3NlZCkge1xuICBpZiAoY29tcHJlc3NlZCA9PSBudWxsKSBjb21wcmVzc2VkID0gdGhpcy5jb21wcmVzc2VkXG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcykpIHJldHVybiBCdWZmZXIuYWxsb2MoMSwgMCkgLy8gSW5maW5pdHkgcG9pbnQgZW5jb2RlZCBpcyBzaW1wbHkgJzAwJ1xuXG4gIHZhciB4ID0gdGhpcy5hZmZpbmVYXG4gIHZhciB5ID0gdGhpcy5hZmZpbmVZXG4gIHZhciBieXRlTGVuZ3RoID0gdGhpcy5jdXJ2ZS5wTGVuZ3RoXG4gIHZhciBidWZmZXJcblxuICAvLyAweDAyLzB4MDMgfCBYXG4gIGlmIChjb21wcmVzc2VkKSB7XG4gICAgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKDEgKyBieXRlTGVuZ3RoKVxuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KHkuaXNFdmVuKCkgPyAweDAyIDogMHgwMywgMClcblxuICAvLyAweDA0IHwgWCB8IFlcbiAgfSBlbHNlIHtcbiAgICBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMSArIGJ5dGVMZW5ndGggKyBieXRlTGVuZ3RoKVxuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KDB4MDQsIDApXG5cbiAgICB5LnRvQnVmZmVyKGJ5dGVMZW5ndGgpLmNvcHkoYnVmZmVyLCAxICsgYnl0ZUxlbmd0aClcbiAgfVxuXG4gIHgudG9CdWZmZXIoYnl0ZUxlbmd0aCkuY29weShidWZmZXIsIDEpXG5cbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5Qb2ludC5kZWNvZGVGcm9tID0gZnVuY3Rpb24gKGN1cnZlLCBidWZmZXIpIHtcbiAgdmFyIHR5cGUgPSBidWZmZXIucmVhZFVJbnQ4KDApXG4gIHZhciBjb21wcmVzc2VkID0gKHR5cGUgIT09IDQpXG5cbiAgdmFyIGJ5dGVMZW5ndGggPSBNYXRoLmZsb29yKChjdXJ2ZS5wLmJpdExlbmd0aCgpICsgNykgLyA4KVxuICB2YXIgeCA9IEJpZ0ludGVnZXIuZnJvbUJ1ZmZlcihidWZmZXIuc2xpY2UoMSwgMSArIGJ5dGVMZW5ndGgpKVxuXG4gIHZhciBRXG4gIGlmIChjb21wcmVzc2VkKSB7XG4gICAgYXNzZXJ0LmVxdWFsKGJ1ZmZlci5sZW5ndGgsIGJ5dGVMZW5ndGggKyAxLCAnSW52YWxpZCBzZXF1ZW5jZSBsZW5ndGgnKVxuICAgIGFzc2VydCh0eXBlID09PSAweDAyIHx8IHR5cGUgPT09IDB4MDMsICdJbnZhbGlkIHNlcXVlbmNlIHRhZycpXG5cbiAgICB2YXIgaXNPZGQgPSAodHlwZSA9PT0gMHgwMylcbiAgICBRID0gY3VydmUucG9pbnRGcm9tWChpc09kZCwgeClcbiAgfSBlbHNlIHtcbiAgICBhc3NlcnQuZXF1YWwoYnVmZmVyLmxlbmd0aCwgMSArIGJ5dGVMZW5ndGggKyBieXRlTGVuZ3RoLCAnSW52YWxpZCBzZXF1ZW5jZSBsZW5ndGgnKVxuXG4gICAgdmFyIHkgPSBCaWdJbnRlZ2VyLmZyb21CdWZmZXIoYnVmZmVyLnNsaWNlKDEgKyBieXRlTGVuZ3RoKSlcbiAgICBRID0gUG9pbnQuZnJvbUFmZmluZShjdXJ2ZSwgeCwgeSlcbiAgfVxuXG4gIFEuY29tcHJlc3NlZCA9IGNvbXByZXNzZWRcbiAgcmV0dXJuIFFcbn1cblxuUG9pbnQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpKSByZXR1cm4gJyhJTkZJTklUWSknXG5cbiAgcmV0dXJuICcoJyArIHRoaXMuYWZmaW5lWC50b1N0cmluZygpICsgJywnICsgdGhpcy5hZmZpbmVZLnRvU3RyaW5nKCkgKyAnKSdcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBQb2ludFxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSB0aGlzLl9tYXhMaXN0ZW5lcnMgfHwgdW5kZWZpbmVkO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG5FdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gIGlmICghaXNOdW1iZXIobikgfHwgbiA8IDAgfHwgaXNOYU4obikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgIChpc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICAgIGVyci5jb250ZXh0ID0gZXI7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc1VuZGVmaW5lZChoYW5kbGVyKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIGhhbmRsZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGhhbmRsZXIpKSB7XG4gICAgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgbGlzdGVuZXJzID0gaGFuZGxlci5zbGljZSgpO1xuICAgIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIG07XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgaWYgKHRoaXMuX2V2ZW50cy5uZXdMaXN0ZW5lcilcbiAgICB0aGlzLmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICAgICAgaXNGdW5jdGlvbihsaXN0ZW5lci5saXN0ZW5lcikgP1xuICAgICAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgZWxzZSBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuICBlbHNlXG4gICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuXG4gIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pICYmICF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKSB7XG4gICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9tYXhMaXN0ZW5lcnMpKSB7XG4gICAgICBtID0gdGhpcy5fbWF4TGlzdGVuZXJzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfVxuXG4gICAgaWYgKG0gJiYgbSA+IDAgJiYgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCA+IG0pIHtcbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQgPSB0cnVlO1xuICAgICAgY29uc29sZS5lcnJvcignKG5vZGUpIHdhcm5pbmc6IHBvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgJyArXG4gICAgICAgICAgICAgICAgICAgICdsZWFrIGRldGVjdGVkLiAlZCBsaXN0ZW5lcnMgYWRkZWQuICcgK1xuICAgICAgICAgICAgICAgICAgICAnVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gaW5jcmVhc2UgbGltaXQuJyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCk7XG4gICAgICBpZiAodHlwZW9mIGNvbnNvbGUudHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gbm90IHN1cHBvcnRlZCBpbiBJRSAxMFxuICAgICAgICBjb25zb2xlLnRyYWNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIHZhciBmaXJlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGcoKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBnKTtcblxuICAgIGlmICghZmlyZWQpIHtcbiAgICAgIGZpcmVkID0gdHJ1ZTtcbiAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9XG5cbiAgZy5saXN0ZW5lciA9IGxpc3RlbmVyO1xuICB0aGlzLm9uKHR5cGUsIGcpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWRcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbGlzdCwgcG9zaXRpb24sIGxlbmd0aCwgaTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXR1cm4gdGhpcztcblxuICBsaXN0ID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuICBsZW5ndGggPSBsaXN0Lmxlbmd0aDtcbiAgcG9zaXRpb24gPSAtMTtcblxuICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHxcbiAgICAgIChpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpICYmIGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG5cbiAgfSBlbHNlIGlmIChpc09iamVjdChsaXN0KSkge1xuICAgIGZvciAoaSA9IGxlbmd0aDsgaS0tID4gMDspIHtcbiAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fFxuICAgICAgICAgIChsaXN0W2ldLmxpc3RlbmVyICYmIGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgbGlzdC5sZW5ndGggPSAwO1xuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGlzdC5zcGxpY2UocG9zaXRpb24sIDEpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGtleSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgaWYgKCF0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIGVsc2UgaWYgKHRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGtleSBpbiB0aGlzLl9ldmVudHMpIHtcbiAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICB9XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzRnVuY3Rpb24obGlzdGVuZXJzKSkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAvLyBMSUZPIG9yZGVyXG4gICAgd2hpbGUgKGxpc3RlbmVycy5sZW5ndGgpXG4gICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV0pO1xuICB9XG4gIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIHJldDtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXQgPSBbXTtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IFt0aGlzLl9ldmVudHNbdHlwZV1dO1xuICBlbHNlXG4gICAgcmV0ID0gdGhpcy5fZXZlbnRzW3R5cGVdLnNsaWNlKCk7XG4gIHJldHVybiByZXQ7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIGlmICh0aGlzLl9ldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGV2bGlzdGVuZXIpKVxuICAgICAgcmV0dXJuIDE7XG4gICAgZWxzZSBpZiAoZXZsaXN0ZW5lcilcbiAgICAgIHJldHVybiBldmxpc3RlbmVyLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gMDtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xufTtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuIiwiJ3VzZSBzdHJpY3QnXG52YXIgQnVmZmVyID0gcmVxdWlyZSg5MykuQnVmZmVyXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgxMDMpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcblxuZnVuY3Rpb24gdGhyb3dJZk5vdFN0cmluZ09yQnVmZmVyICh2YWwsIHByZWZpeCkge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih2YWwpICYmIHR5cGVvZiB2YWwgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihwcmVmaXggKyAnIG11c3QgYmUgYSBzdHJpbmcgb3IgYSBidWZmZXInKVxuICB9XG59XG5cbmZ1bmN0aW9uIEhhc2hCYXNlIChibG9ja1NpemUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcblxuICB0aGlzLl9ibG9jayA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja1NpemUpXG4gIHRoaXMuX2Jsb2NrU2l6ZSA9IGJsb2NrU2l6ZVxuICB0aGlzLl9ibG9ja09mZnNldCA9IDBcbiAgdGhpcy5fbGVuZ3RoID0gWzAsIDAsIDAsIDBdXG5cbiAgdGhpcy5fZmluYWxpemVkID0gZmFsc2Vcbn1cblxuaW5oZXJpdHMoSGFzaEJhc2UsIFRyYW5zZm9ybSlcblxuSGFzaEJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYWxsYmFjaykge1xuICB2YXIgZXJyb3IgPSBudWxsXG4gIHRyeSB7XG4gICAgdGhpcy51cGRhdGUoY2h1bmssIGVuY29kaW5nKVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBlcnJvciA9IGVyclxuICB9XG5cbiAgY2FsbGJhY2soZXJyb3IpXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgdmFyIGVycm9yID0gbnVsbFxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLmRpZ2VzdCgpKVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBlcnJvciA9IGVyclxuICB9XG5cbiAgY2FsbGJhY2soZXJyb3IpXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jb2RpbmcpIHtcbiAgdGhyb3dJZk5vdFN0cmluZ09yQnVmZmVyKGRhdGEsICdEYXRhJylcbiAgaWYgKHRoaXMuX2ZpbmFsaXplZCkgdGhyb3cgbmV3IEVycm9yKCdEaWdlc3QgYWxyZWFkeSBjYWxsZWQnKVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkgZGF0YSA9IEJ1ZmZlci5mcm9tKGRhdGEsIGVuY29kaW5nKVxuXG4gIC8vIGNvbnN1bWUgZGF0YVxuICB2YXIgYmxvY2sgPSB0aGlzLl9ibG9ja1xuICB2YXIgb2Zmc2V0ID0gMFxuICB3aGlsZSAodGhpcy5fYmxvY2tPZmZzZXQgKyBkYXRhLmxlbmd0aCAtIG9mZnNldCA+PSB0aGlzLl9ibG9ja1NpemUpIHtcbiAgICBmb3IgKHZhciBpID0gdGhpcy5fYmxvY2tPZmZzZXQ7IGkgPCB0aGlzLl9ibG9ja1NpemU7KSBibG9ja1tpKytdID0gZGF0YVtvZmZzZXQrK11cbiAgICB0aGlzLl91cGRhdGUoKVxuICAgIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB9XG4gIHdoaWxlIChvZmZzZXQgPCBkYXRhLmxlbmd0aCkgYmxvY2tbdGhpcy5fYmxvY2tPZmZzZXQrK10gPSBkYXRhW29mZnNldCsrXVxuXG4gIC8vIHVwZGF0ZSBsZW5ndGhcbiAgZm9yICh2YXIgaiA9IDAsIGNhcnJ5ID0gZGF0YS5sZW5ndGggKiA4OyBjYXJyeSA+IDA7ICsraikge1xuICAgIHRoaXMuX2xlbmd0aFtqXSArPSBjYXJyeVxuICAgIGNhcnJ5ID0gKHRoaXMuX2xlbmd0aFtqXSAvIDB4MDEwMDAwMDAwMCkgfCAwXG4gICAgaWYgKGNhcnJ5ID4gMCkgdGhpcy5fbGVuZ3RoW2pdIC09IDB4MDEwMDAwMDAwMCAqIGNhcnJ5XG4gIH1cblxuICByZXR1cm4gdGhpc1xufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdXBkYXRlIGlzIG5vdCBpbXBsZW1lbnRlZCcpXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiAoZW5jb2RpbmcpIHtcbiAgaWYgKHRoaXMuX2ZpbmFsaXplZCkgdGhyb3cgbmV3IEVycm9yKCdEaWdlc3QgYWxyZWFkeSBjYWxsZWQnKVxuICB0aGlzLl9maW5hbGl6ZWQgPSB0cnVlXG5cbiAgdmFyIGRpZ2VzdCA9IHRoaXMuX2RpZ2VzdCgpXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSBkaWdlc3QgPSBkaWdlc3QudG9TdHJpbmcoZW5jb2RpbmcpXG5cbiAgLy8gcmVzZXQgc3RhdGVcbiAgdGhpcy5fYmxvY2suZmlsbCgwKVxuICB0aGlzLl9ibG9ja09mZnNldCA9IDBcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyArK2kpIHRoaXMuX2xlbmd0aFtpXSA9IDBcblxuICByZXR1cm4gZGlnZXN0XG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ19kaWdlc3QgaXMgbm90IGltcGxlbWVudGVkJylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBIYXNoQmFzZVxuIiwiZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSAoZSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSAobSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICgodmFsdWUgKiBjKSAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG4iLCIvKiFcbiAqIERldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBCdWZmZXJcbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbi8vIFRoZSBfaXNCdWZmZXIgY2hlY2sgaXMgZm9yIFNhZmFyaSA1LTcgc3VwcG9ydCwgYmVjYXVzZSBpdCdzIG1pc3Npbmdcbi8vIE9iamVjdC5wcm90b3R5cGUuY29uc3RydWN0b3IuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHlcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gb2JqICE9IG51bGwgJiYgKGlzQnVmZmVyKG9iaikgfHwgaXNTbG93QnVmZmVyKG9iaikgfHwgISFvYmouX2lzQnVmZmVyKVxufVxuXG5mdW5jdGlvbiBpc0J1ZmZlciAob2JqKSB7XG4gIHJldHVybiAhIW9iai5jb25zdHJ1Y3RvciAmJiB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopXG59XG5cbi8vIEZvciBOb2RlIHYwLjEwIHN1cHBvcnQuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHkuXG5mdW5jdGlvbiBpc1Nsb3dCdWZmZXIgKG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iai5yZWFkRmxvYXRMRSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2Ygb2JqLnNsaWNlID09PSAnZnVuY3Rpb24nICYmIGlzQnVmZmVyKG9iai5zbGljZSgwLCAwKSlcbn1cbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwiLypcclxuIENvcHlyaWdodCAyMDEzIERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcbiBDb3B5cmlnaHQgMjAwOSBUaGUgQ2xvc3VyZSBMaWJyYXJ5IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcblxyXG4gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcclxuIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cclxuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG5cclxuIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcclxuIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMtSVNcIiBCQVNJUyxcclxuIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxyXG4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxyXG4gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEBsaWNlbnNlIGxvbmcuanMgKGMpIDIwMTMgRGFuaWVsIFdpcnR6IDxkY29kZUBkY29kZS5pbz5cclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMFxyXG4gKiBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL2xvbmcuanMgZm9yIGRldGFpbHNcclxuICovXHJcbihmdW5jdGlvbihnbG9iYWwsIGZhY3RvcnkpIHtcclxuXHJcbiAgICAvKiBBTUQgKi8gaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lW1wiYW1kXCJdKVxyXG4gICAgICAgIGRlZmluZShbXSwgZmFjdG9yeSk7XHJcbiAgICAvKiBDb21tb25KUyAqLyBlbHNlIGlmICh0eXBlb2YgcmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIG1vZHVsZSAmJiBtb2R1bGVbXCJleHBvcnRzXCJdKVxyXG4gICAgICAgIG1vZHVsZVtcImV4cG9ydHNcIl0gPSBmYWN0b3J5KCk7XHJcbiAgICAvKiBHbG9iYWwgKi8gZWxzZVxyXG4gICAgICAgIChnbG9iYWxbXCJkY29kZUlPXCJdID0gZ2xvYmFsW1wiZGNvZGVJT1wiXSB8fCB7fSlbXCJMb25nXCJdID0gZmFjdG9yeSgpO1xyXG5cclxufSkodGhpcywgZnVuY3Rpb24oKSB7XHJcbiAgICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyLCBnaXZlbiBpdHMgbG93IGFuZCBoaWdoIDMyIGJpdCB2YWx1ZXMgYXMgKnNpZ25lZCogaW50ZWdlcnMuXHJcbiAgICAgKiAgU2VlIHRoZSBmcm9tKiBmdW5jdGlvbnMgYmVsb3cgZm9yIG1vcmUgY29udmVuaWVudCB3YXlzIG9mIGNvbnN0cnVjdGluZyBMb25ncy5cclxuICAgICAqIEBleHBvcnRzIExvbmdcclxuICAgICAqIEBjbGFzcyBBIExvbmcgY2xhc3MgZm9yIHJlcHJlc2VudGluZyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIgdmFsdWUuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93IFRoZSBsb3cgKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2ggVGhlIGhpZ2ggKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIExvbmcobG93LCBoaWdoLCB1bnNpZ25lZCkge1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgbG93IDMyIGJpdHMgYXMgYSBzaWduZWQgdmFsdWUuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmxvdyA9IGxvdyB8IDA7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgdmFsdWUuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmhpZ2ggPSBoaWdoIHwgMDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV2hldGhlciB1bnNpZ25lZCBvciBub3QuXHJcbiAgICAgICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy51bnNpZ25lZCA9ICEhdW5zaWduZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIGEgbG9uZyBpcyB0aGUgdHdvIGdpdmVuIHNpZ25lZCwgMzItYml0IHZhbHVlcy5cclxuICAgIC8vIFdlIHVzZSAzMi1iaXQgcGllY2VzIGJlY2F1c2UgdGhlc2UgYXJlIHRoZSBzaXplIG9mIGludGVnZXJzIG9uIHdoaWNoXHJcbiAgICAvLyBKYXZhc2NyaXB0IHBlcmZvcm1zIGJpdC1vcGVyYXRpb25zLiAgRm9yIG9wZXJhdGlvbnMgbGlrZSBhZGRpdGlvbiBhbmRcclxuICAgIC8vIG11bHRpcGxpY2F0aW9uLCB3ZSBzcGxpdCBlYWNoIG51bWJlciBpbnRvIDE2IGJpdCBwaWVjZXMsIHdoaWNoIGNhbiBlYXNpbHkgYmVcclxuICAgIC8vIG11bHRpcGxpZWQgd2l0aGluIEphdmFzY3JpcHQncyBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiB3aXRob3V0IG92ZXJmbG93XHJcbiAgICAvLyBvciBjaGFuZ2UgaW4gc2lnbi5cclxuICAgIC8vXHJcbiAgICAvLyBJbiB0aGUgYWxnb3JpdGhtcyBiZWxvdywgd2UgZnJlcXVlbnRseSByZWR1Y2UgdGhlIG5lZ2F0aXZlIGNhc2UgdG8gdGhlXHJcbiAgICAvLyBwb3NpdGl2ZSBjYXNlIGJ5IG5lZ2F0aW5nIHRoZSBpbnB1dChzKSBhbmQgdGhlbiBwb3N0LXByb2Nlc3NpbmcgdGhlIHJlc3VsdC5cclxuICAgIC8vIE5vdGUgdGhhdCB3ZSBtdXN0IEFMV0FZUyBjaGVjayBzcGVjaWFsbHkgd2hldGhlciB0aG9zZSB2YWx1ZXMgYXJlIE1JTl9WQUxVRVxyXG4gICAgLy8gKC0yXjYzKSBiZWNhdXNlIC1NSU5fVkFMVUUgPT0gTUlOX1ZBTFVFIChzaW5jZSAyXjYzIGNhbm5vdCBiZSByZXByZXNlbnRlZCBhc1xyXG4gICAgLy8gYSBwb3NpdGl2ZSBudW1iZXIsIGl0IG92ZXJmbG93cyBiYWNrIGludG8gYSBuZWdhdGl2ZSkuICBOb3QgaGFuZGxpbmcgdGhpc1xyXG4gICAgLy8gY2FzZSB3b3VsZCBvZnRlbiByZXN1bHQgaW4gaW5maW5pdGUgcmVjdXJzaW9uLlxyXG4gICAgLy9cclxuICAgIC8vIENvbW1vbiBjb25zdGFudCB2YWx1ZXMgWkVSTywgT05FLCBORUdfT05FLCBldGMuIGFyZSBkZWZpbmVkIGJlbG93IHRoZSBmcm9tKlxyXG4gICAgLy8gbWV0aG9kcyBvbiB3aGljaCB0aGV5IGRlcGVuZC5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFuIGluZGljYXRvciB1c2VkIHRvIHJlbGlhYmx5IGRldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBMb25nIG9yIG5vdC5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBMb25nLnByb3RvdHlwZS5fX2lzTG9uZ19fO1xyXG5cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShMb25nLnByb3RvdHlwZSwgXCJfX2lzTG9uZ19fXCIsIHtcclxuICAgICAgICB2YWx1ZTogdHJ1ZSxcclxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlXHJcbiAgICB9KTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBpc0xvbmcob2JqKSB7XHJcbiAgICAgICAgcmV0dXJuIChvYmogJiYgb2JqW1wiX19pc0xvbmdfX1wiXSkgPT09IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhIExvbmcuXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7Kn0gb2JqIE9iamVjdFxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmcuaXNMb25nID0gaXNMb25nO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjYWNoZSBvZiB0aGUgTG9uZyByZXByZXNlbnRhdGlvbnMgb2Ygc21hbGwgaW50ZWdlciB2YWx1ZXMuXHJcbiAgICAgKiBAdHlwZSB7IU9iamVjdH1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgSU5UX0NBQ0hFID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBIGNhY2hlIG9mIHRoZSBMb25nIHJlcHJlc2VudGF0aW9ucyBvZiBzbWFsbCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy5cclxuICAgICAqIEB0eXBlIHshT2JqZWN0fVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBVSU5UX0NBQ0hFID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbUludCh2YWx1ZSwgdW5zaWduZWQpIHtcclxuICAgICAgICB2YXIgb2JqLCBjYWNoZWRPYmosIGNhY2hlO1xyXG4gICAgICAgIGlmICh1bnNpZ25lZCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA+Pj49IDA7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSA9ICgwIDw9IHZhbHVlICYmIHZhbHVlIDwgMjU2KSkge1xyXG4gICAgICAgICAgICAgICAgY2FjaGVkT2JqID0gVUlOVF9DQUNIRVt2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICBpZiAoY2FjaGVkT2JqKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZWRPYmo7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb2JqID0gZnJvbUJpdHModmFsdWUsICh2YWx1ZSB8IDApIDwgMCA/IC0xIDogMCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSlcclxuICAgICAgICAgICAgICAgIFVJTlRfQ0FDSEVbdmFsdWVdID0gb2JqO1xyXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSA9ICgtMTI4IDw9IHZhbHVlICYmIHZhbHVlIDwgMTI4KSkge1xyXG4gICAgICAgICAgICAgICAgY2FjaGVkT2JqID0gSU5UX0NBQ0hFW3ZhbHVlXTtcclxuICAgICAgICAgICAgICAgIGlmIChjYWNoZWRPYmopXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlZE9iajtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvYmogPSBmcm9tQml0cyh2YWx1ZSwgdmFsdWUgPCAwID8gLTEgOiAwLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSlcclxuICAgICAgICAgICAgICAgIElOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XHJcbiAgICAgICAgICAgIHJldHVybiBvYmo7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiAzMiBiaXQgaW50ZWdlciB2YWx1ZS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSAzMiBiaXQgaW50ZWdlciBpbiBxdWVzdGlvblxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbUludCA9IGZyb21JbnQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSwgdW5zaWduZWQpIHtcclxuICAgICAgICBpZiAoaXNOYU4odmFsdWUpIHx8ICFpc0Zpbml0ZSh2YWx1ZSkpXHJcbiAgICAgICAgICAgIHJldHVybiB1bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcclxuICAgICAgICBpZiAodW5zaWduZWQpIHtcclxuICAgICAgICAgICAgaWYgKHZhbHVlIDwgMClcclxuICAgICAgICAgICAgICAgIHJldHVybiBVWkVSTztcclxuICAgICAgICAgICAgaWYgKHZhbHVlID49IFRXT19QV1JfNjRfREJMKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodmFsdWUgPD0gLVRXT19QV1JfNjNfREJMKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1JTl9WQUxVRTtcclxuICAgICAgICAgICAgaWYgKHZhbHVlICsgMSA+PSBUV09fUFdSXzYzX0RCTClcclxuICAgICAgICAgICAgICAgIHJldHVybiBNQVhfVkFMVUU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZSA8IDApXHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tTnVtYmVyKC12YWx1ZSwgdW5zaWduZWQpLm5lZygpO1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cygodmFsdWUgJSBUV09fUFdSXzMyX0RCTCkgfCAwLCAodmFsdWUgLyBUV09fUFdSXzMyX0RCTCkgfCAwLCB1bnNpZ25lZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHZhbHVlLCBwcm92aWRlZCB0aGF0IGl0IGlzIGEgZmluaXRlIG51bWJlci4gT3RoZXJ3aXNlLCB6ZXJvIGlzIHJldHVybmVkLlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIG51bWJlciBpbiBxdWVzdGlvblxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbU51bWJlciA9IGZyb21OdW1iZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93Qml0c1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGZyb21CaXRzKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgTG9uZyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSA2NCBiaXQgaW50ZWdlciB0aGF0IGNvbWVzIGJ5IGNvbmNhdGVuYXRpbmcgdGhlIGdpdmVuIGxvdyBhbmQgaGlnaCBiaXRzLiBFYWNoIGlzXHJcbiAgICAgKiAgYXNzdW1lZCB0byB1c2UgMzIgYml0cy5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHMgVGhlIGxvdyAzMiBiaXRzXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGlnaEJpdHMgVGhlIGhpZ2ggMzIgYml0c1xyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbUJpdHMgPSBmcm9tQml0cztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJhc2VcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBleHBvbmVudFxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgcG93X2RibCA9IE1hdGgucG93OyAvLyBVc2VkIDQgdGltZXMgKDQqOCB0byAxNSs0KVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxyXG4gICAgICogQHBhcmFtIHsoYm9vbGVhbnxudW1iZXIpPX0gdW5zaWduZWRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXhcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBmcm9tU3RyaW5nKHN0ciwgdW5zaWduZWQsIHJhZGl4KSB7XHJcbiAgICAgICAgaWYgKHN0ci5sZW5ndGggPT09IDApXHJcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdlbXB0eSBzdHJpbmcnKTtcclxuICAgICAgICBpZiAoc3RyID09PSBcIk5hTlwiIHx8IHN0ciA9PT0gXCJJbmZpbml0eVwiIHx8IHN0ciA9PT0gXCIrSW5maW5pdHlcIiB8fCBzdHIgPT09IFwiLUluZmluaXR5XCIpXHJcbiAgICAgICAgICAgIHJldHVybiBaRVJPO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdW5zaWduZWQgPT09ICdudW1iZXInKSB7XHJcbiAgICAgICAgICAgIC8vIEZvciBnb29nLm1hdGgubG9uZyBjb21wYXRpYmlsaXR5XHJcbiAgICAgICAgICAgIHJhZGl4ID0gdW5zaWduZWQsXHJcbiAgICAgICAgICAgIHVuc2lnbmVkID0gZmFsc2U7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdW5zaWduZWQgPSAhISB1bnNpZ25lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmFkaXggPSByYWRpeCB8fCAxMDtcclxuICAgICAgICBpZiAocmFkaXggPCAyIHx8IDM2IDwgcmFkaXgpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoJ3JhZGl4Jyk7XHJcblxyXG4gICAgICAgIHZhciBwO1xyXG4gICAgICAgIGlmICgocCA9IHN0ci5pbmRleE9mKCctJykpID4gMClcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2ludGVyaW9yIGh5cGhlbicpO1xyXG4gICAgICAgIGVsc2UgaWYgKHAgPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21TdHJpbmcoc3RyLnN1YnN0cmluZygxKSwgdW5zaWduZWQsIHJhZGl4KS5uZWcoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIERvIHNldmVyYWwgKDgpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cclxuICAgICAgICAvLyBtaW5pbWl6ZSB0aGUgY2FsbHMgdG8gdGhlIHZlcnkgZXhwZW5zaXZlIGVtdWxhdGVkIGRpdi5cclxuICAgICAgICB2YXIgcmFkaXhUb1Bvd2VyID0gZnJvbU51bWJlcihwb3dfZGJsKHJhZGl4LCA4KSk7XHJcblxyXG4gICAgICAgIHZhciByZXN1bHQgPSBaRVJPO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSArPSA4KSB7XHJcbiAgICAgICAgICAgIHZhciBzaXplID0gTWF0aC5taW4oOCwgc3RyLmxlbmd0aCAtIGkpLFxyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUludChzdHIuc3Vic3RyaW5nKGksIGkgKyBzaXplKSwgcmFkaXgpO1xyXG4gICAgICAgICAgICBpZiAoc2l6ZSA8IDgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBwb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgc2l6ZSkpO1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChwb3dlcikuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5tdWwocmFkaXhUb1Bvd2VyKTtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlc3VsdC51bnNpZ25lZCA9IHVuc2lnbmVkO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gc3RyaW5nLCB3cml0dGVuIHVzaW5nIHRoZSBzcGVjaWZpZWQgcmFkaXguXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIExvbmdcclxuICAgICAqIEBwYXJhbSB7KGJvb2xlYW58bnVtYmVyKT19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBgZmFsc2VgIGZvciBzaWduZWRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXggVGhlIHJhZGl4IGluIHdoaWNoIHRoZSB0ZXh0IGlzIHdyaXR0ZW4gKDItMzYpLCBkZWZhdWx0cyB0byAxMFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbVN0cmluZyA9IGZyb21TdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbVZhbHVlKHZhbCkge1xyXG4gICAgICAgIGlmICh2YWwgLyogaXMgY29tcGF0aWJsZSAqLyBpbnN0YW5jZW9mIExvbmcpXHJcbiAgICAgICAgICAgIHJldHVybiB2YWw7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbU51bWJlcih2YWwpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21TdHJpbmcodmFsKTtcclxuICAgICAgICAvLyBUaHJvd3MgZm9yIG5vbi1vYmplY3RzLCBjb252ZXJ0cyBub24taW5zdGFuY2VvZiBMb25nOlxyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh2YWwubG93LCB2YWwuaGlnaCwgdmFsLnVuc2lnbmVkKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgdmFsdWUgdG8gYSBMb25nLlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd8IXtsb3c6IG51bWJlciwgaGlnaDogbnVtYmVyLCB1bnNpZ25lZDogYm9vbGVhbn19IHZhbCBWYWx1ZVxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLmZyb21WYWx1ZSA9IGZyb21WYWx1ZTtcclxuXHJcbiAgICAvLyBOT1RFOiB0aGUgY29tcGlsZXIgc2hvdWxkIGlubGluZSB0aGVzZSBjb25zdGFudCB2YWx1ZXMgYmVsb3cgYW5kIHRoZW4gcmVtb3ZlIHRoZXNlIHZhcmlhYmxlcywgc28gdGhlcmUgc2hvdWxkIGJlXHJcbiAgICAvLyBubyBydW50aW1lIHBlbmFsdHkgZm9yIHRoZXNlLlxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBUV09fUFdSXzE2X0RCTCA9IDEgPDwgMTY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfMjRfREJMID0gMSA8PCAyNDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgVFdPX1BXUl8zMl9EQkwgPSBUV09fUFdSXzE2X0RCTCAqIFRXT19QV1JfMTZfREJMO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBUV09fUFdSXzY0X0RCTCA9IFRXT19QV1JfMzJfREJMICogVFdPX1BXUl8zMl9EQkw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfNjNfREJMID0gVFdPX1BXUl82NF9EQkwgLyAyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfMjQgPSBmcm9tSW50KFRXT19QV1JfMjRfREJMKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgWkVSTyA9IGZyb21JbnQoMCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTaWduZWQgemVyby5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5aRVJPID0gWkVSTztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgVVpFUk8gPSBmcm9tSW50KDAsIHRydWUpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVW5zaWduZWQgemVyby5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5VWkVSTyA9IFVaRVJPO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBPTkUgPSBmcm9tSW50KDEpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2lnbmVkIG9uZS5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5PTkUgPSBPTkU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFVPTkUgPSBmcm9tSW50KDEsIHRydWUpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVW5zaWduZWQgb25lLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLlVPTkUgPSBVT05FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBORUdfT05FID0gZnJvbUludCgtMSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTaWduZWQgbmVnYXRpdmUgb25lLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLk5FR19PTkUgPSBORUdfT05FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBNQVhfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGfDAsIDB4N0ZGRkZGRkZ8MCwgZmFsc2UpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWF4aW11bSBzaWduZWQgdmFsdWUuXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmcuTUFYX1ZBTFVFID0gTUFYX1ZBTFVFO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBNQVhfVU5TSUdORURfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGfDAsIDB4RkZGRkZGRkZ8MCwgdHJ1ZSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYXhpbXVtIHVuc2lnbmVkIHZhbHVlLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLk1BWF9VTlNJR05FRF9WQUxVRSA9IE1BWF9VTlNJR05FRF9WQUxVRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgTUlOX1ZBTFVFID0gZnJvbUJpdHMoMCwgMHg4MDAwMDAwMHwwLCBmYWxzZSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNaW5pbXVtIHNpZ25lZCB2YWx1ZS5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5NSU5fVkFMVUUgPSBNSU5fVkFMVUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAYWxpYXMgTG9uZy5wcm90b3R5cGVcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgTG9uZ1Byb3RvdHlwZSA9IExvbmcucHJvdG90eXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSAzMiBiaXQgaW50ZWdlciwgYXNzdW1pbmcgaXQgaXMgYSAzMiBiaXQgaW50ZWdlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUudG9JbnQgPSBmdW5jdGlvbiB0b0ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IHRoaXMubG93ID4+PiAwIDogdGhpcy5sb3c7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSB0aGUgbmVhcmVzdCBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZhbHVlIChkb3VibGUsIDUzIGJpdCBtYW50aXNzYSkuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgICAgIHJldHVybiAoKHRoaXMuaGlnaCA+Pj4gMCkgKiBUV09fUFdSXzMyX0RCTCkgKyAodGhpcy5sb3cgPj4+IDApO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2ggKiBUV09fUFdSXzMyX0RCTCArICh0aGlzLmxvdyA+Pj4gMCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSBzdHJpbmcgd3JpdHRlbiBpbiB0aGUgc3BlY2lmaWVkIHJhZGl4LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSByYWRpeCBSYWRpeCAoMi0zNiksIGRlZmF1bHRzIHRvIDEwXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxyXG4gICAgICogQG92ZXJyaWRlXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgcmFkaXhgIGlzIG91dCBvZiByYW5nZVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcocmFkaXgpIHtcclxuICAgICAgICByYWRpeCA9IHJhZGl4IHx8IDEwO1xyXG4gICAgICAgIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeClcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcigncmFkaXgnKTtcclxuICAgICAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuICcwJztcclxuICAgICAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHsgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcclxuICAgICAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gY2hhbmdlIHRoZSBMb25nIHZhbHVlIGJlZm9yZSBpdCBjYW4gYmUgbmVnYXRlZCwgc28gd2UgcmVtb3ZlXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgYm90dG9tLW1vc3QgZGlnaXQgaW4gdGhpcyBiYXNlIGFuZCB0aGVuIHJlY3Vyc2UgdG8gZG8gdGhlIHJlc3QuXHJcbiAgICAgICAgICAgICAgICB2YXIgcmFkaXhMb25nID0gZnJvbU51bWJlcihyYWRpeCksXHJcbiAgICAgICAgICAgICAgICAgICAgZGl2ID0gdGhpcy5kaXYocmFkaXhMb25nKSxcclxuICAgICAgICAgICAgICAgICAgICByZW0xID0gZGl2Lm11bChyYWRpeExvbmcpLnN1Yih0aGlzKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkaXYudG9TdHJpbmcocmFkaXgpICsgcmVtMS50b0ludCgpLnRvU3RyaW5nKHJhZGl4KTtcclxuICAgICAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJy0nICsgdGhpcy5uZWcoKS50b1N0cmluZyhyYWRpeCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEbyBzZXZlcmFsICg2KSBkaWdpdHMgZWFjaCB0aW1lIHRocm91Z2ggdGhlIGxvb3AsIHNvIGFzIHRvXHJcbiAgICAgICAgLy8gbWluaW1pemUgdGhlIGNhbGxzIHRvIHRoZSB2ZXJ5IGV4cGVuc2l2ZSBlbXVsYXRlZCBkaXYuXHJcbiAgICAgICAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgNiksIHRoaXMudW5zaWduZWQpLFxyXG4gICAgICAgICAgICByZW0gPSB0aGlzO1xyXG4gICAgICAgIHZhciByZXN1bHQgPSAnJztcclxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xyXG4gICAgICAgICAgICB2YXIgcmVtRGl2ID0gcmVtLmRpdihyYWRpeFRvUG93ZXIpLFxyXG4gICAgICAgICAgICAgICAgaW50dmFsID0gcmVtLnN1YihyZW1EaXYubXVsKHJhZGl4VG9Qb3dlcikpLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgICAgICBkaWdpdHMgPSBpbnR2YWwudG9TdHJpbmcocmFkaXgpO1xyXG4gICAgICAgICAgICByZW0gPSByZW1EaXY7XHJcbiAgICAgICAgICAgIGlmIChyZW0uaXNaZXJvKCkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZGlnaXRzICsgcmVzdWx0O1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChkaWdpdHMubGVuZ3RoIDwgNilcclxuICAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAnMCcgKyBkaWdpdHM7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSAnJyArIGRpZ2l0cyArIHJlc3VsdDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFNpZ25lZCBoaWdoIGJpdHNcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0cyA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2g7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgaGlnaCAzMiBiaXRzIGFzIGFuIHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBoaWdoIGJpdHNcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0SGlnaEJpdHNVbnNpZ25lZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWdoID4+PiAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgbG93IGJpdHNcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzID0gZnVuY3Rpb24gZ2V0TG93Qml0cygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sb3c7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFVuc2lnbmVkIGxvdyBiaXRzXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ2V0TG93Qml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0TG93Qml0c1Vuc2lnbmVkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxvdyA+Pj4gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgYml0cyBuZWVkZWQgdG8gcmVwcmVzZW50IHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGlzIExvbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmdldE51bUJpdHNBYnMgPSBmdW5jdGlvbiBnZXROdW1CaXRzQWJzKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVxKE1JTl9WQUxVRSkgPyA2NCA6IHRoaXMubmVnKCkuZ2V0TnVtQml0c0FicygpO1xyXG4gICAgICAgIHZhciB2YWwgPSB0aGlzLmhpZ2ggIT0gMCA/IHRoaXMuaGlnaCA6IHRoaXMubG93O1xyXG4gICAgICAgIGZvciAodmFyIGJpdCA9IDMxOyBiaXQgPiAwOyBiaXQtLSlcclxuICAgICAgICAgICAgaWYgKCh2YWwgJiAoMSA8PCBiaXQpKSAhPSAwKVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaGlnaCAhPSAwID8gYml0ICsgMzMgOiBiaXQgKyAxO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB6ZXJvLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuaXNaZXJvID0gZnVuY3Rpb24gaXNaZXJvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2ggPT09IDAgJiYgdGhpcy5sb3cgPT09IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbmVnYXRpdmUuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5pc05lZ2F0aXZlID0gZnVuY3Rpb24gaXNOZWdhdGl2ZSgpIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMudW5zaWduZWQgJiYgdGhpcy5oaWdoIDwgMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBwb3NpdGl2ZS5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmlzUG9zaXRpdmUgPSBmdW5jdGlvbiBpc1Bvc2l0aXZlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnVuc2lnbmVkIHx8IHRoaXMuaGlnaCA+PSAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG9kZC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmlzT2RkID0gZnVuY3Rpb24gaXNPZGQoKSB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAxO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGV2ZW4uXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5pc0V2ZW4gPSBmdW5jdGlvbiBpc0V2ZW4oKSB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMob3RoZXIpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgICAgICBpZiAodGhpcy51bnNpZ25lZCAhPT0gb3RoZXIudW5zaWduZWQgJiYgKHRoaXMuaGlnaCA+Pj4gMzEpID09PSAxICYmIChvdGhlci5oaWdoID4+PiAzMSkgPT09IDEpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWdoID09PSBvdGhlci5oaWdoICYmIHRoaXMubG93ID09PSBvdGhlci5sb3c7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNlcXVhbHN9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5lcSA9IExvbmdQcm90b3R5cGUuZXF1YWxzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBzcGVjaWZpZWQncy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm5vdEVxdWFscyA9IGZ1bmN0aW9uIG5vdEVxdWFscyhvdGhlcikge1xyXG4gICAgICAgIHJldHVybiAhdGhpcy5lcSgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubmVxID0gTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubGVzc1RoYW4gPSBmdW5jdGlvbiBsZXNzVGhhbihvdGhlcikge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA8IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmx0ID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBsZXNzVGhhbk9yRXF1YWwob3RoZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPD0gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFuT3JFcXVhbH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmx0ZSA9IExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQncy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuID0gZnVuY3Rpb24gZ3JlYXRlclRoYW4ob3RoZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPiAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW59LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5ndCA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsID0gZnVuY3Rpb24gZ3JlYXRlclRoYW5PckVxdWFsKG90aGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID49IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbk9yRXF1YWx9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5ndGUgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbXBhcmVzIHRoaXMgTG9uZydzIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxyXG4gICAgICogIGlmIHRoZSBnaXZlbiBvbmUgaXMgZ3JlYXRlclxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICAgICAgaWYgKHRoaXMuZXEob3RoZXIpKVxyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB2YXIgdGhpc05lZyA9IHRoaXMuaXNOZWdhdGl2ZSgpLFxyXG4gICAgICAgICAgICBvdGhlck5lZyA9IG90aGVyLmlzTmVnYXRpdmUoKTtcclxuICAgICAgICBpZiAodGhpc05lZyAmJiAhb3RoZXJOZWcpXHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICBpZiAoIXRoaXNOZWcgJiYgb3RoZXJOZWcpXHJcbiAgICAgICAgICAgIHJldHVybiAxO1xyXG4gICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHNpZ24gYml0cyBhcmUgdGhlIHNhbWVcclxuICAgICAgICBpZiAoIXRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN1YihvdGhlcikuaXNOZWdhdGl2ZSgpID8gLTEgOiAxO1xyXG4gICAgICAgIC8vIEJvdGggYXJlIHBvc2l0aXZlIGlmIGF0IGxlYXN0IG9uZSBpcyB1bnNpZ25lZFxyXG4gICAgICAgIHJldHVybiAob3RoZXIuaGlnaCA+Pj4gMCkgPiAodGhpcy5oaWdoID4+PiAwKSB8fCAob3RoZXIuaGlnaCA9PT0gdGhpcy5oaWdoICYmIChvdGhlci5sb3cgPj4+IDApID4gKHRoaXMubG93ID4+PiAwKSkgPyAtMSA6IDE7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY29tcGFyZX0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcclxuICAgICAqICBpZiB0aGUgZ2l2ZW4gb25lIGlzIGdyZWF0ZXJcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5jb21wID0gTG9uZ1Byb3RvdHlwZS5jb21wYXJlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS5cclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubmVnYXRlID0gZnVuY3Rpb24gbmVnYXRlKCkge1xyXG4gICAgICAgIGlmICghdGhpcy51bnNpZ25lZCAmJiB0aGlzLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgIHJldHVybiBNSU5fVkFMVUU7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubm90KCkuYWRkKE9ORSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNuZWdhdGV9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IE5lZ2F0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm5lZyA9IExvbmdQcm90b3R5cGUubmVnYXRlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgc3VtIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gYWRkZW5kIEFkZGVuZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTdW1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQoYWRkZW5kKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcoYWRkZW5kKSlcclxuICAgICAgICAgICAgYWRkZW5kID0gZnJvbVZhbHVlKGFkZGVuZCk7XHJcblxyXG4gICAgICAgIC8vIERpdmlkZSBlYWNoIG51bWJlciBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIHN1bSB0aGUgY2h1bmtzLlxyXG5cclxuICAgICAgICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xyXG4gICAgICAgIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYjQ4ID0gYWRkZW5kLmhpZ2ggPj4+IDE2O1xyXG4gICAgICAgIHZhciBiMzIgPSBhZGRlbmQuaGlnaCAmIDB4RkZGRjtcclxuICAgICAgICB2YXIgYjE2ID0gYWRkZW5kLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGIwMCA9IGFkZGVuZC5sb3cgJiAweEZGRkY7XHJcblxyXG4gICAgICAgIHZhciBjNDggPSAwLCBjMzIgPSAwLCBjMTYgPSAwLCBjMDAgPSAwO1xyXG4gICAgICAgIGMwMCArPSBhMDAgKyBiMDA7XHJcbiAgICAgICAgYzE2ICs9IGMwMCA+Pj4gMTY7XHJcbiAgICAgICAgYzAwICY9IDB4RkZGRjtcclxuICAgICAgICBjMTYgKz0gYTE2ICsgYjE2O1xyXG4gICAgICAgIGMzMiArPSBjMTYgPj4+IDE2O1xyXG4gICAgICAgIGMxNiAmPSAweEZGRkY7XHJcbiAgICAgICAgYzMyICs9IGEzMiArIGIzMjtcclxuICAgICAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgICAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgICAgIGM0OCArPSBhNDggKyBiNDg7XHJcbiAgICAgICAgYzQ4ICY9IDB4RkZGRjtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMoKGMxNiA8PCAxNikgfCBjMDAsIChjNDggPDwgMTYpIHwgYzMyLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gc3VidHJhaGVuZCBTdWJ0cmFoZW5kXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IERpZmZlcmVuY2VcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdCA9IGZ1bmN0aW9uIHN1YnRyYWN0KHN1YnRyYWhlbmQpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhzdWJ0cmFoZW5kKSlcclxuICAgICAgICAgICAgc3VidHJhaGVuZCA9IGZyb21WYWx1ZShzdWJ0cmFoZW5kKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5hZGQoc3VidHJhaGVuZC5uZWcoKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc3VidHJhY3R9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc3ViID0gTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUHJvZHVjdFxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm11bHRpcGx5ID0gZnVuY3Rpb24gbXVsdGlwbHkobXVsdGlwbGllcikge1xyXG4gICAgICAgIGlmICh0aGlzLmlzWmVybygpKVxyXG4gICAgICAgICAgICByZXR1cm4gWkVSTztcclxuICAgICAgICBpZiAoIWlzTG9uZyhtdWx0aXBsaWVyKSlcclxuICAgICAgICAgICAgbXVsdGlwbGllciA9IGZyb21WYWx1ZShtdWx0aXBsaWVyKTtcclxuICAgICAgICBpZiAobXVsdGlwbGllci5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuIFpFUk87XHJcbiAgICAgICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgcmV0dXJuIG11bHRpcGxpZXIuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XHJcbiAgICAgICAgaWYgKG11bHRpcGxpZXIuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xyXG4gICAgICAgICAgICBpZiAobXVsdGlwbGllci5pc05lZ2F0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5tdWwobXVsdGlwbGllci5uZWcoKSk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5lZygpLm11bChtdWx0aXBsaWVyKS5uZWcoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKG11bHRpcGxpZXIuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5tdWwobXVsdGlwbGllci5uZWcoKSkubmVnKCk7XHJcblxyXG4gICAgICAgIC8vIElmIGJvdGggbG9uZ3MgYXJlIHNtYWxsLCB1c2UgZmxvYXQgbXVsdGlwbGljYXRpb25cclxuICAgICAgICBpZiAodGhpcy5sdChUV09fUFdSXzI0KSAmJiBtdWx0aXBsaWVyLmx0KFRXT19QV1JfMjQpKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLnRvTnVtYmVyKCkgKiBtdWx0aXBsaWVyLnRvTnVtYmVyKCksIHRoaXMudW5zaWduZWQpO1xyXG5cclxuICAgICAgICAvLyBEaXZpZGUgZWFjaCBsb25nIGludG8gNCBjaHVua3Mgb2YgMTYgYml0cywgYW5kIHRoZW4gYWRkIHVwIDR4NCBwcm9kdWN0cy5cclxuICAgICAgICAvLyBXZSBjYW4gc2tpcCBwcm9kdWN0cyB0aGF0IHdvdWxkIG92ZXJmbG93LlxyXG5cclxuICAgICAgICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xyXG4gICAgICAgIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYjQ4ID0gbXVsdGlwbGllci5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYjMyID0gbXVsdGlwbGllci5oaWdoICYgMHhGRkZGO1xyXG4gICAgICAgIHZhciBiMTYgPSBtdWx0aXBsaWVyLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGIwMCA9IG11bHRpcGxpZXIubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYzQ4ID0gMCwgYzMyID0gMCwgYzE2ID0gMCwgYzAwID0gMDtcclxuICAgICAgICBjMDAgKz0gYTAwICogYjAwO1xyXG4gICAgICAgIGMxNiArPSBjMDAgPj4+IDE2O1xyXG4gICAgICAgIGMwMCAmPSAweEZGRkY7XHJcbiAgICAgICAgYzE2ICs9IGExNiAqIGIwMDtcclxuICAgICAgICBjMzIgKz0gYzE2ID4+PiAxNjtcclxuICAgICAgICBjMTYgJj0gMHhGRkZGO1xyXG4gICAgICAgIGMxNiArPSBhMDAgKiBiMTY7XHJcbiAgICAgICAgYzMyICs9IGMxNiA+Pj4gMTY7XHJcbiAgICAgICAgYzE2ICY9IDB4RkZGRjtcclxuICAgICAgICBjMzIgKz0gYTMyICogYjAwO1xyXG4gICAgICAgIGM0OCArPSBjMzIgPj4+IDE2O1xyXG4gICAgICAgIGMzMiAmPSAweEZGRkY7XHJcbiAgICAgICAgYzMyICs9IGExNiAqIGIxNjtcclxuICAgICAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgICAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgICAgIGMzMiArPSBhMDAgKiBiMzI7XHJcbiAgICAgICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICAgICAgYzMyICY9IDB4RkZGRjtcclxuICAgICAgICBjNDggKz0gYTQ4ICogYjAwICsgYTMyICogYjE2ICsgYTE2ICogYjMyICsgYTAwICogYjQ4O1xyXG4gICAgICAgIGM0OCAmPSAweEZGRkY7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKChjMTYgPDwgMTYpIHwgYzAwLCAoYzQ4IDw8IDE2KSB8IGMzMiwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgcHJvZHVjdCBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbXVsdGlwbHl9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG11bHRpcGxpZXIgTXVsdGlwbGllclxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBQcm9kdWN0XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubXVsID0gTG9uZ1Byb3RvdHlwZS5tdWx0aXBseTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhlIHJlc3VsdCBpcyBzaWduZWQgaWYgdGhpcyBMb25nIGlzIHNpZ25lZCBvclxyXG4gICAgICogIHVuc2lnbmVkIGlmIHRoaXMgTG9uZyBpcyB1bnNpZ25lZC5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZGl2aWRlID0gZnVuY3Rpb24gZGl2aWRlKGRpdmlzb3IpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhkaXZpc29yKSlcclxuICAgICAgICAgICAgZGl2aXNvciA9IGZyb21WYWx1ZShkaXZpc29yKTtcclxuICAgICAgICBpZiAoZGl2aXNvci5pc1plcm8oKSlcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2RpdmlzaW9uIGJ5IHplcm8nKTtcclxuICAgICAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XHJcbiAgICAgICAgdmFyIGFwcHJveCwgcmVtLCByZXM7XHJcbiAgICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkKSB7XHJcbiAgICAgICAgICAgIC8vIFRoaXMgc2VjdGlvbiBpcyBvbmx5IHJlbGV2YW50IGZvciBzaWduZWQgbG9uZ3MgYW5kIGlzIGRlcml2ZWQgZnJvbSB0aGVcclxuICAgICAgICAgICAgLy8gY2xvc3VyZSBsaWJyYXJ5IGFzIGEgd2hvbGUuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChkaXZpc29yLmVxKE9ORSkgfHwgZGl2aXNvci5lcShORUdfT05FKSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTUlOX1ZBTFVFOyAgLy8gcmVjYWxsIHRoYXQgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUVcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRpdmlzb3IuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gT05FO1xyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgd2UgaGF2ZSB8b3RoZXJ8ID49IDIsIHNvIHx0aGlzL290aGVyfCA8IHxNSU5fVkFMVUV8LlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYWxmVGhpcyA9IHRoaXMuc2hyKDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFwcHJveCA9IGhhbGZUaGlzLmRpdihkaXZpc29yKS5zaGwoMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFwcHJveC5lcShaRVJPKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGl2aXNvci5pc05lZ2F0aXZlKCkgPyBPTkUgOiBORUdfT05FO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbSA9IHRoaXMuc3ViKGRpdmlzb3IubXVsKGFwcHJveCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXMgPSBhcHByb3guYWRkKHJlbS5kaXYoZGl2aXNvcikpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkuZGl2KGRpdmlzb3IubmVnKCkpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkuZGl2KGRpdmlzb3IpLm5lZygpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGl2KGRpdmlzb3IubmVnKCkpLm5lZygpO1xyXG4gICAgICAgICAgICByZXMgPSBaRVJPO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFRoZSBhbGdvcml0aG0gYmVsb3cgaGFzIG5vdCBiZWVuIG1hZGUgZm9yIHVuc2lnbmVkIGxvbmdzLiBJdCdzIHRoZXJlZm9yZVxyXG4gICAgICAgICAgICAvLyByZXF1aXJlZCB0byB0YWtlIHNwZWNpYWwgY2FyZSBvZiB0aGUgTVNCIHByaW9yIHRvIHJ1bm5pbmcgaXQuXHJcbiAgICAgICAgICAgIGlmICghZGl2aXNvci51bnNpZ25lZClcclxuICAgICAgICAgICAgICAgIGRpdmlzb3IgPSBkaXZpc29yLnRvVW5zaWduZWQoKTtcclxuICAgICAgICAgICAgaWYgKGRpdmlzb3IuZ3QodGhpcykpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVVpFUk87XHJcbiAgICAgICAgICAgIGlmIChkaXZpc29yLmd0KHRoaXMuc2hydSgxKSkpIC8vIDE1ID4+PiAxID0gNyA7IHdpdGggZGl2aXNvciA9IDggOyB0cnVlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVU9ORTtcclxuICAgICAgICAgICAgcmVzID0gVVpFUk87XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZXBlYXQgdGhlIGZvbGxvd2luZyB1bnRpbCB0aGUgcmVtYWluZGVyIGlzIGxlc3MgdGhhbiBvdGhlcjogIGZpbmQgYVxyXG4gICAgICAgIC8vIGZsb2F0aW5nLXBvaW50IHRoYXQgYXBwcm94aW1hdGVzIHJlbWFpbmRlciAvIG90aGVyICpmcm9tIGJlbG93KiwgYWRkIHRoaXNcclxuICAgICAgICAvLyBpbnRvIHRoZSByZXN1bHQsIGFuZCBzdWJ0cmFjdCBpdCBmcm9tIHRoZSByZW1haW5kZXIuICBJdCBpcyBjcml0aWNhbCB0aGF0XHJcbiAgICAgICAgLy8gdGhlIGFwcHJveGltYXRlIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgcmVhbCB2YWx1ZSBzbyB0aGF0IHRoZVxyXG4gICAgICAgIC8vIHJlbWFpbmRlciBuZXZlciBiZWNvbWVzIG5lZ2F0aXZlLlxyXG4gICAgICAgIHJlbSA9IHRoaXM7XHJcbiAgICAgICAgd2hpbGUgKHJlbS5ndGUoZGl2aXNvcikpIHtcclxuICAgICAgICAgICAgLy8gQXBwcm94aW1hdGUgdGhlIHJlc3VsdCBvZiBkaXZpc2lvbi4gVGhpcyBtYXkgYmUgYSBsaXR0bGUgZ3JlYXRlciBvclxyXG4gICAgICAgICAgICAvLyBzbWFsbGVyIHRoYW4gdGhlIGFjdHVhbCB2YWx1ZS5cclxuICAgICAgICAgICAgYXBwcm94ID0gTWF0aC5tYXgoMSwgTWF0aC5mbG9vcihyZW0udG9OdW1iZXIoKSAvIGRpdmlzb3IudG9OdW1iZXIoKSkpO1xyXG5cclxuICAgICAgICAgICAgLy8gV2Ugd2lsbCB0d2VhayB0aGUgYXBwcm94aW1hdGUgcmVzdWx0IGJ5IGNoYW5naW5nIGl0IGluIHRoZSA0OC10aCBkaWdpdCBvclxyXG4gICAgICAgICAgICAvLyB0aGUgc21hbGxlc3Qgbm9uLWZyYWN0aW9uYWwgZGlnaXQsIHdoaWNoZXZlciBpcyBsYXJnZXIuXHJcbiAgICAgICAgICAgIHZhciBsb2cyID0gTWF0aC5jZWlsKE1hdGgubG9nKGFwcHJveCkgLyBNYXRoLkxOMiksXHJcbiAgICAgICAgICAgICAgICBkZWx0YSA9IChsb2cyIDw9IDQ4KSA/IDEgOiBwb3dfZGJsKDIsIGxvZzIgLSA0OCksXHJcblxyXG4gICAgICAgICAgICAvLyBEZWNyZWFzZSB0aGUgYXBwcm94aW1hdGlvbiB1bnRpbCBpdCBpcyBzbWFsbGVyIHRoYW4gdGhlIHJlbWFpbmRlci4gIE5vdGVcclxuICAgICAgICAgICAgLy8gdGhhdCBpZiBpdCBpcyB0b28gbGFyZ2UsIHRoZSBwcm9kdWN0IG92ZXJmbG93cyBhbmQgaXMgbmVnYXRpdmUuXHJcbiAgICAgICAgICAgICAgICBhcHByb3hSZXMgPSBmcm9tTnVtYmVyKGFwcHJveCksXHJcbiAgICAgICAgICAgICAgICBhcHByb3hSZW0gPSBhcHByb3hSZXMubXVsKGRpdmlzb3IpO1xyXG4gICAgICAgICAgICB3aGlsZSAoYXBwcm94UmVtLmlzTmVnYXRpdmUoKSB8fCBhcHByb3hSZW0uZ3QocmVtKSkge1xyXG4gICAgICAgICAgICAgICAgYXBwcm94IC09IGRlbHRhO1xyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVzID0gZnJvbU51bWJlcihhcHByb3gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gV2Uga25vdyB0aGUgYW5zd2VyIGNhbid0IGJlIHplcm8uLi4gYW5kIGFjdHVhbGx5LCB6ZXJvIHdvdWxkIGNhdXNlXHJcbiAgICAgICAgICAgIC8vIGluZmluaXRlIHJlY3Vyc2lvbiBzaW5jZSB3ZSB3b3VsZCBtYWtlIG5vIHByb2dyZXNzLlxyXG4gICAgICAgICAgICBpZiAoYXBwcm94UmVzLmlzWmVybygpKVxyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVzID0gT05FO1xyXG5cclxuICAgICAgICAgICAgcmVzID0gcmVzLmFkZChhcHByb3hSZXMpO1xyXG4gICAgICAgICAgICByZW0gPSByZW0uc3ViKGFwcHJveFJlbSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgZGl2aWRlZCBieSB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2RpdmlkZX0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZGl2ID0gTG9uZ1Byb3RvdHlwZS5kaXZpZGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm1vZHVsbyA9IGZ1bmN0aW9uIG1vZHVsbyhkaXZpc29yKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcoZGl2aXNvcikpXHJcbiAgICAgICAgICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViKHRoaXMuZGl2KGRpdmlzb3IpLm11bChkaXZpc29yKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbW9kdWxvfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubW9kID0gTG9uZ1Byb3RvdHlwZS5tb2R1bG87XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBiaXR3aXNlIE5PVCBvZiB0aGlzIExvbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubm90ID0gZnVuY3Rpb24gbm90KCkge1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh+dGhpcy5sb3csIH50aGlzLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGJpdHdpc2UgQU5EIG9mIHRoaXMgTG9uZyBhbmQgdGhlIHNwZWNpZmllZC5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmFuZCA9IGZ1bmN0aW9uIGFuZChvdGhlcikge1xyXG4gICAgICAgIGlmICghaXNMb25nKG90aGVyKSlcclxuICAgICAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyAmIG90aGVyLmxvdywgdGhpcy5oaWdoICYgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgYml0d2lzZSBPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5vciA9IGZ1bmN0aW9uIG9yKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IHwgb3RoZXIubG93LCB0aGlzLmhpZ2ggfCBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBiaXR3aXNlIFhPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBnaXZlbiBvbmUuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS54b3IgPSBmdW5jdGlvbiB4b3Iob3RoZXIpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgXiBvdGhlci5sb3csIHRoaXMuaGlnaCBeIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQgPSBmdW5jdGlvbiBzaGlmdExlZnQobnVtQml0cykge1xyXG4gICAgICAgIGlmIChpc0xvbmcobnVtQml0cykpXHJcbiAgICAgICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICAgICAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgPDwgbnVtQml0cywgKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gKDMyIC0gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tQml0cygwLCB0aGlzLmxvdyA8PCAobnVtQml0cyAtIDMyKSwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHNoaWZ0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdExlZnR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaGwgPSBMb25nUHJvdG90eXBlLnNoaWZ0TGVmdDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc2hpZnRSaWdodCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHQobnVtQml0cykge1xyXG4gICAgICAgIGlmIChpc0xvbmcobnVtQml0cykpXHJcbiAgICAgICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICAgICAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoKHRoaXMubG93ID4+PiBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPDwgKDMyIC0gbnVtQml0cykpLCB0aGlzLmhpZ2ggPj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoID4+IChudW1CaXRzIC0gMzIpLCB0aGlzLmhpZ2ggPj0gMCA/IDAgOiAtMSwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnNociA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHRVbnNpZ25lZChudW1CaXRzKSB7XHJcbiAgICAgICAgaWYgKGlzTG9uZyhudW1CaXRzKSlcclxuICAgICAgICAgICAgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcclxuICAgICAgICBudW1CaXRzICY9IDYzO1xyXG4gICAgICAgIGlmIChudW1CaXRzID09PSAwKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdmFyIGhpZ2ggPSB0aGlzLmhpZ2g7XHJcbiAgICAgICAgICAgIGlmIChudW1CaXRzIDwgMzIpIHtcclxuICAgICAgICAgICAgICAgIHZhciBsb3cgPSB0aGlzLmxvdztcclxuICAgICAgICAgICAgICAgIHJldHVybiBmcm9tQml0cygobG93ID4+PiBudW1CaXRzKSB8IChoaWdoIDw8ICgzMiAtIG51bUJpdHMpKSwgaGlnaCA+Pj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobnVtQml0cyA9PT0gMzIpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoaGlnaCwgMCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiBmcm9tQml0cyhoaWdoID4+PiAobnVtQml0cyAtIDMyKSwgMCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdFJpZ2h0VW5zaWduZWR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaHJ1ID0gTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gc2lnbmVkLlxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvU2lnbmVkID0gZnVuY3Rpb24gdG9TaWduZWQoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgZmFsc2UpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byB1bnNpZ25lZC5cclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gVW5zaWduZWQgbG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvVW5zaWduZWQgPSBmdW5jdGlvbiB0b1Vuc2lnbmVkKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgdHJ1ZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGUgV2hldGhlciBsaXR0bGUgb3IgYmlnIGVuZGlhbiwgZGVmYXVsdHMgdG8gYmlnIGVuZGlhblxyXG4gICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQnl0ZSByZXByZXNlbnRhdGlvblxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvQnl0ZXMgPSBmdW5jdGlvbihsZSkge1xyXG4gICAgICAgIHJldHVybiBsZSA/IHRoaXMudG9CeXRlc0xFKCkgOiB0aGlzLnRvQnl0ZXNCRSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBsaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b0J5dGVzTEUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgaGkgPSB0aGlzLmhpZ2gsXHJcbiAgICAgICAgICAgIGxvID0gdGhpcy5sb3c7XHJcbiAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgIGxvICAgICAgICAgJiAweGZmLFxyXG4gICAgICAgICAgICAobG8gPj4+ICA4KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChsbyA+Pj4gMTYpICYgMHhmZixcclxuICAgICAgICAgICAgKGxvID4+PiAyNCkgJiAweGZmLFxyXG4gICAgICAgICAgICAgaGkgICAgICAgICAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChoaSA+Pj4gIDgpICYgMHhmZixcclxuICAgICAgICAgICAgKGhpID4+PiAxNikgJiAweGZmLFxyXG4gICAgICAgICAgICAoaGkgPj4+IDI0KSAmIDB4ZmZcclxuICAgICAgICBdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBiaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBCaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b0J5dGVzQkUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgaGkgPSB0aGlzLmhpZ2gsXHJcbiAgICAgICAgICAgIGxvID0gdGhpcy5sb3c7XHJcbiAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgKGhpID4+PiAyNCkgJiAweGZmLFxyXG4gICAgICAgICAgICAoaGkgPj4+IDE2KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChoaSA+Pj4gIDgpICYgMHhmZixcclxuICAgICAgICAgICAgIGhpICAgICAgICAgJiAweGZmLFxyXG4gICAgICAgICAgICAobG8gPj4+IDI0KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChsbyA+Pj4gMTYpICYgMHhmZixcclxuICAgICAgICAgICAgKGxvID4+PiAgOCkgJiAweGZmLFxyXG4gICAgICAgICAgICAgbG8gICAgICAgICAmIDB4ZmZcclxuICAgICAgICBdO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBMb25nO1xyXG59KTtcclxuIiwiJ3VzZSBzdHJpY3QnXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaEJhc2UgPSByZXF1aXJlKCdoYXNoLWJhc2UnKVxuXG52YXIgQVJSQVkxNiA9IG5ldyBBcnJheSgxNilcblxuZnVuY3Rpb24gTUQ1ICgpIHtcbiAgSGFzaEJhc2UuY2FsbCh0aGlzLCA2NClcblxuICAvLyBzdGF0ZVxuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxufVxuXG5pbmhlcml0cyhNRDUsIEhhc2hCYXNlKVxuXG5NRDUucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBNID0gQVJSQVkxNlxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIE1baV0gPSB0aGlzLl9ibG9jay5yZWFkSW50MzJMRShpICogNClcblxuICB2YXIgYSA9IHRoaXMuX2FcbiAgdmFyIGIgPSB0aGlzLl9iXG4gIHZhciBjID0gdGhpcy5fY1xuICB2YXIgZCA9IHRoaXMuX2RcblxuICBhID0gZm5GKGEsIGIsIGMsIGQsIE1bMF0sIDB4ZDc2YWE0NzgsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxXSwgMHhlOGM3Yjc1NiwgMTIpXG4gIGMgPSBmbkYoYywgZCwgYSwgYiwgTVsyXSwgMHgyNDIwNzBkYiwgMTcpXG4gIGIgPSBmbkYoYiwgYywgZCwgYSwgTVszXSwgMHhjMWJkY2VlZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVs0XSwgMHhmNTdjMGZhZiwgNylcbiAgZCA9IGZuRihkLCBhLCBiLCBjLCBNWzVdLCAweDQ3ODdjNjJhLCAxMilcbiAgYyA9IGZuRihjLCBkLCBhLCBiLCBNWzZdLCAweGE4MzA0NjEzLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzddLCAweGZkNDY5NTAxLCAyMilcbiAgYSA9IGZuRihhLCBiLCBjLCBkLCBNWzhdLCAweDY5ODA5OGQ4LCA3KVxuICBkID0gZm5GKGQsIGEsIGIsIGMsIE1bOV0sIDB4OGI0NGY3YWYsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTBdLCAweGZmZmY1YmIxLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzExXSwgMHg4OTVjZDdiZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVsxMl0sIDB4NmI5MDExMjIsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxM10sIDB4ZmQ5ODcxOTMsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTRdLCAweGE2Nzk0MzhlLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzE1XSwgMHg0OWI0MDgyMSwgMjIpXG5cbiAgYSA9IGZuRyhhLCBiLCBjLCBkLCBNWzFdLCAweGY2MWUyNTYyLCA1KVxuICBkID0gZm5HKGQsIGEsIGIsIGMsIE1bNl0sIDB4YzA0MGIzNDAsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxMV0sIDB4MjY1ZTVhNTEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bMF0sIDB4ZTliNmM3YWEsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bNV0sIDB4ZDYyZjEwNWQsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxMF0sIDB4MDI0NDE0NTMsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxNV0sIDB4ZDhhMWU2ODEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bNF0sIDB4ZTdkM2ZiYzgsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bOV0sIDB4MjFlMWNkZTYsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxNF0sIDB4YzMzNzA3ZDYsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVszXSwgMHhmNGQ1MGQ4NywgMTQpXG4gIGIgPSBmbkcoYiwgYywgZCwgYSwgTVs4XSwgMHg0NTVhMTRlZCwgMjApXG4gIGEgPSBmbkcoYSwgYiwgYywgZCwgTVsxM10sIDB4YTllM2U5MDUsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsyXSwgMHhmY2VmYTNmOCwgOSlcbiAgYyA9IGZuRyhjLCBkLCBhLCBiLCBNWzddLCAweDY3NmYwMmQ5LCAxNClcbiAgYiA9IGZuRyhiLCBjLCBkLCBhLCBNWzEyXSwgMHg4ZDJhNGM4YSwgMjApXG5cbiAgYSA9IGZuSChhLCBiLCBjLCBkLCBNWzVdLCAweGZmZmEzOTQyLCA0KVxuICBkID0gZm5IKGQsIGEsIGIsIGMsIE1bOF0sIDB4ODc3MWY2ODEsIDExKVxuICBjID0gZm5IKGMsIGQsIGEsIGIsIE1bMTFdLCAweDZkOWQ2MTIyLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzE0XSwgMHhmZGU1MzgwYywgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxXSwgMHhhNGJlZWE0NCwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzRdLCAweDRiZGVjZmE5LCAxMSlcbiAgYyA9IGZuSChjLCBkLCBhLCBiLCBNWzddLCAweGY2YmI0YjYwLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzEwXSwgMHhiZWJmYmM3MCwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxM10sIDB4Mjg5YjdlYzYsIDQpXG4gIGQgPSBmbkgoZCwgYSwgYiwgYywgTVswXSwgMHhlYWExMjdmYSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVszXSwgMHhkNGVmMzA4NSwgMTYpXG4gIGIgPSBmbkgoYiwgYywgZCwgYSwgTVs2XSwgMHgwNDg4MWQwNSwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVs5XSwgMHhkOWQ0ZDAzOSwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzEyXSwgMHhlNmRiOTllNSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVsxNV0sIDB4MWZhMjdjZjgsIDE2KVxuICBiID0gZm5IKGIsIGMsIGQsIGEsIE1bMl0sIDB4YzRhYzU2NjUsIDIzKVxuXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVswXSwgMHhmNDI5MjI0NCwgNilcbiAgZCA9IGZuSShkLCBhLCBiLCBjLCBNWzddLCAweDQzMmFmZjk3LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzE0XSwgMHhhYjk0MjNhNywgMTUpXG4gIGIgPSBmbkkoYiwgYywgZCwgYSwgTVs1XSwgMHhmYzkzYTAzOSwgMjEpXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVsxMl0sIDB4NjU1YjU5YzMsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVszXSwgMHg4ZjBjY2M5MiwgMTApXG4gIGMgPSBmbkkoYywgZCwgYSwgYiwgTVsxMF0sIDB4ZmZlZmY0N2QsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMV0sIDB4ODU4NDVkZDEsIDIxKVxuICBhID0gZm5JKGEsIGIsIGMsIGQsIE1bOF0sIDB4NmZhODdlNGYsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVsxNV0sIDB4ZmUyY2U2ZTAsIDEwKVxuICBjID0gZm5JKGMsIGQsIGEsIGIsIE1bNl0sIDB4YTMwMTQzMTQsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMTNdLCAweDRlMDgxMWExLCAyMSlcbiAgYSA9IGZuSShhLCBiLCBjLCBkLCBNWzRdLCAweGY3NTM3ZTgyLCA2KVxuICBkID0gZm5JKGQsIGEsIGIsIGMsIE1bMTFdLCAweGJkM2FmMjM1LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzJdLCAweDJhZDdkMmJiLCAxNSlcbiAgYiA9IGZuSShiLCBjLCBkLCBhLCBNWzldLCAweGViODZkMzkxLCAyMSlcblxuICB0aGlzLl9hID0gKHRoaXMuX2EgKyBhKSB8IDBcbiAgdGhpcy5fYiA9ICh0aGlzLl9iICsgYikgfCAwXG4gIHRoaXMuX2MgPSAodGhpcy5fYyArIGMpIHwgMFxuICB0aGlzLl9kID0gKHRoaXMuX2QgKyBkKSB8IDBcbn1cblxuTUQ1LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gKCkge1xuICAvLyBjcmVhdGUgcGFkZGluZyBhbmQgaGFuZGxlIGJsb2Nrc1xuICB0aGlzLl9ibG9ja1t0aGlzLl9ibG9ja09mZnNldCsrXSA9IDB4ODBcbiAgaWYgKHRoaXMuX2Jsb2NrT2Zmc2V0ID4gNTYpIHtcbiAgICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA2NClcbiAgICB0aGlzLl91cGRhdGUoKVxuICAgIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB9XG5cbiAgdGhpcy5fYmxvY2suZmlsbCgwLCB0aGlzLl9ibG9ja09mZnNldCwgNTYpXG4gIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyTEUodGhpcy5fbGVuZ3RoWzBdLCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMV0sIDYwKVxuICB0aGlzLl91cGRhdGUoKVxuXG4gIC8vIHByb2R1Y2UgcmVzdWx0XG4gIHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKDE2KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2EsIDApXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYiwgNClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9jLCA4KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2QsIDEyKVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIHJvdGwgKHgsIG4pIHtcbiAgcmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKVxufVxuXG5mdW5jdGlvbiBmbkYgKGEsIGIsIGMsIGQsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiICYgYykgfCAoKH5iKSAmIGQpKSArIG0gKyBrKSB8IDAsIHMpICsgYikgfCAwXG59XG5cbmZ1bmN0aW9uIGZuRyAoYSwgYiwgYywgZCwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgJiBkKSB8IChjICYgKH5kKSkpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxuZnVuY3Rpb24gZm5IIChhLCBiLCBjLCBkLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArIChiIF4gYyBeIGQpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxuZnVuY3Rpb24gZm5JIChhLCBiLCBjLCBkLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYyBeIChiIHwgKH5kKSkpKSArIG0gKyBrKSB8IDAsIHMpICsgYikgfCAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gTUQ1XG4iLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLk1hbmFnZXIgPSBleHBvcnRzLkNoYWluQ29uZmlnID0gZXhwb3J0cy5BcGlzID0gdW5kZWZpbmVkO1xuXG52YXIgX0FwaUluc3RhbmNlcyA9IHJlcXVpcmUoNzEpO1xuXG52YXIgX0FwaUluc3RhbmNlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9BcGlJbnN0YW5jZXMpO1xuXG52YXIgX0Nvbm5lY3Rpb25NYW5hZ2VyID0gcmVxdWlyZSg3NCk7XG5cbnZhciBfQ29ubmVjdGlvbk1hbmFnZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ29ubmVjdGlvbk1hbmFnZXIpO1xuXG52YXIgX0NoYWluQ29uZmlnID0gcmVxdWlyZSg3Mik7XG5cbnZhciBfQ2hhaW5Db25maWcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2hhaW5Db25maWcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5leHBvcnRzLkFwaXMgPSBfQXBpSW5zdGFuY2VzMi5kZWZhdWx0O1xuZXhwb3J0cy5DaGFpbkNvbmZpZyA9IF9DaGFpbkNvbmZpZzIuZGVmYXVsdDtcbmV4cG9ydHMuTWFuYWdlciA9IF9Db25uZWN0aW9uTWFuYWdlcjIuZGVmYXVsdDsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfQ2hhaW5XZWJTb2NrZXQgPSByZXF1aXJlKDczKTtcblxudmFyIF9DaGFpbldlYlNvY2tldDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpbldlYlNvY2tldCk7XG5cbnZhciBfR3JhcGhlbmVBcGkgPSByZXF1aXJlKDc1KTtcblxudmFyIF9HcmFwaGVuZUFwaTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9HcmFwaGVuZUFwaSk7XG5cbnZhciBfQ2hhaW5Db25maWcgPSByZXF1aXJlKDcyKTtcblxudmFyIF9DaGFpbkNvbmZpZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpbkNvbmZpZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBpbnN0ID0gdm9pZCAwO1xuXG52YXIgQXBpc0luc3RhbmNlID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBBcGlzSW5zdGFuY2UoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEFwaXNJbnN0YW5jZSk7XG4gIH1cblxuICAvKiogQGFyZyB7c3RyaW5nfSBjb25uZWN0aW9uIC4uICovXG4gIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uIGNvbm5lY3QoY3MsIGNvbm5lY3RUaW1lb3V0KSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBycGNfdXNlciA9ICcnO1xuICAgIHZhciBycGNfcGFzc3dvcmQgPSAnJztcblxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cubG9jYXRpb24gJiYgd2luZG93LmxvY2F0aW9uLnByb3RvY29sID09PSAnaHR0cHM6JyAmJiBjcy5pbmRleE9mKCd3c3M6Ly8nKSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2VjdXJlIGRvbWFpbnMgcmVxdWlyZSB3c3MgY29ubmVjdGlvbicpO1xuICAgIH1cblxuICAgIHRoaXMud3NfcnBjID0gbmV3IF9DaGFpbldlYlNvY2tldDIuZGVmYXVsdChjcywgdGhpcy5zdGF0dXNDYiwgY29ubmVjdFRpbWVvdXQpO1xuXG4gICAgdGhpcy5pbml0X3Byb21pc2UgPSB0aGlzLndzX3JwYy5sb2dpbihycGNfdXNlciwgcnBjX3Bhc3N3b3JkKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdDb25uZWN0ZWQgdG8gQVBJIG5vZGU6JywgY3MpO1xuICAgICAgX3RoaXMuX2RiID0gbmV3IF9HcmFwaGVuZUFwaTIuZGVmYXVsdChfdGhpcy53c19ycGMsICdkYXRhYmFzZScpO1xuICAgICAgX3RoaXMuX25ldCA9IG5ldyBfR3JhcGhlbmVBcGkyLmRlZmF1bHQoX3RoaXMud3NfcnBjLCAnbmV0d29ya19icm9hZGNhc3QnKTtcbiAgICAgIF90aGlzLl9oaXN0ID0gbmV3IF9HcmFwaGVuZUFwaTIuZGVmYXVsdChfdGhpcy53c19ycGMsICdoaXN0b3J5Jyk7XG4gICAgICBfdGhpcy5fY3J5cHRvID0gbmV3IF9HcmFwaGVuZUFwaTIuZGVmYXVsdChfdGhpcy53c19ycGMsICdjcnlwdG8nKTtcbiAgICAgIF90aGlzLl9ib29raWUgPSBuZXcgX0dyYXBoZW5lQXBpMi5kZWZhdWx0KF90aGlzLndzX3JwYywgJ2Jvb2tpZScpO1xuICAgICAgdmFyIGRiX3Byb21pc2UgPSBfdGhpcy5fZGIuaW5pdCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gX3RoaXMuX2RiLmV4ZWMoJ2dldF9jaGFpbl9pZCcsIFtdKS50aGVuKGZ1bmN0aW9uIChfY2hhaW5faWQpIHtcbiAgICAgICAgICBfdGhpcy5jaGFpbl9pZCA9IF9jaGFpbl9pZDtcbiAgICAgICAgICByZXR1cm4gX0NoYWluQ29uZmlnMi5kZWZhdWx0LnNldENoYWluSWQoX2NoYWluX2lkKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgX3RoaXMud3NfcnBjLm9uX3JlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgX3RoaXMud3NfcnBjLmxvZ2luKCcnLCAnJykudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgX3RoaXMuX2RiLmluaXQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5zdGF0dXNDYikge1xuICAgICAgICAgICAgICBfdGhpcy5zdGF0dXNDYihfQ2hhaW5XZWJTb2NrZXQyLmRlZmF1bHQuc3RhdHVzLlJFQ09OTkVDVEVEKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBfdGhpcy5fbmV0LmluaXQoKTtcbiAgICAgICAgICBfdGhpcy5faGlzdC5pbml0KCk7XG4gICAgICAgICAgX3RoaXMuX2NyeXB0by5pbml0KCk7XG4gICAgICAgICAgX3RoaXMuX2Jvb2tpZS5pbml0KCk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtkYl9wcm9taXNlLCBfdGhpcy5fbmV0LmluaXQoKSwgX3RoaXMuX2hpc3QuaW5pdCgpLFxuICAgICAgLy8gVGVtcG9yYXJ5IHNxdWFzaCBjcnlwdG8gQVBJIGVycm9yIHVudGlsIHRoZSBBUEkgaXMgdXBncmFkZWQgZXZlcnl3aGVyZVxuICAgICAgX3RoaXMuX2NyeXB0by5pbml0KCkuY2F0Y2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoJ0FwaUluc3RhbmNlXFx0Q3J5cHRvIEFQSSBFcnJvcicsIGUpO1xuICAgICAgfSksIF90aGlzLl9ib29raWUuaW5pdCgpXSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uIGNsb3NlKCkge1xuICAgIGlmICh0aGlzLndzX3JwYykge1xuICAgICAgdGhpcy53c19ycGMuY2xvc2UoKTtcbiAgICB9XG5cbiAgICB0aGlzLndzX3JwYyA9IG51bGw7XG4gIH07XG5cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5kYl9hcGkgPSBmdW5jdGlvbiBkYl9hcGkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RiO1xuICB9O1xuXG4gIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUubmV0d29ya19hcGkgPSBmdW5jdGlvbiBuZXR3b3JrX2FwaSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbmV0O1xuICB9O1xuXG4gIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUuaGlzdG9yeV9hcGkgPSBmdW5jdGlvbiBoaXN0b3J5X2FwaSgpIHtcbiAgICByZXR1cm4gdGhpcy5faGlzdDtcbiAgfTtcblxuICBBcGlzSW5zdGFuY2UucHJvdG90eXBlLmNyeXB0b19hcGkgPSBmdW5jdGlvbiBjcnlwdG9fYXBpKCkge1xuICAgIHJldHVybiB0aGlzLl9jcnlwdG87XG4gIH07XG5cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5ib29raWVfYXBpID0gZnVuY3Rpb24gYm9va2llX2FwaSgpIHtcbiAgICByZXR1cm4gdGhpcy5fYm9va2llO1xuICB9O1xuXG4gIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUuc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrID0gZnVuY3Rpb24gc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5zdGF0dXNDYiA9IGNhbGxiYWNrO1xuICB9O1xuXG4gIHJldHVybiBBcGlzSW5zdGFuY2U7XG59KCk7XG5cbi8qKlxuICAgIENvbmZpZ3VyZTogY29uZmlndXJlIGFzIGZvbGxvd3MgYEFwaXMuaW5zdGFuY2UoXCJ3czovL2xvY2FsaG9zdDo4MDkwXCIpLmluaXRfcHJvbWlzZWAuICBUaGlzXG4gICAgcmV0dXJucyBhIHByb21pc2UsIG9uY2UgcmVzb2x2ZWQgdGhlIGNvbm5lY3Rpb24gaXMgcmVhZHkuXG5cbiAgICBJbXBvcnQ6IGltcG9ydCB7IEFwaXMgfSBmcm9tIFwiQGdyYXBoZW5lL2NoYWluXCJcblxuICAgIFNob3J0LWhhbmQ6IEFwaXMuZGIoXCJtZXRob2RcIiwgXCJwYXJtMVwiLCAyLCAzLCAuLi4pLiAgUmV0dXJucyBhIHByb21pc2Ugd2l0aCByZXN1bHRzLlxuXG4gICAgQWRkaXRpb25hbCB1c2FnZTogQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoXCJtZXRob2RcIiwgW1wibWV0aG9kXCIsIFwicGFybTFcIiwgMiwgMywgLi4uXSkuXG4gICAgUmV0dXJucyBhIHByb21pc2Ugd2l0aCByZXN1bHRzLlxuKi9cblxuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICBzZXRScGNDb25uZWN0aW9uU3RhdHVzQ2FsbGJhY2s6IGZ1bmN0aW9uIHNldFJwY0Nvbm5lY3Rpb25TdGF0dXNDYWxsYmFjayhjYWxsYmFjaykge1xuICAgIHRoaXMuc3RhdHVzQ2IgPSBjYWxsYmFjaztcblxuICAgIGlmIChpbnN0KSB7XG4gICAgICBpbnN0LnNldFJwY0Nvbm5lY3Rpb25TdGF0dXNDYWxsYmFjayhjYWxsYmFjayk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgICAgICBAYXJnIHtzdHJpbmd9IGNzIGlzIG9ubHkgcHJvdmlkZWQgaW4gdGhlIGZpcnN0IGNhbGxcbiAgICAgICAgQHJldHVybiB7QXBpc30gc2luZ2xldG9uIC4uIENoZWNrIEFwaXMuaW5zdGFuY2UoKS5pbml0X3Byb21pc2UgdG9cbiAgICAgICAga25vdyB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkXG4gICAgKi9cbiAgcmVzZXQ6IGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgIHZhciBjcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJ3dzOi8vbG9jYWxob3N0OjgwOTAnO1xuICAgIHZhciBjb25uZWN0ID0gYXJndW1lbnRzWzFdO1xuICAgIHZhciBjb25uZWN0VGltZW91dCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogNDAwMDtcblxuICAgIGlmIChpbnN0KSB7XG4gICAgICBpbnN0LmNsb3NlKCk7XG4gICAgICBpbnN0ID0gbnVsbDtcbiAgICB9XG5cbiAgICBpbnN0ID0gbmV3IEFwaXNJbnN0YW5jZSgpO1xuICAgIGluc3Quc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKHRoaXMuc3RhdHVzQ2IpO1xuXG4gICAgaWYgKGluc3QgJiYgY29ubmVjdCkge1xuICAgICAgaW5zdC5jb25uZWN0KGNzLCBjb25uZWN0VGltZW91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGluc3Q7XG4gIH0sXG4gIGluc3RhbmNlOiBmdW5jdGlvbiBpbnN0YW5jZSgpIHtcbiAgICB2YXIgY3MgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6ICd3czovL2xvY2FsaG9zdDo4MDkwJztcbiAgICB2YXIgY29ubmVjdCA9IGFyZ3VtZW50c1sxXTtcbiAgICB2YXIgY29ubmVjdFRpbWVvdXQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IDQwMDA7XG5cbiAgICBpZiAoIWluc3QpIHtcbiAgICAgIGluc3QgPSBuZXcgQXBpc0luc3RhbmNlKCk7XG4gICAgICBpbnN0LnNldFJwY0Nvbm5lY3Rpb25TdGF0dXNDYWxsYmFjayh0aGlzLnN0YXR1c0NiKTtcbiAgICB9XG5cbiAgICBpZiAoaW5zdCAmJiBjb25uZWN0KSB7XG4gICAgICBpbnN0LmNvbm5lY3QoY3MsIGNvbm5lY3RUaW1lb3V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gaW5zdDtcbiAgfSxcbiAgY2hhaW5JZDogZnVuY3Rpb24gY2hhaW5JZCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnN0YW5jZSgpLmNoYWluX2lkO1xuICB9LFxuICBjbG9zZTogZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgaWYgKGluc3QpIHtcbiAgICAgIGluc3QuY2xvc2UoKTtcbiAgICAgIGluc3QgPSBudWxsO1xuICAgIH1cbiAgfVxuICAvLyBkYjogKG1ldGhvZCwgLi4uYXJncykgPT4gQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMobWV0aG9kLCB0b1N0cmluZ3MoYXJncykpLFxuICAvLyBuZXR3b3JrOiAobWV0aG9kLCAuLi5hcmdzKSA9PiBBcGlzLmluc3RhbmNlKCkubmV0d29ya19hcGkoKS5leGVjKG1ldGhvZCwgdG9TdHJpbmdzKGFyZ3MpKSxcbiAgLy8gaGlzdG9yeTogKG1ldGhvZCwgLi4uYXJncykgPT4gQXBpcy5pbnN0YW5jZSgpLmhpc3RvcnlfYXBpKCkuZXhlYyhtZXRob2QsIHRvU3RyaW5ncyhhcmdzKSksXG4gIC8vIGNyeXB0bzogKG1ldGhvZCwgLi4uYXJncykgPT4gQXBpcy5pbnN0YW5jZSgpLmNyeXB0b19hcGkoKS5leGVjKG1ldGhvZCwgdG9TdHJpbmdzKGFyZ3MpKVxuXG59OyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIGRlZmF1bHRzID0ge1xuICBjb3JlX2Fzc2V0OiAnUFBZJyxcbiAgYWRkcmVzc19wcmVmaXg6ICdQUFknLFxuICBleHBpcmVfaW5fc2VjczogMTUsXG4gIGV4cGlyZV9pbl9zZWNzX3Byb3Bvc2FsOiAyNCAqIDYwICogNjAsXG4gIHJldmlld19pbl9zZWNzX2NvbW1pdHRlZTogMjQgKiA2MCAqIDYwXG59O1xuXG52YXIgbmV0d29ya3MgPSB7XG4gIG5ldHdvcmtzOiB7XG4gICAgUGVlcnBsYXlzOiB7XG4gICAgICBjb3JlX2Fzc2V0OiAnUFBZJyxcbiAgICAgIGFkZHJlc3NfcHJlZml4OiAnUFBZJyxcbiAgICAgIGNoYWluX2lkOiAnNmI2YjVmMGNlN2EzNmQzMjM3NjhlNTM0ZjNlZGI0MWM2ZDYzMzJhNTQxYTk1NzI1Yjk4ZTI4ZDE0MDg1MDEzNCdcbiAgICB9LFxuICAgIFBlZXJwbGF5c1Rlc3RuZXQ6IHtcbiAgICAgIGNvcmVfYXNzZXQ6ICdQUFlURVNUJyxcbiAgICAgIGFkZHJlc3NfcHJlZml4OiAnUFBZVEVTVCcsXG4gICAgICBjaGFpbl9pZDogJ2JlNmI3OTI5NWU3Mjg0MDZjYmI3NDk0YmNiNjI2ZTYyYWQyNzhmYTQwMTg2OTljZjhmNzU3MzlmNGMxYTgxZmQnXG4gICAgfVxuICB9XG59O1xuXG52YXIgQ2hhaW5Db25maWcgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIENoYWluQ29uZmlnKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDaGFpbkNvbmZpZyk7XG5cbiAgICB0aGlzLnJlc2V0KCk7XG4gIH1cblxuICBDaGFpbkNvbmZpZy5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiByZXNldCgpIHtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMsIGRlZmF1bHRzKTtcbiAgfTtcblxuICBDaGFpbkNvbmZpZy5wcm90b3R5cGUuc2V0Q2hhaW5JZCA9IGZ1bmN0aW9uIHNldENoYWluSWQoY2hhaW5JRCkge1xuICAgIHZhciByZWYgPSBPYmplY3Qua2V5cyhuZXR3b3Jrcyk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmVmLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB2YXIgbmV0d29ya19uYW1lID0gcmVmW2ldO1xuICAgICAgdmFyIG5ldHdvcmsgPSBuZXR3b3Jrc1tuZXR3b3JrX25hbWVdO1xuXG4gICAgICBpZiAobmV0d29yay5jaGFpbl9pZCA9PT0gY2hhaW5JRCkge1xuICAgICAgICB0aGlzLm5ldHdvcmtfbmFtZSA9IG5ldHdvcmtfbmFtZTtcblxuICAgICAgICBpZiAobmV0d29yay5hZGRyZXNzX3ByZWZpeCkge1xuICAgICAgICAgIHRoaXMuYWRkcmVzc19wcmVmaXggPSBuZXR3b3JrLmFkZHJlc3NfcHJlZml4O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuZXR3b3JrX25hbWU6IG5ldHdvcmtfbmFtZSxcbiAgICAgICAgICBuZXR3b3JrOiBuZXR3b3JrXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLm5ldHdvcmtfbmFtZSkge1xuICAgICAgY29uc29sZS5sb2coJ1Vua25vd24gY2hhaW4gaWQgKHRoaXMgbWF5IGJlIGEgdGVzdG5ldCknLCBjaGFpbklEKTtcbiAgICB9XG4gIH07XG5cbiAgQ2hhaW5Db25maWcucHJvdG90eXBlLnNldFByZWZpeCA9IGZ1bmN0aW9uIHNldFByZWZpeCgpIHtcbiAgICB2YXIgcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiAnUFBZJztcblxuICAgIHRoaXMuYWRkcmVzc19wcmVmaXggPSBwcmVmaXg7XG4gIH07XG5cbiAgcmV0dXJuIENoYWluQ29uZmlnO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBuZXcgQ2hhaW5Db25maWcoKTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBTT0NLRVRfREVCVUcgPSBmYWxzZTtcbnZhciBXZWJTb2NrZXRDbGllbnQgPSBudWxsO1xuXG5pZiAodHlwZW9mIFdlYlNvY2tldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgV2ViU29ja2V0Q2xpZW50ID0gV2ViU29ja2V0O1xufSBlbHNlIHtcbiAgV2ViU29ja2V0Q2xpZW50ID0gcmVxdWlyZSgzNCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZ2xvYmFsLXJlcXVpcmVcbn1cblxudmFyIFNVQlNDUklCRV9PUEVSQVRJT05TID0gWydzZXRfc3Vic2NyaWJlX2NhbGxiYWNrJywgJ3N1YnNjcmliZV90b19tYXJrZXQnLCAnYnJvYWRjYXN0X3RyYW5zYWN0aW9uX3dpdGhfY2FsbGJhY2snLCAnc2V0X3BlbmRpbmdfdHJhbnNhY3Rpb25fY2FsbGJhY2snXTtcblxudmFyIFVOU1VCU0NSSUJFX09QRVJBVElPTlMgPSBbJ3Vuc3Vic2NyaWJlX2Zyb21fbWFya2V0JywgJ3Vuc3Vic2NyaWJlX2Zyb21fYWNjb3VudHMnXTtcblxudmFyIEhFQUxUSF9DSEVDS19JTlRFUlZBTCA9IDEwMDAwO1xuXG52YXIgQ2hhaW5XZWJTb2NrZXQgPSBmdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKkNyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgQ2hhaW5XZWJTb2NrZXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSAgICBzZXJ2ZXJBZGRyZXNzICAgICAgICAgICBUaGUgYWRkcmVzcyBvZiB0aGUgd2Vic29ja2V0IHRvIGNvbm5lY3QgdG8uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259ICBzdGF0dXNDYiAgICAgICAgICAgICAgICBDYWxsZWQgd2hlbiBzdGF0dXMgZXZlbnRzIG9jY3VyLlxuICAgKiBAcGFyYW0ge251bWJlcn0gICAgW2Nvbm5lY3RUaW1lb3V0PTEwMDAwXSAgVGhlIHRpbWUgZm9yIGEgY29ubmVjdGlvbiBhdHRlbXB0IHRvIGNvbXBsZXRlLlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG4gIGZ1bmN0aW9uIENoYWluV2ViU29ja2V0KHNlcnZlckFkZHJlc3MsIHN0YXR1c0NiKSB7XG4gICAgdmFyIGNvbm5lY3RUaW1lb3V0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAxMDAwMDtcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDaGFpbldlYlNvY2tldCk7XG5cbiAgICB0aGlzLnN0YXR1c0NiID0gc3RhdHVzQ2I7XG4gICAgdGhpcy5zZXJ2ZXJBZGRyZXNzID0gc2VydmVyQWRkcmVzcztcbiAgICB0aGlzLnRpbWVvdXRJbnRlcnZhbCA9IGNvbm5lY3RUaW1lb3V0O1xuXG4gICAgLy8gVGhlIGN1cnJlbmN0IGNvbm5lY3Rpb24gc3RhdGUgb2YgdGhlIHdlYnNvY2tldC5cbiAgICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICAgIHRoaXMucmVjb25uZWN0VGltZW91dCA9IG51bGw7XG5cbiAgICAvLyBDYWxsYmFjayB0byBleGVjdXRlIHdoZW4gdGhlIHdlYnNvY2tldCBpcyByZWNvbm5lY3RlZC5cbiAgICB0aGlzLm9uX3JlY29ubmVjdCA9IG51bGw7XG5cbiAgICAvLyBBbiBpbmNyZW1lbnRpbmcgSUQgZm9yIGVhY2ggcmVxdWVzdCBzbyB0aGF0IHdlIGNhbiBwYWlyIGl0IHdpdGggdGhlXG4gICAgLy8gcmVzcG9uc2UgZnJvbSB0aGUgd2Vic29ja2V0LlxuICAgIHRoaXMuY2JJZCA9IDA7XG5cbiAgICAvLyBPYmplY3RzIHRvIHN0b3JlIGtleS92YWx1ZSBwYWlycyBmb3IgY2FsbGJhY2tzLCBzdWJzY3JpcHRpb24gY2FsbGJhY2tzXG4gICAgLy8gYW5kIHVuc3Vic2NyaWJlIGNhbGxiYWNrcy5cbiAgICB0aGlzLmNicyA9IHt9O1xuICAgIHRoaXMuc3VicyA9IHt9O1xuICAgIHRoaXMudW5zdWIgPSB7fTtcblxuICAgIC8vIEN1cnJlbnQgY29ubmVjdGlvbiBwcm9taXNlcycgcmVqZWN0aW9uXG4gICAgdGhpcy5jdXJyZW50UmVzb2x2ZSA9IG51bGw7XG4gICAgdGhpcy5jdXJyZW50UmVqZWN0ID0gbnVsbDtcblxuICAgIC8vIEhlYWx0aCBjaGVjayBmb3IgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIEJsb2NrQ2hhaW4uXG4gICAgdGhpcy5oZWFsdGhDaGVjayA9IG51bGw7XG5cbiAgICAvLyBDb3B5IHRoZSBjb25zdGFudHMgdG8gdGhpcyBpbnN0YW5jZS5cbiAgICB0aGlzLnN0YXR1cyA9IENoYWluV2ViU29ja2V0LnN0YXR1cztcblxuICAgIC8vIEJpbmQgdGhlIGZ1bmN0aW9ucyB0byB0aGUgaW5zdGFuY2UuXG4gICAgdGhpcy5vbkNvbm5lY3Rpb25PcGVuID0gdGhpcy5vbkNvbm5lY3Rpb25PcGVuLmJpbmQodGhpcyk7XG4gICAgdGhpcy5vbkNvbm5lY3Rpb25DbG9zZSA9IHRoaXMub25Db25uZWN0aW9uQ2xvc2UuYmluZCh0aGlzKTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvblRlcm1pbmF0ZSA9IHRoaXMub25Db25uZWN0aW9uVGVybWluYXRlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5vbkNvbm5lY3Rpb25FcnJvciA9IHRoaXMub25Db25uZWN0aW9uRXJyb3IuYmluZCh0aGlzKTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvblRpbWVvdXQgPSB0aGlzLm9uQ29ubmVjdGlvblRpbWVvdXQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmNyZWF0ZUNvbm5lY3Rpb24gPSB0aGlzLmNyZWF0ZUNvbm5lY3Rpb24uYmluZCh0aGlzKTtcbiAgICB0aGlzLmNyZWF0ZUNvbm5lY3Rpb25Qcm9taXNlID0gdGhpcy5jcmVhdGVDb25uZWN0aW9uUHJvbWlzZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMubGlzdGVuZXIgPSB0aGlzLmxpc3RlbmVyLmJpbmQodGhpcyk7XG5cbiAgICAvLyBDcmVhdGUgdGhlIGluaXRpYWwgY29ubmVjdGlvbiB0aGUgYmxvY2tjaGFpbi5cbiAgICB0aGlzLmNyZWF0ZUNvbm5lY3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIEJsb2NrY2hhaW4uXG4gICAqXG4gICAqIEByZXR1cm5zXG4gICAqIEBtZW1iZXJvZiBDaGFpbldlYlNvY2tldFxuICAgKi9cblxuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5jcmVhdGVDb25uZWN0aW9uID0gZnVuY3Rpb24gY3JlYXRlQ29ubmVjdGlvbigpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgY3JlYXRlIGNvbm5lY3Rpb24nKTtcblxuICAgIC8vIENsZWFyIGFueSBwb3NzaWJsZSByZWNvbm5lY3QgdGltZXJzLlxuICAgIHRoaXMucmVjb25uZWN0VGltZW91dCA9IG51bGw7XG5cbiAgICAvLyBDcmVhdGUgdGhlIHByb21pc2UgZm9yIHRoaXMgY29ubmVjdGlvblxuICAgIGlmICghdGhpcy5jb25uZWN0X3Byb21pc2UpIHtcbiAgICAgIHRoaXMuY29ubmVjdF9wcm9taXNlID0gbmV3IFByb21pc2UodGhpcy5jcmVhdGVDb25uZWN0aW9uUHJvbWlzZSk7XG4gICAgfVxuXG4gICAgLy8gQXR0ZW1wdCB0byBjcmVhdGUgdGhlIHdlYnNvY2tldFxuICAgIHRyeSB7XG4gICAgICB0aGlzLndzID0gbmV3IFdlYlNvY2tldENsaWVudCh0aGlzLnNlcnZlckFkZHJlc3MpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBTZXQgYSB0aW1lb3V0IHRvIHRyeSBhbmQgcmVjb25uZWN0IGhlcmUuXG4gICAgICByZXR1cm4gdGhpcy5yZXNldENvbm5lY3Rpb24oKTtcbiAgICB9XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXJzKCk7XG5cbiAgICAvLyBIYW5kbGUgdGltZW91dHMgdG8gdGhlIHdlYnNvY2tldCdzIGluaXRpYWwgY29ubmVjdGlvbi5cbiAgICB0aGlzLmNvbm5lY3Rpb25UaW1lb3V0ID0gc2V0VGltZW91dCh0aGlzLm9uQ29ubmVjdGlvblRpbWVvdXQsIHRoaXMudGltZW91dEludGVydmFsKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVzZXQgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIEJsb2NrQ2hhaW4uXG4gICAqXG4gICAqIEBtZW1iZXJvZiBDaGFpbldlYlNvY2tldFxuICAgKi9cblxuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5yZXNldENvbm5lY3Rpb24gPSBmdW5jdGlvbiByZXNldENvbm5lY3Rpb24oKSB7XG4gICAgLy8gQ2xvc2UgdGhlIFdlYnNvY2tldCBpZiBpdHMgc3RpbGwgJ2hhbGYtb3BlbidcbiAgICB0aGlzLmNsb3NlKCk7XG5cbiAgICAvLyBNYWtlIHN1cmUgd2Ugb25seSBldmVyIGhhdmUgb25lIHRpbWVvdXQgcnVubmluZyB0byByZWNvbm5lY3QuXG4gICAgaWYgKCF0aGlzLnJlY29ubmVjdFRpbWVvdXQpIHtcbiAgICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCByZXNldCBjb25uZWN0aW9uJywgdGhpcy50aW1lb3V0SW50ZXJ2YWwpO1xuICAgICAgdGhpcy5yZWNvbm5lY3RUaW1lb3V0ID0gc2V0VGltZW91dCh0aGlzLmNyZWF0ZUNvbm5lY3Rpb24sIHRoaXMudGltZW91dEludGVydmFsKTtcbiAgICB9XG5cbiAgICAvLyBSZWplY3QgdGhlIGN1cnJlbnQgcHJvbWlzZSBpZiB0aGVyZSBpcyBvbmUuXG4gICAgaWYgKHRoaXMuY3VycmVudFJlamVjdCkge1xuICAgICAgdGhpcy5jdXJyZW50UmVqZWN0KG5ldyBFcnJvcignQ29ubmVjdGlvbiBhdHRlbXB0IGZhaWxlZDogJyArIHRoaXMuc2VydmVyQWRkcmVzcykpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQWRkIGV2ZW50IGxpc3RlbmVycyB0byB0aGUgV2ViU29ja2V0LlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBhZGRFdmVudExpc3RlbmVycygpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgYWRkIGV2ZW50IGxpc3RlbmVycycpO1xuICAgIHRoaXMud3MuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIHRoaXMub25Db25uZWN0aW9uT3Blbik7XG4gICAgdGhpcy53cy5hZGRFdmVudExpc3RlbmVyKCdjbG9zZScsIHRoaXMub25Db25uZWN0aW9uQ2xvc2UpO1xuICAgIHRoaXMud3MuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCB0aGlzLm9uQ29ubmVjdGlvbkVycm9yKTtcbiAgICB0aGlzLndzLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0aGlzLmxpc3RlbmVyKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVtb3ZlIHRoZSBldmVudCBsaXN0ZXJzIGZyb20gdGhlIFdlYlNvY2tldC4gSXRzIGltcG9ydGFudCB0byByZW1vdmUgdGhlIGV2ZW50IGxpc3RlcmVyc1xuICAgKiBmb3IgZ2FyYmFhZ2UgY29sbGVjdGlvbi4gQmVjYXVzZSB3ZSBhcmUgY3JlYXRpbmcgYSBuZXcgV2ViU29ja2V0IG9uIGVhY2ggY29ubmVjdGlvbiBhdHRlbXB0XG4gICAqIGFueSBsaXN0ZW5lcnMgdGhhdCBhcmUgc3RpbGwgYXR0YWNoZWQgY291bGQgcHJldmVudCB0aGUgb2xkIHNvY2tldHMgZnJvbVxuICAgKiBiZWluZyBnYXJiYWdlIGNvbGxlY3RlZC5cbiAgICpcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLnJlbW92ZUV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IHJlbW92ZSBldmVudCBsaXN0ZW5lcnMnKTtcbiAgICB0aGlzLndzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ29wZW4nLCB0aGlzLm9uQ29ubmVjdGlvbk9wZW4pO1xuICAgIHRoaXMud3MucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xvc2UnLCB0aGlzLm9uQ29ubmVjdGlvbkNsb3NlKTtcbiAgICB0aGlzLndzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgdGhpcy5vbkNvbm5lY3Rpb25FcnJvcik7XG4gICAgdGhpcy53cy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5saXN0ZW5lcik7XG4gIH07XG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCBpcyBwYXNzZWQgdG8gYSBuZXcgcHJvbWlzZSB0aGF0IHN0b3JlcyB0aGUgcmVzb2x2ZSBhbmQgcmVqZWN0IGNhbGxiYWNrc1xuICAgKiBpbiB0aGUgc3RhdGUuXG4gICAqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IHJlc29sdmUgQSBjYWxsYmFjayB0byBiZSBleGVjdXRlZCB3aGVuIHRoZSBwcm9taXNlIGlzIHJlc29sdmVkLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSByZWplY3QgQSBjYWxsYmFjayB0byBiZSBleGVjdXRlZCB3aGVuIHRoZSBwcm9taXNlIGlzIHJlamVjdGVkLlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvblByb21pc2UgPSBmdW5jdGlvbiBjcmVhdGVDb25uZWN0aW9uUHJvbWlzZShyZXNvbHZlLCByZWplY3QpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgY3JlYXRlUHJvbWlzZScpO1xuICAgIHRoaXMuY3VycmVudFJlc29sdmUgPSByZXNvbHZlO1xuICAgIHRoaXMuY3VycmVudFJlamVjdCA9IHJlamVjdDtcbiAgfTtcblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gYSBuZXcgV2Vic29ja2V0IGNvbm5lY3Rpb24gaXMgb3BlbmVkLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUub25Db25uZWN0aW9uT3BlbiA9IGZ1bmN0aW9uIG9uQ29ubmVjdGlvbk9wZW4oKSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IENvbm5lY3RlZCAnKTtcblxuICAgIHRoaXMuY29ubmVjdGVkID0gdHJ1ZTtcblxuICAgIGNsZWFyVGltZW91dCh0aGlzLmNvbm5lY3Rpb25UaW1lb3V0KTtcbiAgICB0aGlzLmNvbm5lY3Rpb25UaW1lb3V0ID0gbnVsbDtcblxuICAgIC8vIFRoaXMgd2lsbCB0cmlnZ2VyIHRoZSBsb2dpbiBwcm9jZXNzIGFzIHdlbGwgYXMgc29tZSBhZGRpdGlvbmFsIHNldHVwIGluIEFwaUluc3RhbmNlc1xuICAgIGlmICh0aGlzLm9uX3JlY29ubmVjdCkge1xuICAgICAgdGhpcy5vbl9yZWNvbm5lY3QoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jdXJyZW50UmVzb2x2ZSkge1xuICAgICAgdGhpcy5jdXJyZW50UmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXR1c0NiKSB7XG4gICAgICB0aGlzLnN0YXR1c0NiKENoYWluV2ViU29ja2V0LnN0YXR1cy5PUEVOKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIGNhbGxlZCB3aGVuIHRoZSBjb25uZWN0aW9uIGF0dGVtcHQgdGltZXMgb3V0LlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUub25Db25uZWN0aW9uVGltZW91dCA9IGZ1bmN0aW9uIG9uQ29ubmVjdGlvblRpbWVvdXQoKSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IHRpbWVvdXQnKTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvbkNsb3NlKG5ldyBFcnJvcignQ29ubmVjdGlvbiB0aW1lZCBvdXQuJykpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgV2Vic29ja2V0IGlzIG5vdCByZXNwb25kaW5nIHRvIHRoZSBoZWFsdGggY2hlY2tzLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUub25Db25uZWN0aW9uVGVybWluYXRlID0gZnVuY3Rpb24gb25Db25uZWN0aW9uVGVybWluYXRlKCkge1xuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCB0ZXJtaW5hdGUnKTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvbkNsb3NlKG5ldyBFcnJvcignQ29ubmVjdGlvbiB3YXMgdGVybWluYXRlZC4nKSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBCbG9ja2NoYWluIGlzIGNsb3NlZC5cbiAgICpcbiAgICogQHBhcmFtIHsqfSBlcnJvclxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUub25Db25uZWN0aW9uQ2xvc2UgPSBmdW5jdGlvbiBvbkNvbm5lY3Rpb25DbG9zZShlcnJvcikge1xuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCBDbG9zZSAnLCBlcnJvcik7XG5cbiAgICB0aGlzLnJlc2V0Q29ubmVjdGlvbigpO1xuXG4gICAgaWYgKHRoaXMuc3RhdHVzQ2IpIHtcbiAgICAgIHRoaXMuc3RhdHVzQ2IoQ2hhaW5XZWJTb2NrZXQuc3RhdHVzLkNMT1NFRCk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgV2Vic29ja2V0IGVuY291bnRlcnMgYW4gZXJyb3IuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gZXJyb3JcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLm9uQ29ubmVjdGlvbkVycm9yID0gZnVuY3Rpb24gb25Db25uZWN0aW9uRXJyb3IoZXJyb3IpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgT24gQ29ubmVjdGlvbiBFcnJvciAnLCBlcnJvcik7XG5cbiAgICB0aGlzLnJlc2V0Q29ubmVjdGlvbigpO1xuXG4gICAgaWYgKHRoaXMuc3RhdHVzQ2IpIHtcbiAgICAgIHRoaXMuc3RhdHVzQ2IoQ2hhaW5XZWJTb2NrZXQuc3RhdHVzLkVSUk9SKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEVudHJ5IHBvaW50IHRvIG1ha2UgUlBDIGNhbGxzIG9uIHRoZSBCbG9ja0NoYWluLlxuICAgKlxuICAgKiBAcGFyYW0ge2FycmF5fSBwYXJhbXMgQW4gYXJyYXkgb2YgcGFyYW1zIHRvIGJlIHBhc3NlZCB0byB0aGUgcnBjIGNhbGwuIFttZXRob2QsIC4uLnBhcmFtc11cbiAgICogQHJldHVybnMgQSBuZXcgcHJvbWlzZSBmb3IgdGhpcyBzcGVjaWZpYyBjYWxsLlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuY2FsbCA9IGZ1bmN0aW9uIGNhbGwocGFyYW1zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIGlmICghdGhpcy5jb25uZWN0ZWQpIHtcbiAgICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCBDYWxsIG5vdCBjb25uZWN0ZWQuICcpO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignRGlzY29ubmVjdGVkIGZyb20gdGhlIEJsb2NrQ2hhaW4uJykpO1xuICAgIH1cblxuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCBDYWxsIGNvbm5lY3RlZC4gJywgcGFyYW1zKTtcblxuICAgIHZhciByZXF1ZXN0ID0ge1xuICAgICAgbWV0aG9kOiBwYXJhbXNbMV0sXG4gICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgIGlkOiB0aGlzLmNiSWQgKyAxXG4gICAgfTtcblxuICAgIHRoaXMuY2JJZCA9IHJlcXVlc3QuaWQ7XG5cbiAgICBpZiAoU1VCU0NSSUJFX09QRVJBVElPTlMuaW5jbHVkZXMocmVxdWVzdC5tZXRob2QpKSB7XG4gICAgICAvLyBTdG9yZSBjYWxsYmFjayBpbiBzdWJzIG1hcFxuICAgICAgdGhpcy5zdWJzW3JlcXVlc3QuaWRdID0ge1xuICAgICAgICBjYWxsYmFjazogcmVxdWVzdC5wYXJhbXNbMl1bMF1cbiAgICAgIH07XG5cbiAgICAgIC8vIFJlcGxhY2UgY2FsbGJhY2sgd2l0aCB0aGUgY2FsbGJhY2sgaWRcbiAgICAgIHJlcXVlc3QucGFyYW1zWzJdWzBdID0gcmVxdWVzdC5pZDtcbiAgICB9XG5cbiAgICBpZiAoVU5TVUJTQ1JJQkVfT1BFUkFUSU9OUy5pbmNsdWRlcyhyZXF1ZXN0Lm1ldGhvZCkpIHtcbiAgICAgIGlmICh0eXBlb2YgcmVxdWVzdC5wYXJhbXNbMl1bMF0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBwYXJhbWV0ZXIgb2YgdW5zdWIgbXVzdCBiZSB0aGUgb3JpZ2luYWwgY2FsbGJhY2snKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHVuU3ViQ2IgPSByZXF1ZXN0LnBhcmFtc1syXS5zcGxpY2UoMCwgMSlbMF07XG5cbiAgICAgIC8vIEZpbmQgdGhlIGNvcnJlc3BvbmRpbmcgc3Vic2NyaXB0aW9uXG4gICAgICBmb3IgKHZhciBpZCBpbiB0aGlzLnN1YnMpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgICAgICBpZiAodGhpcy5zdWJzW2lkXS5jYWxsYmFjayA9PT0gdW5TdWJDYikge1xuICAgICAgICAgIHRoaXMudW5zdWJbcmVxdWVzdC5pZF0gPSBpZDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdGhpcy5oZWFsdGhDaGVjaykge1xuICAgICAgdGhpcy5oZWFsdGhDaGVjayA9IHNldFRpbWVvdXQodGhpcy5vbkNvbm5lY3Rpb25UZXJtaW5hdGUuYmluZCh0aGlzKSwgSEVBTFRIX0NIRUNLX0lOVEVSVkFMKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgX3RoaXMuY2JzW3JlcXVlc3QuaWRdID0ge1xuICAgICAgICB0aW1lOiBuZXcgRGF0ZSgpLFxuICAgICAgICByZXNvbHZlOiByZXNvbHZlLFxuICAgICAgICByZWplY3Q6IHJlamVjdFxuICAgICAgfTtcblxuICAgICAgLy8gU2V0IGFsbCByZXF1ZXN0cyB0byBiZSAnY2FsbCcgbWV0aG9kcy5cbiAgICAgIHJlcXVlc3QubWV0aG9kID0gJ2NhbGwnO1xuXG4gICAgICB0cnkge1xuICAgICAgICBfdGhpcy53cy5zZW5kKEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIF90aGlzLmRlYnVnKCdDYXVnaHQgYSBuYXN0eSBlcnJvciA6ICcsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gbWVzc2FnZXMgYXJlIHJlY2VpdmVkIG9uIHRoZSBXZWJzb2NrZXQuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gcmVzcG9uc2UgVGhlIG1lc3NhZ2UgcmVjZWl2ZWQuXG4gICAqIEBtZW1iZXJvZiBDaGFpbldlYlNvY2tldFxuICAgKi9cblxuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5saXN0ZW5lciA9IGZ1bmN0aW9uIGxpc3RlbmVyKHJlc3BvbnNlKSB7XG4gICAgdmFyIHJlc3BvbnNlSlNPTiA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgcmVzcG9uc2VKU09OID0gSlNPTi5wYXJzZShyZXNwb25zZS5kYXRhKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmVzcG9uc2VKU09OLmVycm9yID0gJ0Vycm9yIHBhcnNpbmcgcmVzcG9uc2U6ICcgKyBlcnJvci5zdGFjaztcbiAgICAgIHRoaXMuZGVidWcoJ0Vycm9yIHBhcnNpbmcgcmVzcG9uc2U6ICcsIHJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICAvLyBDbGVhciB0aGUgaGVhbHRoIGNoZWNrIHRpbWVvdXQsIHdlJ3ZlIGp1c3QgcmVjZWl2ZWQgYSBoZWFsdGh5IHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlci5cbiAgICBpZiAodGhpcy5oZWFsdGhDaGVjaykge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuaGVhbHRoQ2hlY2spO1xuICAgICAgdGhpcy5oZWFsdGhDaGVjayA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIHN1YiA9IGZhbHNlO1xuICAgIHZhciBjYWxsYmFjayA9IG51bGw7XG5cbiAgICBpZiAocmVzcG9uc2VKU09OLm1ldGhvZCA9PT0gJ25vdGljZScpIHtcbiAgICAgIHN1YiA9IHRydWU7XG4gICAgICByZXNwb25zZUpTT04uaWQgPSByZXNwb25zZUpTT04ucGFyYW1zWzBdO1xuICAgIH1cblxuICAgIGlmICghc3ViKSB7XG4gICAgICBjYWxsYmFjayA9IHRoaXMuY2JzW3Jlc3BvbnNlSlNPTi5pZF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhbGxiYWNrID0gdGhpcy5zdWJzW3Jlc3BvbnNlSlNPTi5pZF0uY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgaWYgKGNhbGxiYWNrICYmICFzdWIpIHtcbiAgICAgIGlmIChyZXNwb25zZUpTT04uZXJyb3IpIHtcbiAgICAgICAgdGhpcy5kZWJ1ZygnLS0tLT4gcmVzcG9uc2VKU09OIDogJywgcmVzcG9uc2VKU09OKTtcbiAgICAgICAgY2FsbGJhY2sucmVqZWN0KHJlc3BvbnNlSlNPTi5lcnJvcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYWxsYmFjay5yZXNvbHZlKHJlc3BvbnNlSlNPTi5yZXN1bHQpO1xuICAgICAgfVxuXG4gICAgICBkZWxldGUgdGhpcy5jYnNbcmVzcG9uc2VKU09OLmlkXTtcblxuICAgICAgaWYgKHRoaXMudW5zdWJbcmVzcG9uc2VKU09OLmlkXSkge1xuICAgICAgICBkZWxldGUgdGhpcy5zdWJzW3RoaXMudW5zdWJbcmVzcG9uc2VKU09OLmlkXV07XG4gICAgICAgIGRlbGV0ZSB0aGlzLnVuc3ViW3Jlc3BvbnNlSlNPTi5pZF07XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjYWxsYmFjayAmJiBzdWIpIHtcbiAgICAgIGNhbGxiYWNrKHJlc3BvbnNlSlNPTi5wYXJhbXNbMV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlYnVnKCdXYXJuaW5nOiB1bmtub3duIHdlYnNvY2tldCByZXNwb25zZUpTT046ICcsIHJlc3BvbnNlSlNPTik7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBMb2dpbiB0byB0aGUgQmxvY2tjaGFpbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXIgVXNlcm5hbWVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFBhc3N3b3JkXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCBhZnRlciBsb2dpbi5cbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLmxvZ2luID0gZnVuY3Rpb24gbG9naW4odXNlciwgcGFzc3dvcmQpIHtcbiAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCBsb2dpbi4nLCB1c2VyLCBwYXNzd29yZCk7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdF9wcm9taXNlLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzMi5jYWxsKFsxLCAnbG9naW4nLCBbdXNlciwgcGFzc3dvcmRdXSk7XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENsb3NlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBCbG9ja2NoYWluLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICBpZiAodGhpcy53cykge1xuICAgICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVycygpO1xuXG4gICAgICAvLyBUcnkgYW5kIGZpcmUgY2xvc2Ugb24gdGhlIGNvbm5lY3Rpb24uXG4gICAgICB0aGlzLndzLmNsb3NlKCk7XG5cbiAgICAgIC8vIENsZWFyIG91ciByZWZlcmVuY2VzIHNvIHRoYXQgaXQgY2FuIGJlIGdhcmJhZ2UgY29sbGVjdGVkLlxuICAgICAgdGhpcy53cyA9IG51bGw7XG4gICAgfVxuXG4gICAgLy8gQ2xlYXIgb3VyIHRpbWVvdXRzIGZvciBjb25uZWN0aW9uIHRpbWVvdXQgYW5kIGhlYWx0aCBjaGVjay5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5jb25uZWN0aW9uVGltZW91dCk7XG4gICAgdGhpcy5jb25uZWN0aW9uVGltZW91dCA9IG51bGw7XG5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5oZWFsdGhDaGVjayk7XG4gICAgdGhpcy5oZWFsdGhDaGVjayA9IG51bGw7XG5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5yZWNvbm5lY3RUaW1lb3V0KTtcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVvdXQgPSBudWxsO1xuXG4gICAgLy8gVG9nZ2xlIHRoZSBjb25uZWN0ZWQgZmxhZy5cbiAgICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICB9O1xuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5kZWJ1ZyA9IGZ1bmN0aW9uIGRlYnVnKCkge1xuICAgIGlmIChTT0NLRVRfREVCVUcpIHtcbiAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBwYXJhbXMgPSBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgcGFyYW1zW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgICAgfVxuXG4gICAgICBjb25zb2xlLmxvZy5hcHBseShudWxsLCBwYXJhbXMpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gQ2hhaW5XZWJTb2NrZXQ7XG59KCk7XG5cbi8vIENvbnN0YW50cyBmb3IgU1RBVEVcblxuXG5DaGFpbldlYlNvY2tldC5zdGF0dXMgPSB7XG4gIFJFQ09OTkVDVEVEOiAncmVjb25uZWN0ZWQnLFxuICBPUEVOOiAnb3BlbicsXG4gIENMT1NFRDogJ2Nsb3NlZCcsXG4gIEVSUk9SOiAnZXJyb3InXG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBDaGFpbldlYlNvY2tldDsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfQXBpSW5zdGFuY2VzID0gcmVxdWlyZSg3MSk7XG5cbnZhciBfQXBpSW5zdGFuY2VzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0FwaUluc3RhbmNlcyk7XG5cbnZhciBfQ2hhaW5XZWJTb2NrZXQgPSByZXF1aXJlKDczKTtcblxudmFyIF9DaGFpbldlYlNvY2tldDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpbldlYlNvY2tldCk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBNYW5hZ2VyID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBNYW5hZ2VyKF9yZWYpIHtcbiAgICB2YXIgdXJsID0gX3JlZi51cmwsXG4gICAgICAgIHVybHMgPSBfcmVmLnVybHM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTWFuYWdlcik7XG5cbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICB0aGlzLnVybHMgPSB1cmxzLmZpbHRlcihmdW5jdGlvbiAoYSkge1xuICAgICAgcmV0dXJuIGEgIT09IHVybDtcbiAgICB9KTtcbiAgfVxuXG4gIE1hbmFnZXIucHJvdG90eXBlLmxvZ0ZhaWx1cmUgPSBmdW5jdGlvbiBsb2dGYWlsdXJlKHVybCkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1VuYWJsZSB0byBjb25uZWN0IHRvJywgdXJsICsgJywgc2tpcHBpbmcgdG8gbmV4dCBmdWxsIG5vZGUgQVBJIHNlcnZlcicpO1xuICB9O1xuXG4gIE1hbmFnZXIucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbiBjb25uZWN0KCkge1xuICAgIHZhciBfY29ubmVjdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogdHJ1ZTtcblxuICAgIHZhciB1cmwgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHRoaXMudXJsO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIF9BcGlJbnN0YW5jZXMyLmRlZmF1bHQuaW5zdGFuY2UodXJsLCBfY29ubmVjdCkuaW5pdF9wcm9taXNlLnRoZW4ocmVzb2x2ZSkuY2F0Y2goZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIF9BcGlJbnN0YW5jZXMyLmRlZmF1bHQuaW5zdGFuY2UoKS5jbG9zZSgpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdFdpdGhGYWxsYmFjayA9IGZ1bmN0aW9uIGNvbm5lY3RXaXRoRmFsbGJhY2soKSB7XG4gICAgdmFyIGNvbm5lY3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRydWU7XG4gICAgdmFyIHVybCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogdGhpcy51cmw7XG4gICAgdmFyIGluZGV4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAwO1xuXG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciByZXNvbHZlID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiBudWxsO1xuICAgIHZhciByZWplY3QgPSBhcmd1bWVudHMubGVuZ3RoID4gNCAmJiBhcmd1bWVudHNbNF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1s0XSA6IG51bGw7XG5cbiAgICBpZiAocmVqZWN0ICYmIGluZGV4ID4gdGhpcy51cmxzLmxlbmd0aCAtIDEpIHtcbiAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdUcmllZCAnICsgKGluZGV4ICsgMSkgKyAnIGNvbm5lY3Rpb25zLCBub25lIG9mIHdoaWNoIHdvcmtlZDogJyArIEpTT04uc3RyaW5naWZ5KHRoaXMudXJscy5jb25jYXQodGhpcy51cmwpKSkpO1xuICAgIH1cblxuICAgIHZhciBmYWxsYmFjayA9IGZ1bmN0aW9uIGZhbGxiYWNrKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgX3RoaXMubG9nRmFpbHVyZSh1cmwpO1xuICAgICAgcmV0dXJuIF90aGlzLmNvbm5lY3RXaXRoRmFsbGJhY2soY29ubmVjdCwgX3RoaXMudXJsc1tpbmRleF0sIGluZGV4ICsgMSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9O1xuXG4gICAgaWYgKHJlc29sdmUgJiYgcmVqZWN0KSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25uZWN0KGNvbm5lY3QsIHVybCkudGhlbihyZXNvbHZlKS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZhbGxiYWNrKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgX3RoaXMuY29ubmVjdChjb25uZWN0KS50aGVuKHJlc29sdmUpLmNhdGNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZmFsbGJhY2socmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIE1hbmFnZXIucHJvdG90eXBlLmNoZWNrQ29ubmVjdGlvbnMgPSBmdW5jdGlvbiBjaGVja0Nvbm5lY3Rpb25zKCkge1xuICAgIHZhciBycGNfdXNlciA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJyc7XG4gICAgdmFyIHJwY19wYXNzd29yZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJyc7XG5cbiAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgIHZhciByZXNvbHZlID0gYXJndW1lbnRzWzJdO1xuICAgIHZhciByZWplY3QgPSBhcmd1bWVudHNbM107XG5cbiAgICB2YXIgY29ubmVjdGlvblN0YXJ0VGltZXMgPSB7fTtcblxuICAgIHZhciBjaGVja0Z1bmN0aW9uID0gZnVuY3Rpb24gY2hlY2tGdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciBmdWxsTGlzdCA9IF90aGlzMi51cmxzLmNvbmNhdChfdGhpczIudXJsKTtcbiAgICAgIHZhciBjb25uZWN0aW9uUHJvbWlzZXMgPSBbXTtcblxuICAgICAgZnVsbExpc3QuZm9yRWFjaChmdW5jdGlvbiAodXJsKSB7XG4gICAgICAgIHZhciBjb25uID0gbmV3IF9DaGFpbldlYlNvY2tldDIuZGVmYXVsdCh1cmwsIGZ1bmN0aW9uICgpIHt9KTtcbiAgICAgICAgY29ubmVjdGlvblN0YXJ0VGltZXNbdXJsXSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICBjb25uZWN0aW9uUHJvbWlzZXMucHVzaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbm4ubG9naW4ocnBjX3VzZXIsIHJwY19wYXNzd29yZCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgX3JlZjI7XG5cbiAgICAgICAgICAgIGNvbm4uY2xvc2UoKTtcbiAgICAgICAgICAgIHJldHVybiBfcmVmMiA9IHt9LCBfcmVmMlt1cmxdID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBjb25uZWN0aW9uU3RhcnRUaW1lc1t1cmxdLCBfcmVmMjtcbiAgICAgICAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodXJsID09PSBfdGhpczIudXJsKSB7XG4gICAgICAgICAgICAgIF90aGlzMi51cmwgPSBfdGhpczIudXJsc1swXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIF90aGlzMi51cmxzID0gX3RoaXMyLnVybHMuZmlsdGVyKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGEgIT09IHVybDtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbm4uY2xvc2UoKTtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBQcm9taXNlLmFsbChjb25uZWN0aW9uUHJvbWlzZXMubWFwKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgIHJldHVybiBhKCk7XG4gICAgICB9KSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgIHJlc29sdmUocmVzLmZpbHRlcihmdW5jdGlvbiAoYSkge1xuICAgICAgICAgIHJldHVybiAhIWE7XG4gICAgICAgIH0pLnJlZHVjZShmdW5jdGlvbiAoZiwgYSkge1xuICAgICAgICAgIHZhciBrZXkgPSBPYmplY3Qua2V5cyhhKVswXTtcbiAgICAgICAgICBmW2tleV0gPSBhW2tleV07XG4gICAgICAgICAgcmV0dXJuIGY7XG4gICAgICAgIH0sIHt9KSk7XG4gICAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBfdGhpczIuY2hlY2tDb25uZWN0aW9ucyhycGNfdXNlciwgcnBjX3Bhc3N3b3JkLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGlmIChyZXNvbHZlICYmIHJlamVjdCkge1xuICAgICAgY2hlY2tGdW5jdGlvbihyZXNvbHZlLCByZWplY3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoY2hlY2tGdW5jdGlvbik7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBNYW5hZ2VyO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBNYW5hZ2VyOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIEdyYXBoZW5lQXBpID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBHcmFwaGVuZUFwaSh3c19ycGMsIGFwaV9uYW1lKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEdyYXBoZW5lQXBpKTtcblxuICAgIHRoaXMud3NfcnBjID0gd3NfcnBjO1xuICAgIHRoaXMuYXBpX25hbWUgPSBhcGlfbmFtZTtcbiAgfVxuXG4gIEdyYXBoZW5lQXBpLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gaW5pdCgpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgcmV0dXJuIHRoaXMud3NfcnBjLmNhbGwoWzEsIHRoaXMuYXBpX25hbWUsIFtdXSkudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgIF90aGlzLmFwaV9pZCA9IHJlc3BvbnNlO1xuICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH0pO1xuICB9O1xuXG4gIEdyYXBoZW5lQXBpLnByb3RvdHlwZS5leGVjID0gZnVuY3Rpb24gZXhlYyhtZXRob2QsIHBhcmFtcykge1xuICAgIHJldHVybiB0aGlzLndzX3JwYy5jYWxsKFt0aGlzLmFwaV9pZCwgbWV0aG9kLCBwYXJhbXNdKS5jYXRjaChmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUubG9nKCchISEgR3JhcGhlbmVBcGkgZXJyb3I6ICcsIG1ldGhvZCwgcGFyYW1zLCBlcnJvciwgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiBHcmFwaGVuZUFwaTtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gR3JhcGhlbmVBcGk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAoIXByb2Nlc3MudmVyc2lvbiB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MC4nKSA9PT0gMCB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS4nKSA9PT0gMCAmJiBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuOC4nKSAhPT0gMCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IHsgbmV4dFRpY2s6IG5leHRUaWNrIH07XG59IGVsc2Uge1xuICBtb2R1bGUuZXhwb3J0cyA9IHByb2Nlc3Ncbn1cblxuZnVuY3Rpb24gbmV4dFRpY2soZm4sIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiY2FsbGJhY2tcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuICB2YXIgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgdmFyIGFyZ3MsIGk7XG4gIHN3aXRjaCAobGVuKSB7XG4gIGNhc2UgMDpcbiAgY2FzZSAxOlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZuKTtcbiAgY2FzZSAyOlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja09uZSgpIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgYXJnMSk7XG4gICAgfSk7XG4gIGNhc2UgMzpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tUd28oKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEsIGFyZzIpO1xuICAgIH0pO1xuICBjYXNlIDQ6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVGhyZWUoKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICAgIH0pO1xuICBkZWZhdWx0OlxuICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBhcmdzLmxlbmd0aCkge1xuICAgICAgYXJnc1tpKytdID0gYXJndW1lbnRzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2soKSB7XG4gICAgICBmbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICB9KTtcbiAgfVxufVxuXG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKDc5KTtcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBwbmEgPSByZXF1aXJlKDc2KTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBrZXlzLnB1c2goa2V5KTtcbiAgfXJldHVybiBrZXlzO1xufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IER1cGxleDtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSg0MCk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSg4Nyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIFJlYWRhYmxlID0gcmVxdWlyZSg4MSk7XG52YXIgV3JpdGFibGUgPSByZXF1aXJlKDgzKTtcblxudXRpbC5pbmhlcml0cyhEdXBsZXgsIFJlYWRhYmxlKTtcblxue1xuICAvLyBhdm9pZCBzY29wZSBjcmVlcCwgdGhlIGtleXMgYXJyYXkgY2FuIHRoZW4gYmUgY29sbGVjdGVkXG4gIHZhciBrZXlzID0gb2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO1xuICBmb3IgKHZhciB2ID0gMDsgdiA8IGtleXMubGVuZ3RoOyB2KyspIHtcbiAgICB2YXIgbWV0aG9kID0ga2V5c1t2XTtcbiAgICBpZiAoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSkgRHVwbGV4LnByb3RvdHlwZVttZXRob2RdID0gV3JpdGFibGUucHJvdG90eXBlW21ldGhvZF07XG4gIH1cbn1cblxuZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpIHRoaXMucmVhZGFibGUgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSkgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gIHRoaXMuYWxsb3dIYWxmT3BlbiA9IHRydWU7XG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYWxsb3dIYWxmT3BlbiA9PT0gZmFsc2UpIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRHVwbGV4LnByb3RvdHlwZSwgJ3dyaXRhYmxlSGlnaFdhdGVyTWFyaycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgfVxufSk7XG5cbi8vIHRoZSBuby1oYWxmLW9wZW4gZW5mb3JjZXJcbmZ1bmN0aW9uIG9uZW5kKCkge1xuICAvLyBpZiB3ZSBhbGxvdyBoYWxmLW9wZW4gc3RhdGUsIG9yIGlmIHRoZSB3cml0YWJsZSBzaWRlIGVuZGVkLFxuICAvLyB0aGVuIHdlJ3JlIG9rLlxuICBpZiAodGhpcy5hbGxvd0hhbGZPcGVuIHx8IHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kZWQpIHJldHVybjtcblxuICAvLyBubyBtb3JlIGRhdGEgY2FuIGJlIHdyaXR0ZW4uXG4gIC8vIEJ1dCBhbGxvdyBtb3JlIHdyaXRlcyB0byBoYXBwZW4gaW4gdGhpcyB0aWNrLlxuICBwbmEubmV4dFRpY2sob25FbmROVCwgdGhpcyk7XG59XG5cbmZ1bmN0aW9uIG9uRW5kTlQoc2VsZikge1xuICBzZWxmLmVuZCgpO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRHVwbGV4LnByb3RvdHlwZSwgJ2Rlc3Ryb3llZCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCB8fCB0aGlzLl93cml0YWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkICYmIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIC8vIHdlIGlnbm9yZSB0aGUgdmFsdWUgaWYgdGhlIHN0cmVhbVxuICAgIC8vIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCB5ZXRcbiAgICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkIHx8IHRoaXMuX3dyaXRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZSB1c2VyIGlzIGV4cGxpY2l0bHlcbiAgICAvLyBtYW5hZ2luZyBkZXN0cm95ZWRcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdmFsdWU7XG4gIH1cbn0pO1xuXG5EdXBsZXgucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgdGhpcy5wdXNoKG51bGwpO1xuICB0aGlzLmVuZCgpO1xuXG4gIHBuYS5uZXh0VGljayhjYiwgZXJyKTtcbn07IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUGFzc1Rocm91Z2g7XG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKDgyKTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSg0MCk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSg4Nyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCwgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKSByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG51bGwsIGNodW5rKTtcbn07IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBSZWFkYWJsZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRHVwbGV4O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgRUVsaXN0ZW5lckNvdW50ID0gZnVuY3Rpb24gKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW0gPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvc3RyZWFtJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyO1xudmFyIE91clVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheSB8fCBmdW5jdGlvbiAoKSB7fTtcbmZ1bmN0aW9uIF91aW50OEFycmF5VG9CdWZmZXIoY2h1bmspIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKGNodW5rKTtcbn1cbmZ1bmN0aW9uIF9pc1VpbnQ4QXJyYXkob2JqKSB7XG4gIHJldHVybiBCdWZmZXIuaXNCdWZmZXIob2JqKSB8fCBvYmogaW5zdGFuY2VvZiBPdXJVaW50OEFycmF5O1xufVxuXG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGRlYnVnVXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBkZWJ1ZyA9IHZvaWQgMDtcbmlmIChkZWJ1Z1V0aWwgJiYgZGVidWdVdGlsLmRlYnVnbG9nKSB7XG4gIGRlYnVnID0gZGVidWdVdGlsLmRlYnVnbG9nKCdzdHJlYW0nKTtcbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge307XG59XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdCcpO1xudmFyIGRlc3Ryb3lJbXBsID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL2Rlc3Ryb3knKTtcbnZhciBTdHJpbmdEZWNvZGVyO1xuXG51dGlsLmluaGVyaXRzKFJlYWRhYmxlLCBTdHJlYW0pO1xuXG52YXIga1Byb3h5RXZlbnRzID0gWydlcnJvcicsICdjbG9zZScsICdkZXN0cm95JywgJ3BhdXNlJywgJ3Jlc3VtZSddO1xuXG5mdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIoZW1pdHRlciwgZXZlbnQsIGZuKSB7XG4gIC8vIFNhZGx5IHRoaXMgaXMgbm90IGNhY2hlYWJsZSBhcyBzb21lIGxpYnJhcmllcyBidW5kbGUgdGhlaXIgb3duXG4gIC8vIGV2ZW50IGVtaXR0ZXIgaW1wbGVtZW50YXRpb24gd2l0aCB0aGVtLlxuICBpZiAodHlwZW9mIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSByZXR1cm4gZW1pdHRlci5wcmVwZW5kTGlzdGVuZXIoZXZlbnQsIGZuKTtcblxuICAvLyBUaGlzIGlzIGEgaGFjayB0byBtYWtlIHN1cmUgdGhhdCBvdXIgZXJyb3IgaGFuZGxlciBpcyBhdHRhY2hlZCBiZWZvcmUgYW55XG4gIC8vIHVzZXJsYW5kIG9uZXMuICBORVZFUiBETyBUSElTLiBUaGlzIGlzIGhlcmUgb25seSBiZWNhdXNlIHRoaXMgY29kZSBuZWVkc1xuICAvLyB0byBjb250aW51ZSB0byB3b3JrIHdpdGggb2xkZXIgdmVyc2lvbnMgb2YgTm9kZS5qcyB0aGF0IGRvIG5vdCBpbmNsdWRlXG4gIC8vIHRoZSBwcmVwZW5kTGlzdGVuZXIoKSBtZXRob2QuIFRoZSBnb2FsIGlzIHRvIGV2ZW50dWFsbHkgcmVtb3ZlIHRoaXMgaGFjay5cbiAgaWYgKCFlbWl0dGVyLl9ldmVudHMgfHwgIWVtaXR0ZXIuX2V2ZW50c1tldmVudF0pIGVtaXR0ZXIub24oZXZlbnQsIGZuKTtlbHNlIGlmIChpc0FycmF5KGVtaXR0ZXIuX2V2ZW50c1tldmVudF0pKSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdLnVuc2hpZnQoZm4pO2Vsc2UgZW1pdHRlci5fZXZlbnRzW2V2ZW50XSA9IFtmbiwgZW1pdHRlci5fZXZlbnRzW2V2ZW50XV07XG59XG5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gRHVwbGV4IHN0cmVhbXMgYXJlIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLCBidXQgc2hhcmVcbiAgLy8gdGhlIHNhbWUgb3B0aW9ucyBvYmplY3QuXG4gIC8vIEhvd2V2ZXIsIHNvbWUgY2FzZXMgcmVxdWlyZSBzZXR0aW5nIG9wdGlvbnMgdG8gZGlmZmVyZW50XG4gIC8vIHZhbHVlcyBmb3IgdGhlIHJlYWRhYmxlIGFuZCB0aGUgd3JpdGFibGUgc2lkZXMgb2YgdGhlIGR1cGxleCBzdHJlYW0uXG4gIC8vIFRoZXNlIG9wdGlvbnMgY2FuIGJlIHByb3ZpZGVkIHNlcGFyYXRlbHkgYXMgcmVhZGFibGVYWFggYW5kIHdyaXRhYmxlWFhYLlxuICB2YXIgaXNEdXBsZXggPSBzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXg7XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnLiBVc2VkIHRvIG1ha2UgcmVhZChuKSBpZ25vcmUgbiBhbmQgdG9cbiAgLy8gbWFrZSBhbGwgdGhlIGJ1ZmZlciBtZXJnaW5nIGFuZCBsZW5ndGggY2hlY2tzIGdvIGF3YXlcbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgaWYgKGlzRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciByZWFkYWJsZUh3bSA9IG9wdGlvbnMucmVhZGFibGVIaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuXG4gIGlmIChod20gfHwgaHdtID09PSAwKSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod207ZWxzZSBpZiAoaXNEdXBsZXggJiYgKHJlYWRhYmxlSHdtIHx8IHJlYWRhYmxlSHdtID09PSAwKSkgdGhpcy5oaWdoV2F0ZXJNYXJrID0gcmVhZGFibGVId207ZWxzZSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gTWF0aC5mbG9vcih0aGlzLmhpZ2hXYXRlck1hcmspO1xuXG4gIC8vIEEgbGlua2VkIGxpc3QgaXMgdXNlZCB0byBzdG9yZSBkYXRhIGNodW5rcyBpbnN0ZWFkIG9mIGFuIGFycmF5IGJlY2F1c2UgdGhlXG4gIC8vIGxpbmtlZCBsaXN0IGNhbiByZW1vdmUgZWxlbWVudHMgZnJvbSB0aGUgYmVnaW5uaW5nIGZhc3RlciB0aGFuXG4gIC8vIGFycmF5LnNoaWZ0KClcbiAgdGhpcy5idWZmZXIgPSBuZXcgQnVmZmVyTGlzdCgpO1xuICB0aGlzLmxlbmd0aCA9IDA7XG4gIHRoaXMucGlwZXMgPSBudWxsO1xuICB0aGlzLnBpcGVzQ291bnQgPSAwO1xuICB0aGlzLmZsb3dpbmcgPSBudWxsO1xuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIHRoaXMuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB0aGlzLnJlYWRpbmcgPSBmYWxzZTtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBldmVudCAncmVhZGFibGUnLydkYXRhJyBpcyBlbWl0dGVkXG4gIC8vIGltbWVkaWF0ZWx5LCBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlXG4gIC8vIGFueSBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCByZWFkIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gd2hlbmV2ZXIgd2UgcmV0dXJuIG51bGwsIHRoZW4gd2Ugc2V0IGEgZmxhZyB0byBzYXlcbiAgLy8gdGhhdCB3ZSdyZSBhd2FpdGluZyBhICdyZWFkYWJsZScgZXZlbnQgZW1pc3Npb24uXG4gIHRoaXMubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGVMaXN0ZW5pbmcgPSBmYWxzZTtcbiAgdGhpcy5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcblxuICAvLyBoYXMgaXQgYmVlbiBkZXN0cm95ZWRcbiAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyB0aGUgbnVtYmVyIG9mIHdyaXRlcnMgdGhhdCBhcmUgYXdhaXRpbmcgYSBkcmFpbiBldmVudCBpbiAucGlwZSgpc1xuICB0aGlzLmF3YWl0RHJhaW4gPSAwO1xuXG4gIC8vIGlmIHRydWUsIGEgbWF5YmVSZWFkTW9yZSBoYXMgYmVlbiBzY2hlZHVsZWRcbiAgdGhpcy5yZWFkaW5nTW9yZSA9IGZhbHNlO1xuXG4gIHRoaXMuZGVjb2RlciA9IG51bGw7XG4gIHRoaXMuZW5jb2RpbmcgPSBudWxsO1xuICBpZiAob3B0aW9ucy5lbmNvZGluZykge1xuICAgIGlmICghU3RyaW5nRGVjb2RlcikgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyLycpLlN0cmluZ0RlY29kZXI7XG4gICAgdGhpcy5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIob3B0aW9ucy5lbmNvZGluZyk7XG4gICAgdGhpcy5lbmNvZGluZyA9IG9wdGlvbnMuZW5jb2Rpbmc7XG4gIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSZWFkYWJsZSkpIHJldHVybiBuZXcgUmVhZGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZSA9IG5ldyBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeVxuICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5yZWFkID09PSAnZnVuY3Rpb24nKSB0aGlzLl9yZWFkID0gb3B0aW9ucy5yZWFkO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHRoaXMuX2Rlc3Ryb3kgPSBvcHRpb25zLmRlc3Ryb3k7XG4gIH1cblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ2Rlc3Ryb3llZCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgLy8gd2UgaWdub3JlIHRoZSB2YWx1ZSBpZiB0aGUgc3RyZWFtXG4gICAgLy8gaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIHlldFxuICAgIGlmICghdGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZSB1c2VyIGlzIGV4cGxpY2l0bHlcbiAgICAvLyBtYW5hZ2luZyBkZXN0cm95ZWRcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTtcblxuUmVhZGFibGUucHJvdG90eXBlLmRlc3Ryb3kgPSBkZXN0cm95SW1wbC5kZXN0cm95O1xuUmVhZGFibGUucHJvdG90eXBlLl91bmRlc3Ryb3kgPSBkZXN0cm95SW1wbC51bmRlc3Ryb3k7XG5SZWFkYWJsZS5wcm90b3R5cGUuX2Rlc3Ryb3kgPSBmdW5jdGlvbiAoZXJyLCBjYikge1xuICB0aGlzLnB1c2gobnVsbCk7XG4gIGNiKGVycik7XG59O1xuXG4vLyBNYW51YWxseSBzaG92ZSBzb21ldGhpbmcgaW50byB0aGUgcmVhZCgpIGJ1ZmZlci5cbi8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIHRoZSBoaWdoV2F0ZXJNYXJrIGhhcyBub3QgYmVlbiBoaXQgeWV0LFxuLy8gc2ltaWxhciB0byBob3cgV3JpdGFibGUud3JpdGUoKSByZXR1cm5zIHRydWUgaWYgeW91IHNob3VsZFxuLy8gd3JpdGUoKSBzb21lIG1vcmUuXG5SZWFkYWJsZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHNraXBDaHVua0NoZWNrO1xuXG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGlmICh0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlbmNvZGluZyA9IGVuY29kaW5nIHx8IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgICAgIGlmIChlbmNvZGluZyAhPT0gc3RhdGUuZW5jb2RpbmcpIHtcbiAgICAgICAgY2h1bmsgPSBCdWZmZXIuZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgICBlbmNvZGluZyA9ICcnO1xuICAgICAgfVxuICAgICAgc2tpcENodW5rQ2hlY2sgPSB0cnVlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBza2lwQ2h1bmtDaGVjayA9IHRydWU7XG4gIH1cblxuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBjaHVuaywgZW5jb2RpbmcsIGZhbHNlLCBza2lwQ2h1bmtDaGVjayk7XG59O1xuXG4vLyBVbnNoaWZ0IHNob3VsZCAqYWx3YXlzKiBiZSBzb21ldGhpbmcgZGlyZWN0bHkgb3V0IG9mIHJlYWQoKVxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgY2h1bmssIG51bGwsIHRydWUsIGZhbHNlKTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBjaHVuaywgZW5jb2RpbmcsIGFkZFRvRnJvbnQsIHNraXBDaHVua0NoZWNrKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGVyO1xuICAgIGlmICghc2tpcENodW5rQ2hlY2spIGVyID0gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuayk7XG4gICAgaWYgKGVyKSB7XG4gICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rICYmIGNodW5rLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICh0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmICFzdGF0ZS5vYmplY3RNb2RlICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihjaHVuaykgIT09IEJ1ZmZlci5wcm90b3R5cGUpIHtcbiAgICAgICAgY2h1bmsgPSBfdWludDhBcnJheVRvQnVmZmVyKGNodW5rKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFkZFRvRnJvbnQpIHtcbiAgICAgICAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignc3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnQnKSk7ZWxzZSBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgdHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmVuZGVkKSB7XG4gICAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignc3RyZWFtLnB1c2goKSBhZnRlciBFT0YnKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFlbmNvZGluZykge1xuICAgICAgICAgIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG4gICAgICAgICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgfHwgY2h1bmsubGVuZ3RoICE9PSAwKSBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO2Vsc2UgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghYWRkVG9Gcm9udCkge1xuICAgICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZWVkTW9yZURhdGEoc3RhdGUpO1xufVxuXG5mdW5jdGlvbiBhZGRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgYWRkVG9Gcm9udCkge1xuICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLnN5bmMpIHtcbiAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGNodW5rKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB1cGRhdGUgdGhlIGJ1ZmZlciBpbmZvLlxuICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICBpZiAoYWRkVG9Gcm9udCkgc3RhdGUuYnVmZmVyLnVuc2hpZnQoY2h1bmspO2Vsc2Ugc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuXG4gICAgaWYgKHN0YXRlLm5lZWRSZWFkYWJsZSkgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG4gIH1cbiAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbn1cblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXI7XG4gIGlmICghX2lzVWludDhBcnJheShjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG4vLyBpZiBpdCdzIHBhc3QgdGhlIGhpZ2ggd2F0ZXIgbWFyaywgd2UgY2FuIHB1c2ggaW4gc29tZSBtb3JlLlxuLy8gQWxzbywgaWYgd2UgaGF2ZSBubyBkYXRhIHlldCwgd2UgY2FuIHN0YW5kIHNvbWVcbi8vIG1vcmUgYnl0ZXMuICBUaGlzIGlzIHRvIHdvcmsgYXJvdW5kIGNhc2VzIHdoZXJlIGh3bT0wLFxuLy8gc3VjaCBhcyB0aGUgcmVwbC4gIEFsc28sIGlmIHRoZSBwdXNoKCkgdHJpZ2dlcmVkIGFcbi8vIHJlYWRhYmxlIGV2ZW50LCBhbmQgdGhlIHVzZXIgY2FsbGVkIHJlYWQobGFyZ2VOdW1iZXIpIHN1Y2ggdGhhdFxuLy8gbmVlZFJlYWRhYmxlIHdhcyBzZXQsIHRoZW4gd2Ugb3VnaHQgdG8gcHVzaCBtb3JlLCBzbyB0aGF0IGFub3RoZXJcbi8vICdyZWFkYWJsZScgZXZlbnQgd2lsbCBiZSB0cmlnZ2VyZWQuXG5mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpIHtcbiAgcmV0dXJuICFzdGF0ZS5lbmRlZCAmJiAoc3RhdGUubmVlZFJlYWRhYmxlIHx8IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUubGVuZ3RoID09PSAwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLmlzUGF1c2VkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID09PSBmYWxzZTtcbn07XG5cbi8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24gKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihlbmMpO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuY29kaW5nID0gZW5jO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIERvbid0IHJhaXNlIHRoZSBod20gPiA4TUJcbnZhciBNQVhfSFdNID0gMHg4MDAwMDA7XG5mdW5jdGlvbiBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKSB7XG4gIGlmIChuID49IE1BWF9IV00pIHtcbiAgICBuID0gTUFYX0hXTTtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIG5leHQgaGlnaGVzdCBwb3dlciBvZiAyIHRvIHByZXZlbnQgaW5jcmVhc2luZyBod20gZXhjZXNzaXZlbHkgaW5cbiAgICAvLyB0aW55IGFtb3VudHNcbiAgICBuLS07XG4gICAgbiB8PSBuID4+PiAxO1xuICAgIG4gfD0gbiA+Pj4gMjtcbiAgICBuIHw9IG4gPj4+IDQ7XG4gICAgbiB8PSBuID4+PiA4O1xuICAgIG4gfD0gbiA+Pj4gMTY7XG4gICAgbisrO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobiwgc3RhdGUpIHtcbiAgaWYgKG4gPD0gMCB8fCBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpIHJldHVybiAwO1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0dXJuIDE7XG4gIGlmIChuICE9PSBuKSB7XG4gICAgLy8gT25seSBmbG93IG9uZSBidWZmZXIgYXQgYSB0aW1lXG4gICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoKSByZXR1cm4gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YS5sZW5ndGg7ZWxzZSByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9XG4gIC8vIElmIHdlJ3JlIGFza2luZyBmb3IgbW9yZSB0aGFuIHRoZSBjdXJyZW50IGh3bSwgdGhlbiByYWlzZSB0aGUgaHdtLlxuICBpZiAobiA+IHN0YXRlLmhpZ2hXYXRlck1hcmspIHN0YXRlLmhpZ2hXYXRlck1hcmsgPSBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKTtcbiAgaWYgKG4gPD0gc3RhdGUubGVuZ3RoKSByZXR1cm4gbjtcbiAgLy8gRG9uJ3QgaGF2ZSBlbm91Z2hcbiAgaWYgKCFzdGF0ZS5lbmRlZCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbn1cblxuLy8geW91IGNhbiBvdmVycmlkZSBlaXRoZXIgdGhpcyBtZXRob2QsIG9yIHRoZSBhc3luYyBfcmVhZChuKSBiZWxvdy5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgZGVidWcoJ3JlYWQnLCBuKTtcbiAgbiA9IHBhcnNlSW50KG4sIDEwKTtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIG5PcmlnID0gbjtcblxuICBpZiAobiAhPT0gMCkgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgLy8gaWYgd2UncmUgZG9pbmcgcmVhZCgwKSB0byB0cmlnZ2VyIGEgcmVhZGFibGUgZXZlbnQsIGJ1dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYSBidW5jaCBvZiBkYXRhIGluIHRoZSBidWZmZXIsIHRoZW4ganVzdCB0cmlnZ2VyXG4gIC8vIHRoZSAncmVhZGFibGUnIGV2ZW50IGFuZCBtb3ZlIG9uLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5uZWVkUmVhZGFibGUgJiYgKHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmVuZGVkKSkge1xuICAgIGRlYnVnKCdyZWFkOiBlbWl0UmVhZGFibGUnLCBzdGF0ZS5sZW5ndGgsIHN0YXRlLmVuZGVkKTtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSBlbmRSZWFkYWJsZSh0aGlzKTtlbHNlIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIG4gPSBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKTtcblxuICAvLyBpZiB3ZSd2ZSBlbmRlZCwgYW5kIHdlJ3JlIG5vdyBjbGVhciwgdGhlbiBmaW5pc2ggaXQgdXAuXG4gIGlmIChuID09PSAwICYmIHN0YXRlLmVuZGVkKSB7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgZW5kUmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBbGwgdGhlIGFjdHVhbCBjaHVuayBnZW5lcmF0aW9uIGxvZ2ljIG5lZWRzIHRvIGJlXG4gIC8vICpiZWxvdyogdGhlIGNhbGwgdG8gX3JlYWQuICBUaGUgcmVhc29uIGlzIHRoYXQgaW4gY2VydGFpblxuICAvLyBzeW50aGV0aWMgc3RyZWFtIGNhc2VzLCBzdWNoIGFzIHBhc3N0aHJvdWdoIHN0cmVhbXMsIF9yZWFkXG4gIC8vIG1heSBiZSBhIGNvbXBsZXRlbHkgc3luY2hyb25vdXMgb3BlcmF0aW9uIHdoaWNoIG1heSBjaGFuZ2VcbiAgLy8gdGhlIHN0YXRlIG9mIHRoZSByZWFkIGJ1ZmZlciwgcHJvdmlkaW5nIGVub3VnaCBkYXRhIHdoZW5cbiAgLy8gYmVmb3JlIHRoZXJlIHdhcyAqbm90KiBlbm91Z2guXG4gIC8vXG4gIC8vIFNvLCB0aGUgc3RlcHMgYXJlOlxuICAvLyAxLiBGaWd1cmUgb3V0IHdoYXQgdGhlIHN0YXRlIG9mIHRoaW5ncyB3aWxsIGJlIGFmdGVyIHdlIGRvXG4gIC8vIGEgcmVhZCBmcm9tIHRoZSBidWZmZXIuXG4gIC8vXG4gIC8vIDIuIElmIHRoYXQgcmVzdWx0aW5nIHN0YXRlIHdpbGwgdHJpZ2dlciBhIF9yZWFkLCB0aGVuIGNhbGwgX3JlYWQuXG4gIC8vIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBhc3luY2hyb25vdXMsIG9yIHN5bmNocm9ub3VzLiAgWWVzLCBpdCBpc1xuICAvLyBkZWVwbHkgdWdseSB0byB3cml0ZSBBUElzIHRoaXMgd2F5LCBidXQgdGhhdCBzdGlsbCBkb2Vzbid0IG1lYW5cbiAgLy8gdGhhdCB0aGUgUmVhZGFibGUgY2xhc3Mgc2hvdWxkIGJlaGF2ZSBpbXByb3Blcmx5LCBhcyBzdHJlYW1zIGFyZVxuICAvLyBkZXNpZ25lZCB0byBiZSBzeW5jL2FzeW5jIGFnbm9zdGljLlxuICAvLyBUYWtlIG5vdGUgaWYgdGhlIF9yZWFkIGNhbGwgaXMgc3luYyBvciBhc3luYyAoaWUsIGlmIHRoZSByZWFkIGNhbGxcbiAgLy8gaGFzIHJldHVybmVkIHlldCksIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIG9yIG5vdCBpdCdzIHNhZmUgdG8gZW1pdFxuICAvLyAncmVhZGFibGUnIGV0Yy5cbiAgLy9cbiAgLy8gMy4gQWN0dWFsbHkgcHVsbCB0aGUgcmVxdWVzdGVkIGNodW5rcyBvdXQgb2YgdGhlIGJ1ZmZlciBhbmQgcmV0dXJuLlxuXG4gIC8vIGlmIHdlIG5lZWQgYSByZWFkYWJsZSBldmVudCwgdGhlbiB3ZSBuZWVkIHRvIGRvIHNvbWUgcmVhZGluZy5cbiAgdmFyIGRvUmVhZCA9IHN0YXRlLm5lZWRSZWFkYWJsZTtcbiAgZGVidWcoJ25lZWQgcmVhZGFibGUnLCBkb1JlYWQpO1xuXG4gIC8vIGlmIHdlIGN1cnJlbnRseSBoYXZlIGxlc3MgdGhhbiB0aGUgaGlnaFdhdGVyTWFyaywgdGhlbiBhbHNvIHJlYWQgc29tZVxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwIHx8IHN0YXRlLmxlbmd0aCAtIG4gPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZG9SZWFkID0gdHJ1ZTtcbiAgICBkZWJ1ZygnbGVuZ3RoIGxlc3MgdGhhbiB3YXRlcm1hcmsnLCBkb1JlYWQpO1xuICB9XG5cbiAgLy8gaG93ZXZlciwgaWYgd2UndmUgZW5kZWQsIHRoZW4gdGhlcmUncyBubyBwb2ludCwgYW5kIGlmIHdlJ3JlIGFscmVhZHlcbiAgLy8gcmVhZGluZywgdGhlbiBpdCdzIHVubmVjZXNzYXJ5LlxuICBpZiAoc3RhdGUuZW5kZWQgfHwgc3RhdGUucmVhZGluZykge1xuICAgIGRvUmVhZCA9IGZhbHNlO1xuICAgIGRlYnVnKCdyZWFkaW5nIG9yIGVuZGVkJywgZG9SZWFkKTtcbiAgfSBlbHNlIGlmIChkb1JlYWQpIHtcbiAgICBkZWJ1ZygnZG8gcmVhZCcpO1xuICAgIHN0YXRlLnJlYWRpbmcgPSB0cnVlO1xuICAgIHN0YXRlLnN5bmMgPSB0cnVlO1xuICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgY3VycmVudGx5IHplcm8sIHRoZW4gd2UgKm5lZWQqIGEgcmVhZGFibGUgZXZlbnQuXG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAvLyBjYWxsIGludGVybmFsIHJlYWQgbWV0aG9kXG4gICAgdGhpcy5fcmVhZChzdGF0ZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICBzdGF0ZS5zeW5jID0gZmFsc2U7XG4gICAgLy8gSWYgX3JlYWQgcHVzaGVkIGRhdGEgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2Agd2lsbCBiZSBmYWxzZSxcbiAgICAvLyBhbmQgd2UgbmVlZCB0byByZS1ldmFsdWF0ZSBob3cgbXVjaCBkYXRhIHdlIGNhbiByZXR1cm4gdG8gdGhlIHVzZXIuXG4gICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSBuID0gaG93TXVjaFRvUmVhZChuT3JpZywgc3RhdGUpO1xuICB9XG5cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKSByZXQgPSBmcm9tTGlzdChuLCBzdGF0ZSk7ZWxzZSByZXQgPSBudWxsO1xuXG4gIGlmIChyZXQgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIG4gPSAwO1xuICB9IGVsc2Uge1xuICAgIHN0YXRlLmxlbmd0aCAtPSBuO1xuICB9XG5cbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIElmIHdlIGhhdmUgbm90aGluZyBpbiB0aGUgYnVmZmVyLCB0aGVuIHdlIHdhbnQgdG8ga25vd1xuICAgIC8vIGFzIHNvb24gYXMgd2UgKmRvKiBnZXQgc29tZXRoaW5nIGludG8gdGhlIGJ1ZmZlci5cbiAgICBpZiAoIXN0YXRlLmVuZGVkKSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gICAgLy8gSWYgd2UgdHJpZWQgdG8gcmVhZCgpIHBhc3QgdGhlIEVPRiwgdGhlbiBlbWl0IGVuZCBvbiB0aGUgbmV4dCB0aWNrLlxuICAgIGlmIChuT3JpZyAhPT0gbiAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7XG4gIH1cblxuICBpZiAocmV0ICE9PSBudWxsKSB0aGlzLmVtaXQoJ2RhdGEnLCByZXQpO1xuXG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG4gIGlmIChzdGF0ZS5kZWNvZGVyKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICAvLyBlbWl0ICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmICghc3RhdGUuZW1pdHRlZFJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ2VtaXRSZWFkYWJsZScsIHN0YXRlLmZsb3dpbmcpO1xuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgaWYgKHN0YXRlLnN5bmMpIHBuYS5uZXh0VGljayhlbWl0UmVhZGFibGVfLCBzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIGRlYnVnKCdlbWl0IHJlYWRhYmxlJyk7XG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICBmbG93KHN0cmVhbSk7XG59XG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgcG5hLm5leHRUaWNrKG1heWJlUmVhZE1vcmVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRlYnVnKCdtYXliZVJlYWRNb3JlIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICAgIGlmIChsZW4gPT09IHN0YXRlLmxlbmd0aClcbiAgICAgIC8vIGRpZG4ndCBnZXQgYW55IGRhdGEsIHN0b3Agc3Bpbm5pbmcuXG4gICAgICBicmVhaztlbHNlIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ19yZWFkKCkgaXMgbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoZGVzdCwgcGlwZU9wdHMpIHtcbiAgdmFyIHNyYyA9IHRoaXM7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgc3dpdGNoIChzdGF0ZS5waXBlc0NvdW50KSB7XG4gICAgY2FzZSAwOlxuICAgICAgc3RhdGUucGlwZXMgPSBkZXN0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAxOlxuICAgICAgc3RhdGUucGlwZXMgPSBbc3RhdGUucGlwZXMsIGRlc3RdO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHN0YXRlLnBpcGVzLnB1c2goZGVzdCk7XG4gICAgICBicmVhaztcbiAgfVxuICBzdGF0ZS5waXBlc0NvdW50ICs9IDE7XG4gIGRlYnVnKCdwaXBlIGNvdW50PSVkIG9wdHM9JWonLCBzdGF0ZS5waXBlc0NvdW50LCBwaXBlT3B0cyk7XG5cbiAgdmFyIGRvRW5kID0gKCFwaXBlT3B0cyB8fCBwaXBlT3B0cy5lbmQgIT09IGZhbHNlKSAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZG91dCAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZGVycjtcblxuICB2YXIgZW5kRm4gPSBkb0VuZCA/IG9uZW5kIDogdW5waXBlO1xuICBpZiAoc3RhdGUuZW5kRW1pdHRlZCkgcG5hLm5leHRUaWNrKGVuZEZuKTtlbHNlIHNyYy5vbmNlKCdlbmQnLCBlbmRGbik7XG5cbiAgZGVzdC5vbigndW5waXBlJywgb251bnBpcGUpO1xuICBmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSwgdW5waXBlSW5mbykge1xuICAgIGRlYnVnKCdvbnVucGlwZScpO1xuICAgIGlmIChyZWFkYWJsZSA9PT0gc3JjKSB7XG4gICAgICBpZiAodW5waXBlSW5mbyAmJiB1bnBpcGVJbmZvLmhhc1VucGlwZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHVucGlwZUluZm8uaGFzVW5waXBlZCA9IHRydWU7XG4gICAgICAgIGNsZWFudXAoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBkZWJ1Zygnb25lbmQnKTtcbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cbiAgLy8gd2hlbiB0aGUgZGVzdCBkcmFpbnMsIGl0IHJlZHVjZXMgdGhlIGF3YWl0RHJhaW4gY291bnRlclxuICAvLyBvbiB0aGUgc291cmNlLiAgVGhpcyB3b3VsZCBiZSBtb3JlIGVsZWdhbnQgd2l0aCBhIC5vbmNlKClcbiAgLy8gaGFuZGxlciBpbiBmbG93KCksIGJ1dCBhZGRpbmcgYW5kIHJlbW92aW5nIHJlcGVhdGVkbHkgaXNcbiAgLy8gdG9vIHNsb3cuXG4gIHZhciBvbmRyYWluID0gcGlwZU9uRHJhaW4oc3JjKTtcbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICB2YXIgY2xlYW5lZFVwID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgZGVidWcoJ2NsZWFudXAnKTtcbiAgICAvLyBjbGVhbnVwIGV2ZW50IGhhbmRsZXJzIG9uY2UgdGhlIHBpcGUgaXMgYnJva2VuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ3VucGlwZScsIG9udW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIHVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcblxuICAgIGNsZWFuZWRVcCA9IHRydWU7XG5cbiAgICAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluICYmICghZGVzdC5fd3JpdGFibGVTdGF0ZSB8fCBkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbikpIG9uZHJhaW4oKTtcbiAgfVxuXG4gIC8vIElmIHRoZSB1c2VyIHB1c2hlcyBtb3JlIGRhdGEgd2hpbGUgd2UncmUgd3JpdGluZyB0byBkZXN0IHRoZW4gd2UnbGwgZW5kIHVwXG4gIC8vIGluIG9uZGF0YSBhZ2Fpbi4gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIGluY3JlYXNlIGF3YWl0RHJhaW4gb25jZSBiZWNhdXNlXG4gIC8vIGRlc3Qgd2lsbCBvbmx5IGVtaXQgb25lICdkcmFpbicgZXZlbnQgZm9yIHRoZSBtdWx0aXBsZSB3cml0ZXMuXG4gIC8vID0+IEludHJvZHVjZSBhIGd1YXJkIG9uIGluY3JlYXNpbmcgYXdhaXREcmFpbi5cbiAgdmFyIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgc3JjLm9uKCdkYXRhJywgb25kYXRhKTtcbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgZGVidWcoJ29uZGF0YScpO1xuICAgIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgICB2YXIgcmV0ID0gZGVzdC53cml0ZShjaHVuayk7XG4gICAgaWYgKGZhbHNlID09PSByZXQgJiYgIWluY3JlYXNlZEF3YWl0RHJhaW4pIHtcbiAgICAgIC8vIElmIHRoZSB1c2VyIHVucGlwZWQgZHVyaW5nIGBkZXN0LndyaXRlKClgLCBpdCBpcyBwb3NzaWJsZVxuICAgICAgLy8gdG8gZ2V0IHN0dWNrIGluIGEgcGVybWFuZW50bHkgcGF1c2VkIHN0YXRlIGlmIHRoYXQgd3JpdGVcbiAgICAgIC8vIGFsc28gcmV0dXJuZWQgZmFsc2UuXG4gICAgICAvLyA9PiBDaGVjayB3aGV0aGVyIGBkZXN0YCBpcyBzdGlsbCBhIHBpcGluZyBkZXN0aW5hdGlvbi5cbiAgICAgIGlmICgoc3RhdGUucGlwZXNDb3VudCA9PT0gMSAmJiBzdGF0ZS5waXBlcyA9PT0gZGVzdCB8fCBzdGF0ZS5waXBlc0NvdW50ID4gMSAmJiBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KSAhPT0gLTEpICYmICFjbGVhbmVkVXApIHtcbiAgICAgICAgZGVidWcoJ2ZhbHNlIHdyaXRlIHJlc3BvbnNlLCBwYXVzZScsIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKTtcbiAgICAgICAgc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4rKztcbiAgICAgICAgaW5jcmVhc2VkQXdhaXREcmFpbiA9IHRydWU7XG4gICAgICB9XG4gICAgICBzcmMucGF1c2UoKTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgZGVzdCBoYXMgYW4gZXJyb3IsIHRoZW4gc3RvcCBwaXBpbmcgaW50byBpdC5cbiAgLy8gaG93ZXZlciwgZG9uJ3Qgc3VwcHJlc3MgdGhlIHRocm93aW5nIGJlaGF2aW9yIGZvciB0aGlzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgZGVidWcoJ29uZXJyb3InLCBlcik7XG4gICAgdW5waXBlKCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBpZiAoRUVsaXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpID09PSAwKSBkZXN0LmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIG91ciBlcnJvciBoYW5kbGVyIGlzIGF0dGFjaGVkIGJlZm9yZSB1c2VybGFuZCBvbmVzLlxuICBwcmVwZW5kTGlzdGVuZXIoZGVzdCwgJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZWJ1Zygnb25maW5pc2gnKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBkZWJ1ZygndW5waXBlJyk7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfVxuXG4gIC8vIHRlbGwgdGhlIGRlc3QgdGhhdCBpdCdzIGJlaW5nIHBpcGVkIHRvXG4gIGRlc3QuZW1pdCgncGlwZScsIHNyYyk7XG5cbiAgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGlwZSByZXN1bWUnKTtcbiAgICBzcmMucmVzdW1lKCk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBkZWJ1ZygncGlwZU9uRHJhaW4nLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbikgc3RhdGUuYXdhaXREcmFpbi0tO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluID09PSAwICYmIEVFbGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykpIHtcbiAgICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgICAgZmxvdyhzcmMpO1xuICAgIH1cbiAgfTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uIChkZXN0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciB1bnBpcGVJbmZvID0geyBoYXNVbnBpcGVkOiBmYWxzZSB9O1xuXG4gIC8vIGlmIHdlJ3JlIG5vdCBwaXBpbmcgYW55d2hlcmUsIHRoZW4gZG8gbm90aGluZy5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApIHJldHVybiB0aGlzO1xuXG4gIC8vIGp1c3Qgb25lIGRlc3RpbmF0aW9uLiAgbW9zdCBjb21tb24gY2FzZS5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHtcbiAgICAvLyBwYXNzZWQgaW4gb25lLCBidXQgaXQncyBub3QgdGhlIHJpZ2h0IG9uZS5cbiAgICBpZiAoZGVzdCAmJiBkZXN0ICE9PSBzdGF0ZS5waXBlcykgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoIWRlc3QpIGRlc3QgPSBzdGF0ZS5waXBlcztcblxuICAgIC8vIGdvdCBhIG1hdGNoLlxuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgaWYgKGRlc3QpIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzbG93IGNhc2UuIG11bHRpcGxlIHBpcGUgZGVzdGluYXRpb25zLlxuXG4gIGlmICghZGVzdCkge1xuICAgIC8vIHJlbW92ZSBhbGwuXG4gICAgdmFyIGRlc3RzID0gc3RhdGUucGlwZXM7XG4gICAgdmFyIGxlbiA9IHN0YXRlLnBpcGVzQ291bnQ7XG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGRlc3RzW2ldLmVtaXQoJ3VucGlwZScsIHRoaXMsIHVucGlwZUluZm8pO1xuICAgIH1yZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHRyeSB0byBmaW5kIHRoZSByaWdodCBvbmUuXG4gIHZhciBpbmRleCA9IGluZGV4T2Yoc3RhdGUucGlwZXMsIGRlc3QpO1xuICBpZiAoaW5kZXggPT09IC0xKSByZXR1cm4gdGhpcztcblxuICBzdGF0ZS5waXBlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICBzdGF0ZS5waXBlc0NvdW50IC09IDE7XG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuXG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcywgdW5waXBlSW5mbyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBzZXQgdXAgZGF0YSBldmVudHMgaWYgdGhleSBhcmUgYXNrZWQgZm9yXG4vLyBFbnN1cmUgcmVhZGFibGUgbGlzdGVuZXJzIGV2ZW50dWFsbHkgZ2V0IHNvbWV0aGluZ1xuUmVhZGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2LCBmbikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKHRoaXMsIGV2LCBmbik7XG5cbiAgaWYgKGV2ID09PSAnZGF0YScpIHtcbiAgICAvLyBTdGFydCBmbG93aW5nIG9uIG5leHQgdGljayBpZiBzdHJlYW0gaXNuJ3QgZXhwbGljaXRseSBwYXVzZWRcbiAgICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nICE9PSBmYWxzZSkgdGhpcy5yZXN1bWUoKTtcbiAgfSBlbHNlIGlmIChldiA9PT0gJ3JlYWRhYmxlJykge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmICFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgcG5hLm5leHRUaWNrKG5SZWFkaW5nTmV4dFRpY2ssIHRoaXMpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5sZW5ndGgpIHtcbiAgICAgICAgZW1pdFJlYWRhYmxlKHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyID0gUmVhZGFibGUucHJvdG90eXBlLm9uO1xuXG5mdW5jdGlvbiBuUmVhZGluZ05leHRUaWNrKHNlbGYpIHtcbiAgZGVidWcoJ3JlYWRhYmxlIG5leHR0aWNrIHJlYWQgMCcpO1xuICBzZWxmLnJlYWQoMCk7XG59XG5cbi8vIHBhdXNlKCkgYW5kIHJlc3VtZSgpIGFyZSByZW1uYW50cyBvZiB0aGUgbGVnYWN5IHJlYWRhYmxlIHN0cmVhbSBBUElcbi8vIElmIHRoZSB1c2VyIHVzZXMgdGhlbSwgdGhlbiBzd2l0Y2ggaW50byBvbGQgbW9kZS5cblJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdyZXN1bWUnKTtcbiAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICByZXN1bWUodGhpcywgc3RhdGUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gcmVzdW1lKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZXN1bWVTY2hlZHVsZWQpIHtcbiAgICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSB0cnVlO1xuICAgIHBuYS5uZXh0VGljayhyZXN1bWVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuICBzdGF0ZS5hd2FpdERyYWluID0gMDtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKSBzdHJlYW0ucmVhZCgwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2FsbCBwYXVzZSBmbG93aW5nPSVqJywgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtcbiAgaWYgKGZhbHNlICE9PSB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGF1c2UnKTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmbG93KHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdmbG93Jywgc3RhdGUuZmxvd2luZyk7XG4gIHdoaWxlIChzdGF0ZS5mbG93aW5nICYmIHN0cmVhbS5yZWFkKCkgIT09IG51bGwpIHt9XG59XG5cbi8vIHdyYXAgYW4gb2xkLXN0eWxlIHN0cmVhbSBhcyB0aGUgYXN5bmMgZGF0YSBzb3VyY2UuXG4vLyBUaGlzIGlzICpub3QqIHBhcnQgb2YgdGhlIHJlYWRhYmxlIHN0cmVhbSBpbnRlcmZhY2UuXG4vLyBJdCBpcyBhbiB1Z2x5IHVuZm9ydHVuYXRlIG1lc3Mgb2YgaGlzdG9yeS5cblJlYWRhYmxlLnByb3RvdHlwZS53cmFwID0gZnVuY3Rpb24gKHN0cmVhbSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBwYXVzZWQgPSBmYWxzZTtcblxuICBzdHJlYW0ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBlbmQnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSBfdGhpcy5wdXNoKGNodW5rKTtcbiAgICB9XG5cbiAgICBfdGhpcy5wdXNoKG51bGwpO1xuICB9KTtcblxuICBzdHJlYW0ub24oJ2RhdGEnLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBkYXRhJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG5cbiAgICAvLyBkb24ndCBza2lwIG92ZXIgZmFsc3kgdmFsdWVzIGluIG9iamVjdE1vZGVcbiAgICBpZiAoc3RhdGUub2JqZWN0TW9kZSAmJiAoY2h1bmsgPT09IG51bGwgfHwgY2h1bmsgPT09IHVuZGVmaW5lZCkpIHJldHVybjtlbHNlIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiAoIWNodW5rIHx8ICFjaHVuay5sZW5ndGgpKSByZXR1cm47XG5cbiAgICB2YXIgcmV0ID0gX3RoaXMucHVzaChjaHVuayk7XG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHByb3h5IGFsbCB0aGUgb3RoZXIgbWV0aG9kcy5cbiAgLy8gaW1wb3J0YW50IHdoZW4gd3JhcHBpbmcgZmlsdGVycyBhbmQgZHVwbGV4ZXMuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHRoaXNbaV0gPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBzdHJlYW1bbWV0aG9kXS5hcHBseShzdHJlYW0sIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgICB9KGkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHByb3h5IGNlcnRhaW4gaW1wb3J0YW50IGV2ZW50cy5cbiAgZm9yICh2YXIgbiA9IDA7IG4gPCBrUHJveHlFdmVudHMubGVuZ3RoOyBuKyspIHtcbiAgICBzdHJlYW0ub24oa1Byb3h5RXZlbnRzW25dLCB0aGlzLmVtaXQuYmluZCh0aGlzLCBrUHJveHlFdmVudHNbbl0pKTtcbiAgfVxuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHRoaXMuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICAgIGRlYnVnKCd3cmFwcGVkIF9yZWFkJywgbik7XG4gICAgaWYgKHBhdXNlZCkge1xuICAgICAgcGF1c2VkID0gZmFsc2U7XG4gICAgICBzdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlLnByb3RvdHlwZSwgJ3JlYWRhYmxlSGlnaFdhdGVyTWFyaycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgfVxufSk7XG5cbi8vIGV4cG9zZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS5cblJlYWRhYmxlLl9mcm9tTGlzdCA9IGZyb21MaXN0O1xuXG4vLyBQbHVjayBvZmYgbiBieXRlcyBmcm9tIGFuIGFycmF5IG9mIGJ1ZmZlcnMuXG4vLyBMZW5ndGggaXMgdGhlIGNvbWJpbmVkIGxlbmd0aHMgb2YgYWxsIHRoZSBidWZmZXJzIGluIHRoZSBsaXN0LlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBmcm9tTGlzdChuLCBzdGF0ZSkge1xuICAvLyBub3RoaW5nIGJ1ZmZlcmVkXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gIHZhciByZXQ7XG4gIGlmIChzdGF0ZS5vYmplY3RNb2RlKSByZXQgPSBzdGF0ZS5idWZmZXIuc2hpZnQoKTtlbHNlIGlmICghbiB8fCBuID49IHN0YXRlLmxlbmd0aCkge1xuICAgIC8vIHJlYWQgaXQgYWxsLCB0cnVuY2F0ZSB0aGUgbGlzdFxuICAgIGlmIChzdGF0ZS5kZWNvZGVyKSByZXQgPSBzdGF0ZS5idWZmZXIuam9pbignJyk7ZWxzZSBpZiAoc3RhdGUuYnVmZmVyLmxlbmd0aCA9PT0gMSkgcmV0ID0gc3RhdGUuYnVmZmVyLmhlYWQuZGF0YTtlbHNlIHJldCA9IHN0YXRlLmJ1ZmZlci5jb25jYXQoc3RhdGUubGVuZ3RoKTtcbiAgICBzdGF0ZS5idWZmZXIuY2xlYXIoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWFkIHBhcnQgb2YgbGlzdFxuICAgIHJldCA9IGZyb21MaXN0UGFydGlhbChuLCBzdGF0ZS5idWZmZXIsIHN0YXRlLmRlY29kZXIpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuLy8gRXh0cmFjdHMgb25seSBlbm91Z2ggYnVmZmVyZWQgZGF0YSB0byBzYXRpc2Z5IHRoZSBhbW91bnQgcmVxdWVzdGVkLlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBmcm9tTGlzdFBhcnRpYWwobiwgbGlzdCwgaGFzU3RyaW5ncykge1xuICB2YXIgcmV0O1xuICBpZiAobiA8IGxpc3QuaGVhZC5kYXRhLmxlbmd0aCkge1xuICAgIC8vIHNsaWNlIGlzIHRoZSBzYW1lIGZvciBidWZmZXJzIGFuZCBzdHJpbmdzXG4gICAgcmV0ID0gbGlzdC5oZWFkLmRhdGEuc2xpY2UoMCwgbik7XG4gICAgbGlzdC5oZWFkLmRhdGEgPSBsaXN0LmhlYWQuZGF0YS5zbGljZShuKTtcbiAgfSBlbHNlIGlmIChuID09PSBsaXN0LmhlYWQuZGF0YS5sZW5ndGgpIHtcbiAgICAvLyBmaXJzdCBjaHVuayBpcyBhIHBlcmZlY3QgbWF0Y2hcbiAgICByZXQgPSBsaXN0LnNoaWZ0KCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVzdWx0IHNwYW5zIG1vcmUgdGhhbiBvbmUgYnVmZmVyXG4gICAgcmV0ID0gaGFzU3RyaW5ncyA/IGNvcHlGcm9tQnVmZmVyU3RyaW5nKG4sIGxpc3QpIDogY29weUZyb21CdWZmZXIobiwgbGlzdCk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuLy8gQ29waWVzIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBjaGFyYWN0ZXJzIGZyb20gdGhlIGxpc3Qgb2YgYnVmZmVyZWQgZGF0YVxuLy8gY2h1bmtzLlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBjb3B5RnJvbUJ1ZmZlclN0cmluZyhuLCBsaXN0KSB7XG4gIHZhciBwID0gbGlzdC5oZWFkO1xuICB2YXIgYyA9IDE7XG4gIHZhciByZXQgPSBwLmRhdGE7XG4gIG4gLT0gcmV0Lmxlbmd0aDtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICB2YXIgc3RyID0gcC5kYXRhO1xuICAgIHZhciBuYiA9IG4gPiBzdHIubGVuZ3RoID8gc3RyLmxlbmd0aCA6IG47XG4gICAgaWYgKG5iID09PSBzdHIubGVuZ3RoKSByZXQgKz0gc3RyO2Vsc2UgcmV0ICs9IHN0ci5zbGljZSgwLCBuKTtcbiAgICBuIC09IG5iO1xuICAgIGlmIChuID09PSAwKSB7XG4gICAgICBpZiAobmIgPT09IHN0ci5sZW5ndGgpIHtcbiAgICAgICAgKytjO1xuICAgICAgICBpZiAocC5uZXh0KSBsaXN0LmhlYWQgPSBwLm5leHQ7ZWxzZSBsaXN0LmhlYWQgPSBsaXN0LnRhaWwgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGlzdC5oZWFkID0gcDtcbiAgICAgICAgcC5kYXRhID0gc3RyLnNsaWNlKG5iKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICArK2M7XG4gIH1cbiAgbGlzdC5sZW5ndGggLT0gYztcbiAgcmV0dXJuIHJldDtcbn1cblxuLy8gQ29waWVzIGEgc3BlY2lmaWVkIGFtb3VudCBvZiBieXRlcyBmcm9tIHRoZSBsaXN0IG9mIGJ1ZmZlcmVkIGRhdGEgY2h1bmtzLlxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBjb3B5RnJvbUJ1ZmZlcihuLCBsaXN0KSB7XG4gIHZhciByZXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobik7XG4gIHZhciBwID0gbGlzdC5oZWFkO1xuICB2YXIgYyA9IDE7XG4gIHAuZGF0YS5jb3B5KHJldCk7XG4gIG4gLT0gcC5kYXRhLmxlbmd0aDtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICB2YXIgYnVmID0gcC5kYXRhO1xuICAgIHZhciBuYiA9IG4gPiBidWYubGVuZ3RoID8gYnVmLmxlbmd0aCA6IG47XG4gICAgYnVmLmNvcHkocmV0LCByZXQubGVuZ3RoIC0gbiwgMCwgbmIpO1xuICAgIG4gLT0gbmI7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIGlmIChuYiA9PT0gYnVmLmxlbmd0aCkge1xuICAgICAgICArK2M7XG4gICAgICAgIGlmIChwLm5leHQpIGxpc3QuaGVhZCA9IHAubmV4dDtlbHNlIGxpc3QuaGVhZCA9IGxpc3QudGFpbCA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaXN0LmhlYWQgPSBwO1xuICAgICAgICBwLmRhdGEgPSBidWYuc2xpY2UobmIpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgICsrYztcbiAgfVxuICBsaXN0Lmxlbmd0aCAtPSBjO1xuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIElmIHdlIGdldCBoZXJlIGJlZm9yZSBjb25zdW1pbmcgYWxsIHRoZSBieXRlcywgdGhlbiB0aGF0IGlzIGFcbiAgLy8gYnVnIGluIG5vZGUuICBTaG91bGQgbmV2ZXIgaGFwcGVuLlxuICBpZiAoc3RhdGUubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEVycm9yKCdcImVuZFJlYWRhYmxlKClcIiBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO1xuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCkge1xuICAgIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgICBwbmEubmV4dFRpY2soZW5kUmVhZGFibGVOVCwgc3RhdGUsIHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSwgc3RyZWFtKSB7XG4gIC8vIENoZWNrIHRoYXQgd2UgZGlkbid0IGdldCBvbmUgbGFzdCB1bnNoaWZ0LlxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKSB7XG4gICAgc3RhdGUuZW5kRW1pdHRlZCA9IHRydWU7XG4gICAgc3RyZWFtLnJlYWRhYmxlID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2VuZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gYSB0cmFuc2Zvcm0gc3RyZWFtIGlzIGEgcmVhZGFibGUvd3JpdGFibGUgc3RyZWFtIHdoZXJlIHlvdSBkb1xuLy8gc29tZXRoaW5nIHdpdGggdGhlIGRhdGEuICBTb21ldGltZXMgaXQncyBjYWxsZWQgYSBcImZpbHRlclwiLFxuLy8gYnV0IHRoYXQncyBub3QgYSBncmVhdCBuYW1lIGZvciBpdCwgc2luY2UgdGhhdCBpbXBsaWVzIGEgdGhpbmcgd2hlcmVcbi8vIHNvbWUgYml0cyBwYXNzIHRocm91Z2gsIGFuZCBvdGhlcnMgYXJlIHNpbXBseSBpZ25vcmVkLiAgKFRoYXQgd291bGRcbi8vIGJlIGEgdmFsaWQgZXhhbXBsZSBvZiBhIHRyYW5zZm9ybSwgb2YgY291cnNlLilcbi8vXG4vLyBXaGlsZSB0aGUgb3V0cHV0IGlzIGNhdXNhbGx5IHJlbGF0ZWQgdG8gdGhlIGlucHV0LCBpdCdzIG5vdCBhXG4vLyBuZWNlc3NhcmlseSBzeW1tZXRyaWMgb3Igc3luY2hyb25vdXMgdHJhbnNmb3JtYXRpb24uICBGb3IgZXhhbXBsZSxcbi8vIGEgemxpYiBzdHJlYW0gbWlnaHQgdGFrZSBtdWx0aXBsZSBwbGFpbi10ZXh0IHdyaXRlcygpLCBhbmQgdGhlblxuLy8gZW1pdCBhIHNpbmdsZSBjb21wcmVzc2VkIGNodW5rIHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLlxuLy9cbi8vIEhlcmUncyBob3cgdGhpcyB3b3Jrczpcbi8vXG4vLyBUaGUgVHJhbnNmb3JtIHN0cmVhbSBoYXMgYWxsIHRoZSBhc3BlY3RzIG9mIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGVcbi8vIHN0cmVhbSBjbGFzc2VzLiAgV2hlbiB5b3Ugd3JpdGUoY2h1bmspLCB0aGF0IGNhbGxzIF93cml0ZShjaHVuayxjYilcbi8vIGludGVybmFsbHksIGFuZCByZXR1cm5zIGZhbHNlIGlmIHRoZXJlJ3MgYSBsb3Qgb2YgcGVuZGluZyB3cml0ZXNcbi8vIGJ1ZmZlcmVkIHVwLiAgV2hlbiB5b3UgY2FsbCByZWFkKCksIHRoYXQgY2FsbHMgX3JlYWQobikgdW50aWxcbi8vIHRoZXJlJ3MgZW5vdWdoIHBlbmRpbmcgcmVhZGFibGUgZGF0YSBidWZmZXJlZCB1cC5cbi8vXG4vLyBJbiBhIHRyYW5zZm9ybSBzdHJlYW0sIHRoZSB3cml0dGVuIGRhdGEgaXMgcGxhY2VkIGluIGEgYnVmZmVyLiAgV2hlblxuLy8gX3JlYWQobikgaXMgY2FsbGVkLCBpdCB0cmFuc2Zvcm1zIHRoZSBxdWV1ZWQgdXAgZGF0YSwgY2FsbGluZyB0aGVcbi8vIGJ1ZmZlcmVkIF93cml0ZSBjYidzIGFzIGl0IGNvbnN1bWVzIGNodW5rcy4gIElmIGNvbnN1bWluZyBhIHNpbmdsZVxuLy8gd3JpdHRlbiBjaHVuayB3b3VsZCByZXN1bHQgaW4gbXVsdGlwbGUgb3V0cHV0IGNodW5rcywgdGhlbiB0aGUgZmlyc3Rcbi8vIG91dHB1dHRlZCBiaXQgY2FsbHMgdGhlIHJlYWRjYiwgYW5kIHN1YnNlcXVlbnQgY2h1bmtzIGp1c3QgZ28gaW50b1xuLy8gdGhlIHJlYWQgYnVmZmVyLCBhbmQgd2lsbCBjYXVzZSBpdCB0byBlbWl0ICdyZWFkYWJsZScgaWYgbmVjZXNzYXJ5LlxuLy9cbi8vIFRoaXMgd2F5LCBiYWNrLXByZXNzdXJlIGlzIGFjdHVhbGx5IGRldGVybWluZWQgYnkgdGhlIHJlYWRpbmcgc2lkZSxcbi8vIHNpbmNlIF9yZWFkIGhhcyB0byBiZSBjYWxsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZyBhIG5ldyBjaHVuay4gIEhvd2V2ZXIsXG4vLyBhIHBhdGhvbG9naWNhbCBpbmZsYXRlIHR5cGUgb2YgdHJhbnNmb3JtIGNhbiBjYXVzZSBleGNlc3NpdmUgYnVmZmVyaW5nXG4vLyBoZXJlLiAgRm9yIGV4YW1wbGUsIGltYWdpbmUgYSBzdHJlYW0gd2hlcmUgZXZlcnkgYnl0ZSBvZiBpbnB1dCBpc1xuLy8gaW50ZXJwcmV0ZWQgYXMgYW4gaW50ZWdlciBmcm9tIDAtMjU1LCBhbmQgdGhlbiByZXN1bHRzIGluIHRoYXQgbWFueVxuLy8gYnl0ZXMgb2Ygb3V0cHV0LiAgV3JpdGluZyB0aGUgNCBieXRlcyB7ZmYsZmYsZmYsZmZ9IHdvdWxkIHJlc3VsdCBpblxuLy8gMWtiIG9mIGRhdGEgYmVpbmcgb3V0cHV0LiAgSW4gdGhpcyBjYXNlLCB5b3UgY291bGQgd3JpdGUgYSB2ZXJ5IHNtYWxsXG4vLyBhbW91bnQgb2YgaW5wdXQsIGFuZCBlbmQgdXAgd2l0aCBhIHZlcnkgbGFyZ2UgYW1vdW50IG9mIG91dHB1dC4gIEluXG4vLyBzdWNoIGEgcGF0aG9sb2dpY2FsIGluZmxhdGluZyBtZWNoYW5pc20sIHRoZXJlJ2QgYmUgbm8gd2F5IHRvIHRlbGxcbi8vIHRoZSBzeXN0ZW0gdG8gc3RvcCBkb2luZyB0aGUgdHJhbnNmb3JtLiAgQSBzaW5nbGUgNE1CIHdyaXRlIGNvdWxkXG4vLyBjYXVzZSB0aGUgc3lzdGVtIHRvIHJ1biBvdXQgb2YgbWVtb3J5LlxuLy9cbi8vIEhvd2V2ZXIsIGV2ZW4gaW4gc3VjaCBhIHBhdGhvbG9naWNhbCBjYXNlLCBvbmx5IGEgc2luZ2xlIHdyaXR0ZW4gY2h1bmtcbi8vIHdvdWxkIGJlIGNvbnN1bWVkLCBhbmQgdGhlbiB0aGUgcmVzdCB3b3VsZCB3YWl0ICh1bi10cmFuc2Zvcm1lZCkgdW50aWxcbi8vIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm1lZCBjaHVuayB3ZXJlIGNvbnN1bWVkLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNmb3JtO1xuXG52YXIgRHVwbGV4ID0gcmVxdWlyZSg3OSk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoNDApO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoODcpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoVHJhbnNmb3JtLCBEdXBsZXgpO1xuXG5mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShlciwgZGF0YSkge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMudHJhbnNmb3JtaW5nID0gZmFsc2U7XG5cbiAgdmFyIGNiID0gdHMud3JpdGVjYjtcblxuICBpZiAoIWNiKSB7XG4gICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ3dyaXRlIGNhbGxiYWNrIGNhbGxlZCBtdWx0aXBsZSB0aW1lcycpKTtcbiAgfVxuXG4gIHRzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0cy53cml0ZWNiID0gbnVsbDtcblxuICBpZiAoZGF0YSAhPSBudWxsKSAvLyBzaW5nbGUgZXF1YWxzIGNoZWNrIGZvciBib3RoIGBudWxsYCBhbmQgYHVuZGVmaW5lZGBcbiAgICB0aGlzLnB1c2goZGF0YSk7XG5cbiAgY2IoZXIpO1xuXG4gIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHJzLnJlYWRpbmcgPSBmYWxzZTtcbiAgaWYgKHJzLm5lZWRSZWFkYWJsZSB8fCBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSkgcmV0dXJuIG5ldyBUcmFuc2Zvcm0ob3B0aW9ucyk7XG5cbiAgRHVwbGV4LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUgPSB7XG4gICAgYWZ0ZXJUcmFuc2Zvcm06IGFmdGVyVHJhbnNmb3JtLmJpbmQodGhpcyksXG4gICAgbmVlZFRyYW5zZm9ybTogZmFsc2UsXG4gICAgdHJhbnNmb3JtaW5nOiBmYWxzZSxcbiAgICB3cml0ZWNiOiBudWxsLFxuICAgIHdyaXRlY2h1bms6IG51bGwsXG4gICAgd3JpdGVlbmNvZGluZzogbnVsbFxuICB9O1xuXG4gIC8vIHN0YXJ0IG91dCBhc2tpbmcgZm9yIGEgcmVhZGFibGUgZXZlbnQgb25jZSBkYXRhIGlzIHRyYW5zZm9ybWVkLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gd2UgaGF2ZSBpbXBsZW1lbnRlZCB0aGUgX3JlYWQgbWV0aG9kLCBhbmQgZG9uZSB0aGUgb3RoZXIgdGhpbmdzXG4gIC8vIHRoYXQgUmVhZGFibGUgd2FudHMgYmVmb3JlIHRoZSBmaXJzdCBfcmVhZCBjYWxsLCBzbyB1bnNldCB0aGVcbiAgLy8gc3luYyBndWFyZCBmbGFnLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmMgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy50cmFuc2Zvcm0gPT09ICdmdW5jdGlvbicpIHRoaXMuX3RyYW5zZm9ybSA9IG9wdGlvbnMudHJhbnNmb3JtO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmZsdXNoID09PSAnZnVuY3Rpb24nKSB0aGlzLl9mbHVzaCA9IG9wdGlvbnMuZmx1c2g7XG4gIH1cblxuICAvLyBXaGVuIHRoZSB3cml0YWJsZSBzaWRlIGZpbmlzaGVzLCB0aGVuIGZsdXNoIG91dCBhbnl0aGluZyByZW1haW5pbmcuXG4gIHRoaXMub24oJ3ByZWZpbmlzaCcsIHByZWZpbmlzaCk7XG59XG5cbmZ1bmN0aW9uIHByZWZpbmlzaCgpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICBpZiAodHlwZW9mIHRoaXMuX2ZsdXNoID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5fZmx1c2goZnVuY3Rpb24gKGVyLCBkYXRhKSB7XG4gICAgICBkb25lKF90aGlzLCBlciwgZGF0YSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgZG9uZSh0aGlzLCBudWxsLCBudWxsKTtcbiAgfVxufVxuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgcmV0dXJuIER1cGxleC5wcm90b3R5cGUucHVzaC5jYWxsKHRoaXMsIGNodW5rLCBlbmNvZGluZyk7XG59O1xuXG4vLyBUaGlzIGlzIHRoZSBwYXJ0IHdoZXJlIHlvdSBkbyBzdHVmZiFcbi8vIG92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gaW4gaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vICdjaHVuaycgaXMgYW4gaW5wdXQgY2h1bmsuXG4vL1xuLy8gQ2FsbCBgcHVzaChuZXdDaHVuaylgIHRvIHBhc3MgYWxvbmcgdHJhbnNmb3JtZWQgb3V0cHV0XG4vLyB0byB0aGUgcmVhZGFibGUgc2lkZS4gIFlvdSBtYXkgY2FsbCAncHVzaCcgemVybyBvciBtb3JlIHRpbWVzLlxuLy9cbi8vIENhbGwgYGNiKGVycilgIHdoZW4geW91IGFyZSBkb25lIHdpdGggdGhpcyBjaHVuay4gIElmIHlvdSBwYXNzXG4vLyBhbiBlcnJvciwgdGhlbiB0aGF0J2xsIHB1dCB0aGUgaHVydCBvbiB0aGUgd2hvbGUgb3BlcmF0aW9uLiAgSWYgeW91XG4vLyBuZXZlciBjYWxsIGNiKCksIHRoZW4geW91J2xsIG5ldmVyIGdldCBhbm90aGVyIGNodW5rLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdHJhbnNmb3JtKCkgaXMgbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuICBpZiAoIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKHRzLm5lZWRUcmFuc2Zvcm0gfHwgcnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn07XG5cbi8vIERvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGFyZ3MgYXJlIGhlcmUuXG4vLyBfdHJhbnNmb3JtIGRvZXMgYWxsIHRoZSB3b3JrLlxuLy8gVGhhdCB3ZSBnb3QgaGVyZSBtZWFucyB0aGF0IHRoZSByZWFkYWJsZSBzaWRlIHdhbnRzIG1vcmUgZGF0YS5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAodHMud3JpdGVjaHVuayAhPT0gbnVsbCAmJiB0cy53cml0ZWNiICYmICF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB0cy50cmFuc2Zvcm1pbmcgPSB0cnVlO1xuICAgIHRoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLCB0cy53cml0ZWVuY29kaW5nLCB0cy5hZnRlclRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFyayB0aGF0IHdlIG5lZWQgYSB0cmFuc2Zvcm0sIHNvIHRoYXQgYW55IGRhdGEgdGhhdCBjb21lcyBpblxuICAgIC8vIHdpbGwgZ2V0IHByb2Nlc3NlZCwgbm93IHRoYXQgd2UndmUgYXNrZWQgZm9yIGl0LlxuICAgIHRzLm5lZWRUcmFuc2Zvcm0gPSB0cnVlO1xuICB9XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgRHVwbGV4LnByb3RvdHlwZS5fZGVzdHJveS5jYWxsKHRoaXMsIGVyciwgZnVuY3Rpb24gKGVycjIpIHtcbiAgICBjYihlcnIyKTtcbiAgICBfdGhpczIuZW1pdCgnY2xvc2UnKTtcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgaWYgKGVyKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuXG4gIGlmIChkYXRhICE9IG51bGwpIC8vIHNpbmdsZSBlcXVhbHMgY2hlY2sgZm9yIGJvdGggYG51bGxgIGFuZCBgdW5kZWZpbmVkYFxuICAgIHN0cmVhbS5wdXNoKGRhdGEpO1xuXG4gIC8vIGlmIHRoZXJlJ3Mgbm90aGluZyBpbiB0aGUgd3JpdGUgYnVmZmVyLCB0aGVuIHRoYXQgbWVhbnNcbiAgLy8gdGhhdCBub3RoaW5nIG1vcmUgd2lsbCBldmVyIGJlIHByb3ZpZGVkXG4gIGlmIChzdHJlYW0uX3dyaXRhYmxlU3RhdGUubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ0NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiB3cy5sZW5ndGggIT0gMCcpO1xuXG4gIGlmIChzdHJlYW0uX3RyYW5zZm9ybVN0YXRlLnRyYW5zZm9ybWluZykgdGhyb3cgbmV3IEVycm9yKCdDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gc3RpbGwgdHJhbnNmb3JtaW5nJyk7XG5cbiAgcmV0dXJuIHN0cmVhbS5wdXNoKG51bGwpO1xufSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBBIGJpdCBzaW1wbGVyIHRoYW4gcmVhZGFibGUgc3RyZWFtcy5cbi8vIEltcGxlbWVudCBhbiBhc3luYyAuX3dyaXRlKGNodW5rLCBlbmNvZGluZywgY2IpLCBhbmQgaXQnbGwgaGFuZGxlIGFsbFxuLy8gdGhlIGRyYWluIGV2ZW50IGVtaXNzaW9uIGFuZCBidWZmZXJpbmcuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBXcml0YWJsZTtcblxuLyogPHJlcGxhY2VtZW50PiAqL1xuZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aGlzLmNodW5rID0gY2h1bms7XG4gIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgdGhpcy5jYWxsYmFjayA9IGNiO1xuICB0aGlzLm5leHQgPSBudWxsO1xufVxuXG4vLyBJdCBzZWVtcyBhIGxpbmtlZCBsaXN0IGJ1dCBpdCBpcyBub3Rcbi8vIHRoZXJlIHdpbGwgYmUgb25seSAyIG9mIHRoZXNlIGZvciBlYWNoIHN0cmVhbVxuZnVuY3Rpb24gQ29ya2VkUmVxdWVzdChzdGF0ZSkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHRoaXMubmV4dCA9IG51bGw7XG4gIHRoaXMuZW50cnkgPSBudWxsO1xuICB0aGlzLmZpbmlzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICBvbkNvcmtlZEZpbmlzaChfdGhpcywgc3RhdGUpO1xuICB9O1xufVxuLyogPC9yZXBsYWNlbWVudD4gKi9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBhc3luY1dyaXRlID0gIXByb2Nlc3MuYnJvd3NlciAmJiBbJ3YwLjEwJywgJ3YwLjkuJ10uaW5kZXhPZihwcm9jZXNzLnZlcnNpb24uc2xpY2UoMCwgNSkpID4gLTEgPyBzZXRJbW1lZGlhdGUgOiBwbmEubmV4dFRpY2s7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBEdXBsZXg7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpbnRlcm5hbFV0aWwgPSB7XG4gIGRlcHJlY2F0ZTogcmVxdWlyZSgndXRpbC1kZXByZWNhdGUnKVxufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0nKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXI7XG52YXIgT3VyVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5IHx8IGZ1bmN0aW9uICgpIHt9O1xuZnVuY3Rpb24gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuaykge1xuICByZXR1cm4gQnVmZmVyLmZyb20oY2h1bmspO1xufVxuZnVuY3Rpb24gX2lzVWludDhBcnJheShvYmopIHtcbiAgcmV0dXJuIEJ1ZmZlci5pc0J1ZmZlcihvYmopIHx8IG9iaiBpbnN0YW5jZW9mIE91clVpbnQ4QXJyYXk7XG59XG5cbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgZGVzdHJveUltcGwgPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvZGVzdHJveScpO1xuXG51dGlsLmluaGVyaXRzKFdyaXRhYmxlLCBTdHJlYW0pO1xuXG5mdW5jdGlvbiBub3AoKSB7fVxuXG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIER1cGxleCBzdHJlYW1zIGFyZSBib3RoIHJlYWRhYmxlIGFuZCB3cml0YWJsZSwgYnV0IHNoYXJlXG4gIC8vIHRoZSBzYW1lIG9wdGlvbnMgb2JqZWN0LlxuICAvLyBIb3dldmVyLCBzb21lIGNhc2VzIHJlcXVpcmUgc2V0dGluZyBvcHRpb25zIHRvIGRpZmZlcmVudFxuICAvLyB2YWx1ZXMgZm9yIHRoZSByZWFkYWJsZSBhbmQgdGhlIHdyaXRhYmxlIHNpZGVzIG9mIHRoZSBkdXBsZXggc3RyZWFtLlxuICAvLyBUaGVzZSBvcHRpb25zIGNhbiBiZSBwcm92aWRlZCBzZXBhcmF0ZWx5IGFzIHJlYWRhYmxlWFhYIGFuZCB3cml0YWJsZVhYWC5cbiAgdmFyIGlzRHVwbGV4ID0gc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChpc0R1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy53cml0YWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIHdyaXRlKCkgc3RhcnRzIHJldHVybmluZyBmYWxzZVxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIHRoYXQgd2UgYWx3YXlzIHJldHVybiBmYWxzZSBpZlxuICAvLyB0aGUgZW50aXJlIGJ1ZmZlciBpcyBub3QgZmx1c2hlZCBpbW1lZGlhdGVseSBvbiB3cml0ZSgpXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciB3cml0YWJsZUh3bSA9IG9wdGlvbnMud3JpdGFibGVIaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuXG4gIGlmIChod20gfHwgaHdtID09PSAwKSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod207ZWxzZSBpZiAoaXNEdXBsZXggJiYgKHdyaXRhYmxlSHdtIHx8IHdyaXRhYmxlSHdtID09PSAwKSkgdGhpcy5oaWdoV2F0ZXJNYXJrID0gd3JpdGFibGVId207ZWxzZSB0aGlzLmhpZ2hXYXRlck1hcmsgPSBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gTWF0aC5mbG9vcih0aGlzLmhpZ2hXYXRlck1hcmspO1xuXG4gIC8vIGlmIF9maW5hbCBoYXMgYmVlbiBjYWxsZWRcbiAgdGhpcy5maW5hbENhbGxlZCA9IGZhbHNlO1xuXG4gIC8vIGRyYWluIGV2ZW50IGZsYWcuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIGhhcyBpdCBiZWVuIGRlc3Ryb3llZFxuICB0aGlzLmRlc3Ryb3llZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyB3aGVuIHRydWUgYWxsIHdyaXRlcyB3aWxsIGJlIGJ1ZmZlcmVkIHVudGlsIC51bmNvcmsoKSBjYWxsXG4gIHRoaXMuY29ya2VkID0gMDtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uIChlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuXG4gIC8vIGNvdW50IGJ1ZmZlcmVkIHJlcXVlc3RzXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuXG4gIC8vIGFsbG9jYXRlIHRoZSBmaXJzdCBDb3JrZWRSZXF1ZXN0LCB0aGVyZSBpcyBhbHdheXNcbiAgLy8gb25lIGFsbG9jYXRlZCBhbmQgZnJlZSB0byB1c2UsIGFuZCB3ZSBtYWludGFpbiBhdCBtb3N0IHR3b1xuICB0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xufVxuXG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiBnZXRCdWZmZXIoKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXJlZFJlcXVlc3Q7XG4gIHZhciBvdXQgPSBbXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0YXRlLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgICAgIGdldDogaW50ZXJuYWxVdGlsLmRlcHJlY2F0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICAgICAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgKyAnaW5zdGVhZC4nLCAnREVQMDAwMycpXG4gICAgfSk7XG4gIH0gY2F0Y2ggKF8pIHt9XG59KSgpO1xuXG4vLyBUZXN0IF93cml0YWJsZVN0YXRlIGZvciBpbmhlcml0YW5jZSB0byBhY2NvdW50IGZvciBEdXBsZXggc3RyZWFtcyxcbi8vIHdob3NlIHByb3RvdHlwZSBjaGFpbiBvbmx5IHBvaW50cyB0byBSZWFkYWJsZS5cbnZhciByZWFsSGFzSW5zdGFuY2U7XG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuaGFzSW5zdGFuY2UgJiYgdHlwZW9mIEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdID09PSAnZnVuY3Rpb24nKSB7XG4gIHJlYWxIYXNJbnN0YW5jZSA9IEZ1bmN0aW9uLnByb3RvdHlwZVtTeW1ib2wuaGFzSW5zdGFuY2VdO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUsIFN5bWJvbC5oYXNJbnN0YW5jZSwge1xuICAgIHZhbHVlOiBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgICBpZiAocmVhbEhhc0luc3RhbmNlLmNhbGwodGhpcywgb2JqZWN0KSkgcmV0dXJuIHRydWU7XG4gICAgICBpZiAodGhpcyAhPT0gV3JpdGFibGUpIHJldHVybiBmYWxzZTtcblxuICAgICAgcmV0dXJuIG9iamVjdCAmJiBvYmplY3QuX3dyaXRhYmxlU3RhdGUgaW5zdGFuY2VvZiBXcml0YWJsZVN0YXRlO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICByZWFsSGFzSW5zdGFuY2UgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIHRoaXM7XG4gIH07XG59XG5cbmZ1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICAvLyBXcml0YWJsZSBjdG9yIGlzIGFwcGxpZWQgdG8gRHVwbGV4ZXMsIHRvby5cbiAgLy8gYHJlYWxIYXNJbnN0YW5jZWAgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdXNpbmcgcGxhaW4gYGluc3RhbmNlb2ZgXG4gIC8vIHdvdWxkIHJldHVybiBmYWxzZSwgYXMgbm8gYF93cml0YWJsZVN0YXRlYCBwcm9wZXJ0eSBpcyBhdHRhY2hlZC5cblxuICAvLyBUcnlpbmcgdG8gdXNlIHRoZSBjdXN0b20gYGluc3RhbmNlb2ZgIGZvciBXcml0YWJsZSBoZXJlIHdpbGwgYWxzbyBicmVhayB0aGVcbiAgLy8gTm9kZS5qcyBMYXp5VHJhbnNmb3JtIGltcGxlbWVudGF0aW9uLCB3aGljaCBoYXMgYSBub24tdHJpdmlhbCBnZXR0ZXIgZm9yXG4gIC8vIGBfd3JpdGFibGVTdGF0ZWAgdGhhdCB3b3VsZCBsZWFkIHRvIGluZmluaXRlIHJlY3Vyc2lvbi5cbiAgaWYgKCFyZWFsSGFzSW5zdGFuY2UuY2FsbChXcml0YWJsZSwgdGhpcykgJiYgISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSkge1xuICAgIHJldHVybiBuZXcgV3JpdGFibGUob3B0aW9ucyk7XG4gIH1cblxuICB0aGlzLl93cml0YWJsZVN0YXRlID0gbmV3IFdyaXRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5LlxuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53cml0ZSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGUgPSBvcHRpb25zLndyaXRlO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRldiA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGV2ID0gb3B0aW9ucy53cml0ZXY7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZGVzdHJveSA9IG9wdGlvbnMuZGVzdHJveTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5maW5hbCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmluYWwgPSBvcHRpb25zLmZpbmFsO1xuICB9XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE90aGVyd2lzZSBwZW9wbGUgY2FuIHBpcGUgV3JpdGFibGUgc3RyZWFtcywgd2hpY2ggaXMganVzdCB3cm9uZy5cbldyaXRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdDYW5ub3QgcGlwZSwgbm90IHJlYWRhYmxlJykpO1xufTtcblxuZnVuY3Rpb24gd3JpdGVBZnRlckVuZChzdHJlYW0sIGNiKSB7XG4gIHZhciBlciA9IG5ldyBFcnJvcignd3JpdGUgYWZ0ZXIgZW5kJyk7XG4gIC8vIFRPRE86IGRlZmVyIGVycm9yIGV2ZW50cyBjb25zaXN0ZW50bHkgZXZlcnl3aGVyZSwgbm90IGp1c3QgdGhlIGNiXG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgcG5hLm5leHRUaWNrKGNiLCBlcik7XG59XG5cbi8vIENoZWNrcyB0aGF0IGEgdXNlci1zdXBwbGllZCBjaHVuayBpcyB2YWxpZCwgZXNwZWNpYWxseSBmb3IgdGhlIHBhcnRpY3VsYXJcbi8vIG1vZGUgdGhlIHN0cmVhbSBpcyBpbi4gQ3VycmVudGx5IHRoaXMgbWVhbnMgdGhhdCBgbnVsbGAgaXMgbmV2ZXIgYWNjZXB0ZWRcbi8vIGFuZCB1bmRlZmluZWQvbm9uLXN0cmluZyB2YWx1ZXMgYXJlIG9ubHkgYWxsb3dlZCBpbiBvYmplY3QgbW9kZS5cbmZ1bmN0aW9uIHZhbGlkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGNiKSB7XG4gIHZhciB2YWxpZCA9IHRydWU7XG4gIHZhciBlciA9IGZhbHNlO1xuXG4gIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignTWF5IG5vdCB3cml0ZSBudWxsIHZhbHVlcyB0byBzdHJlYW0nKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmIGNodW5rICE9PSB1bmRlZmluZWQgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgfVxuICBpZiAoZXIpIHtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgcG5hLm5leHRUaWNrKGNiLCBlcik7XG4gICAgdmFsaWQgPSBmYWxzZTtcbiAgfVxuICByZXR1cm4gdmFsaWQ7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG4gIHZhciByZXQgPSBmYWxzZTtcbiAgdmFyIGlzQnVmID0gIXN0YXRlLm9iamVjdE1vZGUgJiYgX2lzVWludDhBcnJheShjaHVuayk7XG5cbiAgaWYgKGlzQnVmICYmICFCdWZmZXIuaXNCdWZmZXIoY2h1bmspKSB7XG4gICAgY2h1bmsgPSBfdWludDhBcnJheVRvQnVmZmVyKGNodW5rKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChpc0J1ZikgZW5jb2RpbmcgPSAnYnVmZmVyJztlbHNlIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuXG4gIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpIGNiID0gbm9wO1xuXG4gIGlmIChzdGF0ZS5lbmRlZCkgd3JpdGVBZnRlckVuZCh0aGlzLCBjYik7ZWxzZSBpZiAoaXNCdWYgfHwgdmFsaWRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGNiKSkge1xuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGlzQnVmLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBzdGF0ZS5jb3JrZWQrKztcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS51bmNvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZC0tO1xuXG4gICAgaWYgKCFzdGF0ZS53cml0aW5nICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCkgY2xlYXJCdWZmZXIodGhpcywgc3RhdGUpO1xuICB9XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuc2V0RGVmYXVsdEVuY29kaW5nID0gZnVuY3Rpb24gc2V0RGVmYXVsdEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIC8vIG5vZGU6OlBhcnNlRW5jb2RpbmcoKSByZXF1aXJlcyBsb3dlciBjYXNlLlxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykgZW5jb2RpbmcgPSBlbmNvZGluZy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoIShbJ2hleCcsICd1dGY4JywgJ3V0Zi04JywgJ2FzY2lpJywgJ2JpbmFyeScsICdiYXNlNjQnLCAndWNzMicsICd1Y3MtMicsICd1dGYxNmxlJywgJ3V0Zi0xNmxlJywgJ3JhdyddLmluZGV4T2YoKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKCkpID4gLTEpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB0aGlzLl93cml0YWJsZVN0YXRlLmRlZmF1bHRFbmNvZGluZyA9IGVuY29kaW5nO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpIHtcbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmIHN0YXRlLmRlY29kZVN0cmluZ3MgIT09IGZhbHNlICYmIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBjaHVuayA9IEJ1ZmZlci5mcm9tKGNodW5rLCBlbmNvZGluZyk7XG4gIH1cbiAgcmV0dXJuIGNodW5rO1xufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnd3JpdGFibGVIaWdoV2F0ZXJNYXJrJywge1xuICAvLyBtYWtpbmcgaXQgZXhwbGljaXQgdGhpcyBwcm9wZXJ0eSBpcyBub3QgZW51bWVyYWJsZVxuICAvLyBiZWNhdXNlIG90aGVyd2lzZSBzb21lIHByb3RvdHlwZSBtYW5pcHVsYXRpb24gaW5cbiAgLy8gdXNlcmxhbmQgd2lsbCBmYWlsXG4gIGVudW1lcmFibGU6IGZhbHNlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZS5oaWdoV2F0ZXJNYXJrO1xuICB9XG59KTtcblxuLy8gaWYgd2UncmUgYWxyZWFkeSB3cml0aW5nIHNvbWV0aGluZywgdGhlbiBqdXN0IHB1dCB0aGlzXG4vLyBpbiB0aGUgcXVldWUsIGFuZCB3YWl0IG91ciB0dXJuLiAgT3RoZXJ3aXNlLCBjYWxsIF93cml0ZVxuLy8gSWYgd2UgcmV0dXJuIGZhbHNlLCB0aGVuIHdlIG5lZWQgYSBkcmFpbiBldmVudCwgc28gc2V0IHRoYXQgZmxhZy5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgaXNCdWYsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgaWYgKCFpc0J1Zikge1xuICAgIHZhciBuZXdDaHVuayA9IGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpO1xuICAgIGlmIChjaHVuayAhPT0gbmV3Q2h1bmspIHtcbiAgICAgIGlzQnVmID0gdHJ1ZTtcbiAgICAgIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gICAgICBjaHVuayA9IG5ld0NodW5rO1xuICAgIH1cbiAgfVxuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcblxuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgLy8gd2UgbXVzdCBlbnN1cmUgdGhhdCBwcmV2aW91cyBuZWVkRHJhaW4gd2lsbCBub3QgYmUgcmVzZXQgdG8gZmFsc2UuXG4gIGlmICghcmV0KSBzdGF0ZS5uZWVkRHJhaW4gPSB0cnVlO1xuXG4gIGlmIChzdGF0ZS53cml0aW5nIHx8IHN0YXRlLmNvcmtlZCkge1xuICAgIHZhciBsYXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0ge1xuICAgICAgY2h1bms6IGNodW5rLFxuICAgICAgZW5jb2Rpbmc6IGVuY29kaW5nLFxuICAgICAgaXNCdWY6IGlzQnVmLFxuICAgICAgY2FsbGJhY2s6IGNiLFxuICAgICAgbmV4dDogbnVsbFxuICAgIH07XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIGxhc3QubmV4dCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgfVxuICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ICs9IDE7XG4gIH0gZWxzZSB7XG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgd3JpdGV2LCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgc3RhdGUud3JpdGVsZW4gPSBsZW47XG4gIHN0YXRlLndyaXRlY2IgPSBjYjtcbiAgc3RhdGUud3JpdGluZyA9IHRydWU7XG4gIHN0YXRlLnN5bmMgPSB0cnVlO1xuICBpZiAod3JpdGV2KSBzdHJlYW0uX3dyaXRldihjaHVuaywgc3RhdGUub253cml0ZSk7ZWxzZSBzdHJlYW0uX3dyaXRlKGNodW5rLCBlbmNvZGluZywgc3RhdGUub253cml0ZSk7XG4gIHN0YXRlLnN5bmMgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYikge1xuICAtLXN0YXRlLnBlbmRpbmdjYjtcblxuICBpZiAoc3luYykge1xuICAgIC8vIGRlZmVyIHRoZSBjYWxsYmFjayBpZiB3ZSBhcmUgYmVpbmcgY2FsbGVkIHN5bmNocm9ub3VzbHlcbiAgICAvLyB0byBhdm9pZCBwaWxpbmcgdXAgdGhpbmdzIG9uIHRoZSBzdGFja1xuICAgIHBuYS5uZXh0VGljayhjYiwgZXIpO1xuICAgIC8vIHRoaXMgY2FuIGVtaXQgZmluaXNoLCBhbmQgaXQgd2lsbCBhbHdheXMgaGFwcGVuXG4gICAgLy8gYWZ0ZXIgZXJyb3JcbiAgICBwbmEubmV4dFRpY2soZmluaXNoTWF5YmUsIHN0cmVhbSwgc3RhdGUpO1xuICAgIHN0cmVhbS5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB0aGUgY2FsbGVyIGV4cGVjdCB0aGlzIHRvIGhhcHBlbiBiZWZvcmUgaWZcbiAgICAvLyBpdCBpcyBhc3luY1xuICAgIGNiKGVyKTtcbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgLy8gdGhpcyBjYW4gZW1pdCBmaW5pc2gsIGJ1dCBmaW5pc2ggbXVzdFxuICAgIC8vIGFsd2F5cyBmb2xsb3cgZXJyb3JcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpIHtcbiAgc3RhdGUud3JpdGluZyA9IGZhbHNlO1xuICBzdGF0ZS53cml0ZWNiID0gbnVsbDtcbiAgc3RhdGUubGVuZ3RoIC09IHN0YXRlLndyaXRlbGVuO1xuICBzdGF0ZS53cml0ZWxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcblxuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuXG4gIGlmIChlcikgb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYik7ZWxzZSB7XG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgYWN0dWFsbHkgcmVhZHkgdG8gZmluaXNoLCBidXQgZG9uJ3QgZW1pdCB5ZXRcbiAgICB2YXIgZmluaXNoZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcblxuICAgIGlmICghZmluaXNoZWQgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIHtcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cblxuICAgIGlmIChzeW5jKSB7XG4gICAgICAvKjxyZXBsYWNlbWVudD4qL1xuICAgICAgYXN5bmNXcml0ZShhZnRlcldyaXRlLCBzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgICAgLyo8L3JlcGxhY2VtZW50PiovXG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZCkgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgY2IoKTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbi8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5uZWVkRHJhaW4pIHtcbiAgICBzdGF0ZS5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZHJhaW4nKTtcbiAgfVxufVxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0O1xuXG4gIGlmIChzdHJlYW0uX3dyaXRldiAmJiBlbnRyeSAmJiBlbnRyeS5uZXh0KSB7XG4gICAgLy8gRmFzdCBjYXNlLCB3cml0ZSBldmVyeXRoaW5nIHVzaW5nIF93cml0ZXYoKVxuICAgIHZhciBsID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ7XG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheShsKTtcbiAgICB2YXIgaG9sZGVyID0gc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO1xuICAgIGhvbGRlci5lbnRyeSA9IGVudHJ5O1xuXG4gICAgdmFyIGNvdW50ID0gMDtcbiAgICB2YXIgYWxsQnVmZmVycyA9IHRydWU7XG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICBidWZmZXJbY291bnRdID0gZW50cnk7XG4gICAgICBpZiAoIWVudHJ5LmlzQnVmKSBhbGxCdWZmZXJzID0gZmFsc2U7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICBjb3VudCArPSAxO1xuICAgIH1cbiAgICBidWZmZXIuYWxsQnVmZmVycyA9IGFsbEJ1ZmZlcnM7XG5cbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHRydWUsIHN0YXRlLmxlbmd0aCwgYnVmZmVyLCAnJywgaG9sZGVyLmZpbmlzaCk7XG5cbiAgICAvLyBkb1dyaXRlIGlzIGFsbW9zdCBhbHdheXMgYXN5bmMsIGRlZmVyIHRoZXNlIHRvIHNhdmUgYSBiaXQgb2YgdGltZVxuICAgIC8vIGFzIHRoZSBob3QgcGF0aCBlbmRzIHdpdGggZG9Xcml0ZVxuICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICAgIGlmIChob2xkZXIubmV4dCkge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gaG9sZGVyLm5leHQ7XG4gICAgICBob2xkZXIubmV4dCA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHN0YXRlKTtcbiAgICB9XG4gICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIFNsb3cgY2FzZSwgd3JpdGUgY2h1bmtzIG9uZS1ieS1vbmVcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjaHVuayA9IGVudHJ5LmNodW5rO1xuICAgICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICAgIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICAgICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50LS07XG4gICAgICAvLyBpZiB3ZSBkaWRuJ3QgY2FsbCB0aGUgb253cml0ZSBpbW1lZGlhdGVseSwgdGhlblxuICAgICAgLy8gaXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIHdhaXQgdW50aWwgaXQgZG9lcy5cbiAgICAgIC8vIGFsc28sIHRoYXQgbWVhbnMgdGhhdCB0aGUgY2h1bmsgYW5kIGNiIGFyZSBjdXJyZW50bHlcbiAgICAgIC8vIGJlaW5nIHByb2Nlc3NlZCwgc28gbW92ZSB0aGUgYnVmZmVyIGNvdW50ZXIgcGFzdCB0aGVtLlxuICAgICAgaWYgKHN0YXRlLndyaXRpbmcpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5ID09PSBudWxsKSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCA9IGVudHJ5O1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihuZXcgRXJyb3IoJ193cml0ZSgpIGlzIG5vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGV2ID0gbnVsbDtcblxuV3JpdGFibGUucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBjaHVuayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gY2h1bms7XG4gICAgY2h1bmsgPSBudWxsO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkKSB0aGlzLndyaXRlKGNodW5rLCBlbmNvZGluZyk7XG5cbiAgLy8gLmVuZCgpIGZ1bGx5IHVuY29ya3NcbiAgaWYgKHN0YXRlLmNvcmtlZCkge1xuICAgIHN0YXRlLmNvcmtlZCA9IDE7XG4gICAgdGhpcy51bmNvcmsoKTtcbiAgfVxuXG4gIC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cbiAgaWYgKCFzdGF0ZS5lbmRpbmcgJiYgIXN0YXRlLmZpbmlzaGVkKSBlbmRXcml0YWJsZSh0aGlzLCBzdGF0ZSwgY2IpO1xufTtcblxuZnVuY3Rpb24gbmVlZEZpbmlzaChzdGF0ZSkge1xuICByZXR1cm4gc3RhdGUuZW5kaW5nICYmIHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPT09IG51bGwgJiYgIXN0YXRlLmZpbmlzaGVkICYmICFzdGF0ZS53cml0aW5nO1xufVxuZnVuY3Rpb24gY2FsbEZpbmFsKHN0cmVhbSwgc3RhdGUpIHtcbiAgc3RyZWFtLl9maW5hbChmdW5jdGlvbiAoZXJyKSB7XG4gICAgc3RhdGUucGVuZGluZ2NiLS07XG4gICAgaWYgKGVycikge1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICB9XG4gICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgfSk7XG59XG5mdW5jdGlvbiBwcmVmaW5pc2goc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnByZWZpbmlzaGVkICYmICFzdGF0ZS5maW5hbENhbGxlZCkge1xuICAgIGlmICh0eXBlb2Ygc3RyZWFtLl9maW5hbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgICBzdGF0ZS5maW5hbENhbGxlZCA9IHRydWU7XG4gICAgICBwbmEubmV4dFRpY2soY2FsbEZpbmFsLCBzdHJlYW0sIHN0YXRlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucHJlZmluaXNoZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLmVtaXQoJ3ByZWZpbmlzaCcpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBuZWVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG4gIGlmIChuZWVkKSB7XG4gICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICAgIGlmIChzdGF0ZS5wZW5kaW5nY2IgPT09IDApIHtcbiAgICAgIHN0YXRlLmZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5lbWl0KCdmaW5pc2gnKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5lZWQ7XG59XG5cbmZ1bmN0aW9uIGVuZFdyaXRhYmxlKHN0cmVhbSwgc3RhdGUsIGNiKSB7XG4gIHN0YXRlLmVuZGluZyA9IHRydWU7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xuICBpZiAoY2IpIHtcbiAgICBpZiAoc3RhdGUuZmluaXNoZWQpIHBuYS5uZXh0VGljayhjYik7ZWxzZSBzdHJlYW0ub25jZSgnZmluaXNoJywgY2IpO1xuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgc3RyZWFtLndyaXRhYmxlID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG9uQ29ya2VkRmluaXNoKGNvcmtSZXEsIHN0YXRlLCBlcnIpIHtcbiAgdmFyIGVudHJ5ID0gY29ya1JlcS5lbnRyeTtcbiAgY29ya1JlcS5lbnRyeSA9IG51bGw7XG4gIHdoaWxlIChlbnRyeSkge1xuICAgIHZhciBjYiA9IGVudHJ5LmNhbGxiYWNrO1xuICAgIHN0YXRlLnBlbmRpbmdjYi0tO1xuICAgIGNiKGVycik7XG4gICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICB9XG4gIGlmIChzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUpIHtcbiAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dCA9IGNvcmtSZXE7XG4gIH0gZWxzZSB7XG4gICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gY29ya1JlcTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGUucHJvdG90eXBlLCAnZGVzdHJveWVkJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAvLyB3ZSBpZ25vcmUgdGhlIHZhbHVlIGlmIHRoZSBzdHJlYW1cbiAgICAvLyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgaWYgKCF0aGlzLl93cml0YWJsZVN0YXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdGhlIHVzZXIgaXMgZXhwbGljaXRseVxuICAgIC8vIG1hbmFnaW5nIGRlc3Ryb3llZFxuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdmFsdWU7XG4gIH1cbn0pO1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLmRlc3Ryb3k7XG5Xcml0YWJsZS5wcm90b3R5cGUuX3VuZGVzdHJveSA9IGRlc3Ryb3lJbXBsLnVuZGVzdHJveTtcbldyaXRhYmxlLnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIChlcnIsIGNiKSB7XG4gIHRoaXMuZW5kKCk7XG4gIGNiKGVycik7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlcjtcbnZhciB1dGlsID0gcmVxdWlyZSgzNCk7XG5cbmZ1bmN0aW9uIGNvcHlCdWZmZXIoc3JjLCB0YXJnZXQsIG9mZnNldCkge1xuICBzcmMuY29weSh0YXJnZXQsIG9mZnNldCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBCdWZmZXJMaXN0KCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBCdWZmZXJMaXN0KTtcblxuICAgIHRoaXMuaGVhZCA9IG51bGw7XG4gICAgdGhpcy50YWlsID0gbnVsbDtcbiAgICB0aGlzLmxlbmd0aCA9IDA7XG4gIH1cblxuICBCdWZmZXJMaXN0LnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gcHVzaCh2KSB7XG4gICAgdmFyIGVudHJ5ID0geyBkYXRhOiB2LCBuZXh0OiBudWxsIH07XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gMCkgdGhpcy50YWlsLm5leHQgPSBlbnRyeTtlbHNlIHRoaXMuaGVhZCA9IGVudHJ5O1xuICAgIHRoaXMudGFpbCA9IGVudHJ5O1xuICAgICsrdGhpcy5sZW5ndGg7XG4gIH07XG5cbiAgQnVmZmVyTGlzdC5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uIHVuc2hpZnQodikge1xuICAgIHZhciBlbnRyeSA9IHsgZGF0YTogdiwgbmV4dDogdGhpcy5oZWFkIH07XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSB0aGlzLnRhaWwgPSBlbnRyeTtcbiAgICB0aGlzLmhlYWQgPSBlbnRyeTtcbiAgICArK3RoaXMubGVuZ3RoO1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24gc2hpZnQoKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgdmFyIHJldCA9IHRoaXMuaGVhZC5kYXRhO1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtlbHNlIHRoaXMuaGVhZCA9IHRoaXMuaGVhZC5uZXh0O1xuICAgIC0tdGhpcy5sZW5ndGg7XG4gICAgcmV0dXJuIHJldDtcbiAgfTtcblxuICBCdWZmZXJMaXN0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiBqb2luKHMpIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgICB2YXIgcCA9IHRoaXMuaGVhZDtcbiAgICB2YXIgcmV0ID0gJycgKyBwLmRhdGE7XG4gICAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICAgIHJldCArPSBzICsgcC5kYXRhO1xuICAgIH1yZXR1cm4gcmV0O1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdChuKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gQnVmZmVyLmFsbG9jKDApO1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHRoaXMuaGVhZC5kYXRhO1xuICAgIHZhciByZXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobiA+Pj4gMCk7XG4gICAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChwKSB7XG4gICAgICBjb3B5QnVmZmVyKHAuZGF0YSwgcmV0LCBpKTtcbiAgICAgIGkgKz0gcC5kYXRhLmxlbmd0aDtcbiAgICAgIHAgPSBwLm5leHQ7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH07XG5cbiAgcmV0dXJuIEJ1ZmZlckxpc3Q7XG59KCk7XG5cbmlmICh1dGlsICYmIHV0aWwuaW5zcGVjdCAmJiB1dGlsLmluc3BlY3QuY3VzdG9tKSB7XG4gIG1vZHVsZS5leHBvcnRzLnByb3RvdHlwZVt1dGlsLmluc3BlY3QuY3VzdG9tXSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgb2JqID0gdXRpbC5pbnNwZWN0KHsgbGVuZ3RoOiB0aGlzLmxlbmd0aCB9KTtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5uYW1lICsgJyAnICsgb2JqO1xuICB9O1xufSIsIid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIHBuYSA9IHJlcXVpcmUoNzYpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8vIHVuZG9jdW1lbnRlZCBjYigpIEFQSSwgbmVlZGVkIGZvciBjb3JlLCBub3QgZm9yIHB1YmxpYyBBUElcbmZ1bmN0aW9uIGRlc3Ryb3koZXJyLCBjYikge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHZhciByZWFkYWJsZURlc3Ryb3llZCA9IHRoaXMuX3JlYWRhYmxlU3RhdGUgJiYgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIHZhciB3cml0YWJsZURlc3Ryb3llZCA9IHRoaXMuX3dyaXRhYmxlU3RhdGUgJiYgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG5cbiAgaWYgKHJlYWRhYmxlRGVzdHJveWVkIHx8IHdyaXRhYmxlRGVzdHJveWVkKSB7XG4gICAgaWYgKGNiKSB7XG4gICAgICBjYihlcnIpO1xuICAgIH0gZWxzZSBpZiAoZXJyICYmICghdGhpcy5fd3JpdGFibGVTdGF0ZSB8fCAhdGhpcy5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQpKSB7XG4gICAgICBwbmEubmV4dFRpY2soZW1pdEVycm9yTlQsIHRoaXMsIGVycik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gd2Ugc2V0IGRlc3Ryb3llZCB0byB0cnVlIGJlZm9yZSBmaXJpbmcgZXJyb3IgY2FsbGJhY2tzIGluIG9yZGVyXG4gIC8vIHRvIG1ha2UgaXQgcmUtZW50cmFuY2Ugc2FmZSBpbiBjYXNlIGRlc3Ryb3koKSBpcyBjYWxsZWQgd2l0aGluIGNhbGxiYWNrc1xuXG4gIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlKSB7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB0cnVlO1xuICB9XG5cbiAgLy8gaWYgdGhpcyBpcyBhIGR1cGxleCBzdHJlYW0gbWFyayB0aGUgd3JpdGFibGUgcGFydCBhcyBkZXN0cm95ZWQgYXMgd2VsbFxuICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdHJ1ZTtcbiAgfVxuXG4gIHRoaXMuX2Rlc3Ryb3koZXJyIHx8IG51bGwsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoIWNiICYmIGVycikge1xuICAgICAgcG5hLm5leHRUaWNrKGVtaXRFcnJvck5ULCBfdGhpcywgZXJyKTtcbiAgICAgIGlmIChfdGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgICAgICBfdGhpcy5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY2IpIHtcbiAgICAgIGNiKGVycik7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gdW5kZXN0cm95KCkge1xuICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKHRoaXMuX3dyaXRhYmxlU3RhdGUpIHtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZmluaXNoZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRFcnJvck5UKHNlbGYsIGVycikge1xuICBzZWxmLmVtaXQoJ2Vycm9yJywgZXJyKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGRlc3Ryb3k6IGRlc3Ryb3ksXG4gIHVuZGVzdHJveTogdW5kZXN0cm95XG59OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSg2MikuRXZlbnRFbWl0dGVyO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKDg5KS5QYXNzVGhyb3VnaFxuIiwiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSg4MSk7XG5leHBvcnRzLlN0cmVhbSA9IGV4cG9ydHM7XG5leHBvcnRzLlJlYWRhYmxlID0gZXhwb3J0cztcbmV4cG9ydHMuV3JpdGFibGUgPSByZXF1aXJlKDgzKTtcbmV4cG9ydHMuRHVwbGV4ID0gcmVxdWlyZSg3OSk7XG5leHBvcnRzLlRyYW5zZm9ybSA9IHJlcXVpcmUoODIpO1xuZXhwb3J0cy5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoODApO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKDg5KS5UcmFuc2Zvcm1cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSg4Myk7XG4iLCIndXNlIHN0cmljdCdcbnZhciBCdWZmZXIgPSByZXF1aXJlKDM1KS5CdWZmZXJcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoNjUpXG52YXIgSGFzaEJhc2UgPSByZXF1aXJlKDYzKVxuXG52YXIgQVJSQVkxNiA9IG5ldyBBcnJheSgxNilcblxudmFyIHpsID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dXG5cbnZhciB6ciA9IFtcbiAgNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMixcbiAgNiwgMTEsIDMsIDcsIDAsIDEzLCA1LCAxMCwgMTQsIDE1LCA4LCAxMiwgNCwgOSwgMSwgMixcbiAgMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxMyxcbiAgOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNCxcbiAgMTIsIDE1LCAxMCwgNCwgMSwgNSwgOCwgNywgNiwgMiwgMTMsIDE0LCAwLCAzLCA5LCAxMVxuXVxuXG52YXIgc2wgPSBbXG4gIDExLCAxNCwgMTUsIDEyLCA1LCA4LCA3LCA5LCAxMSwgMTMsIDE0LCAxNSwgNiwgNywgOSwgOCxcbiAgNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyLFxuICAxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDUsXG4gIDExLCAxMiwgMTQsIDE1LCAxNCwgMTUsIDksIDgsIDksIDE0LCA1LCA2LCA4LCA2LCA1LCAxMixcbiAgOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XG5dXG5cbnZhciBzciA9IFtcbiAgOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2LFxuICA5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTEsXG4gIDksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNSxcbiAgMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4LFxuICA4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFcbl1cblxudmFyIGhsID0gWzB4MDAwMDAwMDAsIDB4NWE4Mjc5OTksIDB4NmVkOWViYTEsIDB4OGYxYmJjZGMsIDB4YTk1M2ZkNGVdXG52YXIgaHIgPSBbMHg1MGEyOGJlNiwgMHg1YzRkZDEyNCwgMHg2ZDcwM2VmMywgMHg3YTZkNzZlOSwgMHgwMDAwMDAwMF1cblxuZnVuY3Rpb24gUklQRU1EMTYwICgpIHtcbiAgSGFzaEJhc2UuY2FsbCh0aGlzLCA2NClcblxuICAvLyBzdGF0ZVxuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxuICB0aGlzLl9lID0gMHhjM2QyZTFmMFxufVxuXG5pbmhlcml0cyhSSVBFTUQxNjAsIEhhc2hCYXNlKVxuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB3b3JkcyA9IEFSUkFZMTZcbiAgZm9yICh2YXIgaiA9IDA7IGogPCAxNjsgKytqKSB3b3Jkc1tqXSA9IHRoaXMuX2Jsb2NrLnJlYWRJbnQzMkxFKGogKiA0KVxuXG4gIHZhciBhbCA9IHRoaXMuX2EgfCAwXG4gIHZhciBibCA9IHRoaXMuX2IgfCAwXG4gIHZhciBjbCA9IHRoaXMuX2MgfCAwXG4gIHZhciBkbCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlbCA9IHRoaXMuX2UgfCAwXG5cbiAgdmFyIGFyID0gdGhpcy5fYSB8IDBcbiAgdmFyIGJyID0gdGhpcy5fYiB8IDBcbiAgdmFyIGNyID0gdGhpcy5fYyB8IDBcbiAgdmFyIGRyID0gdGhpcy5fZCB8IDBcbiAgdmFyIGVyID0gdGhpcy5fZSB8IDBcblxuICAvLyBjb21wdXRhdGlvblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDgwOyBpICs9IDEpIHtcbiAgICB2YXIgdGxcbiAgICB2YXIgdHJcbiAgICBpZiAoaSA8IDE2KSB7XG4gICAgICB0bCA9IGZuMShhbCwgYmwsIGNsLCBkbCwgZWwsIHdvcmRzW3psW2ldXSwgaGxbMF0sIHNsW2ldKVxuICAgICAgdHIgPSBmbjUoYXIsIGJyLCBjciwgZHIsIGVyLCB3b3Jkc1t6cltpXV0sIGhyWzBdLCBzcltpXSlcbiAgICB9IGVsc2UgaWYgKGkgPCAzMikge1xuICAgICAgdGwgPSBmbjIoYWwsIGJsLCBjbCwgZGwsIGVsLCB3b3Jkc1t6bFtpXV0sIGhsWzFdLCBzbFtpXSlcbiAgICAgIHRyID0gZm40KGFyLCBiciwgY3IsIGRyLCBlciwgd29yZHNbenJbaV1dLCBoclsxXSwgc3JbaV0pXG4gICAgfSBlbHNlIGlmIChpIDwgNDgpIHtcbiAgICAgIHRsID0gZm4zKGFsLCBibCwgY2wsIGRsLCBlbCwgd29yZHNbemxbaV1dLCBobFsyXSwgc2xbaV0pXG4gICAgICB0ciA9IGZuMyhhciwgYnIsIGNyLCBkciwgZXIsIHdvcmRzW3pyW2ldXSwgaHJbMl0sIHNyW2ldKVxuICAgIH0gZWxzZSBpZiAoaSA8IDY0KSB7XG4gICAgICB0bCA9IGZuNChhbCwgYmwsIGNsLCBkbCwgZWwsIHdvcmRzW3psW2ldXSwgaGxbM10sIHNsW2ldKVxuICAgICAgdHIgPSBmbjIoYXIsIGJyLCBjciwgZHIsIGVyLCB3b3Jkc1t6cltpXV0sIGhyWzNdLCBzcltpXSlcbiAgICB9IGVsc2UgeyAvLyBpZiAoaTw4MCkge1xuICAgICAgdGwgPSBmbjUoYWwsIGJsLCBjbCwgZGwsIGVsLCB3b3Jkc1t6bFtpXV0sIGhsWzRdLCBzbFtpXSlcbiAgICAgIHRyID0gZm4xKGFyLCBiciwgY3IsIGRyLCBlciwgd29yZHNbenJbaV1dLCBocls0XSwgc3JbaV0pXG4gICAgfVxuXG4gICAgYWwgPSBlbFxuICAgIGVsID0gZGxcbiAgICBkbCA9IHJvdGwoY2wsIDEwKVxuICAgIGNsID0gYmxcbiAgICBibCA9IHRsXG5cbiAgICBhciA9IGVyXG4gICAgZXIgPSBkclxuICAgIGRyID0gcm90bChjciwgMTApXG4gICAgY3IgPSBiclxuICAgIGJyID0gdHJcbiAgfVxuXG4gIC8vIHVwZGF0ZSBzdGF0ZVxuICB2YXIgdCA9ICh0aGlzLl9iICsgY2wgKyBkcikgfCAwXG4gIHRoaXMuX2IgPSAodGhpcy5fYyArIGRsICsgZXIpIHwgMFxuICB0aGlzLl9jID0gKHRoaXMuX2QgKyBlbCArIGFyKSB8IDBcbiAgdGhpcy5fZCA9ICh0aGlzLl9lICsgYWwgKyBicikgfCAwXG4gIHRoaXMuX2UgPSAodGhpcy5fYSArIGJsICsgY3IpIHwgMFxuICB0aGlzLl9hID0gdFxufVxuXG5SSVBFTUQxNjAucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIGNyZWF0ZSBwYWRkaW5nIGFuZCBoYW5kbGUgYmxvY2tzXG4gIHRoaXMuX2Jsb2NrW3RoaXMuX2Jsb2NrT2Zmc2V0KytdID0gMHg4MFxuICBpZiAodGhpcy5fYmxvY2tPZmZzZXQgPiA1Nikge1xuICAgIHRoaXMuX2Jsb2NrLmZpbGwoMCwgdGhpcy5fYmxvY2tPZmZzZXQsIDY0KVxuICAgIHRoaXMuX3VwZGF0ZSgpXG4gICAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIH1cblxuICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMF0sIDU2KVxuICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkxFKHRoaXMuX2xlbmd0aFsxXSwgNjApXG4gIHRoaXMuX3VwZGF0ZSgpXG5cbiAgLy8gcHJvZHVjZSByZXN1bHRcbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyA/IEJ1ZmZlci5hbGxvYygyMCkgOiBuZXcgQnVmZmVyKDIwKVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2EsIDApXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYiwgNClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9jLCA4KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2QsIDEyKVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2UsIDE2KVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIHJvdGwgKHgsIG4pIHtcbiAgcmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKVxufVxuXG5mdW5jdGlvbiBmbjEgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKGIgXiBjIF4gZCkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5mdW5jdGlvbiBmbjIgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiICYgYykgfCAoKH5iKSAmIGQpKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbmZ1bmN0aW9uIGZuMyAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgfCAofmMpKSBeIGQpICsgbSArIGspIHwgMCwgcykgKyBlKSB8IDBcbn1cblxuZnVuY3Rpb24gZm40IChhLCBiLCBjLCBkLCBlLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYiAmIGQpIHwgKGMgJiAofmQpKSkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5mdW5jdGlvbiBmbjUgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKGIgXiAoYyB8ICh+ZCkpKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUklQRU1EMTYwXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBub2RlL25vLWRlcHJlY2F0ZWQtYXBpICovXG52YXIgYnVmZmVyID0gcmVxdWlyZSgzNSlcbnZhciBCdWZmZXIgPSBidWZmZXIuQnVmZmVyXG5cbi8vIGFsdGVybmF0aXZlIHRvIHVzaW5nIE9iamVjdC5rZXlzIGZvciBvbGQgYnJvd3NlcnNcbmZ1bmN0aW9uIGNvcHlQcm9wcyAoc3JjLCBkc3QpIHtcbiAgZm9yICh2YXIga2V5IGluIHNyYykge1xuICAgIGRzdFtrZXldID0gc3JjW2tleV1cbiAgfVxufVxuaWYgKEJ1ZmZlci5mcm9tICYmIEJ1ZmZlci5hbGxvYyAmJiBCdWZmZXIuYWxsb2NVbnNhZmUgJiYgQnVmZmVyLmFsbG9jVW5zYWZlU2xvdykge1xuICBtb2R1bGUuZXhwb3J0cyA9IGJ1ZmZlclxufSBlbHNlIHtcbiAgLy8gQ29weSBwcm9wZXJ0aWVzIGZyb20gcmVxdWlyZSgnYnVmZmVyJylcbiAgY29weVByb3BzKGJ1ZmZlciwgZXhwb3J0cylcbiAgZXhwb3J0cy5CdWZmZXIgPSBTYWZlQnVmZmVyXG59XG5cbmZ1bmN0aW9uIFNhZmVCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIENvcHkgc3RhdGljIG1ldGhvZHMgZnJvbSBCdWZmZXJcbmNvcHlQcm9wcyhCdWZmZXIsIFNhZmVCdWZmZXIpXG5cblNhZmVCdWZmZXIuZnJvbSA9IGZ1bmN0aW9uIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuU2FmZUJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgdmFyIGJ1ZiA9IEJ1ZmZlcihzaXplKVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgIH0gZWxzZSB7XG4gICAgICBidWYuZmlsbChmaWxsKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBidWYuZmlsbCgwKVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKHNpemUpXG59XG5cblNhZmVCdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBidWZmZXIuU2xvd0J1ZmZlcihzaXplKVxufVxuIiwiIWZ1bmN0aW9uKGdsb2JhbHMpe1xuJ3VzZSBzdHJpY3QnXG5cbi8vKioqIFVNRCBCRUdJTlxuaWYgKHR5cGVvZiBkZWZpbmUgIT09ICd1bmRlZmluZWQnICYmIGRlZmluZS5hbWQpIHsgLy9yZXF1aXJlLmpzIC8gQU1EXG4gIGRlZmluZShbXSwgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNlY3VyZVJhbmRvbVxuICB9KVxufSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykgeyAvL0NvbW1vbkpTXG4gIG1vZHVsZS5leHBvcnRzID0gc2VjdXJlUmFuZG9tXG59IGVsc2UgeyAvL3NjcmlwdCAvIGJyb3dzZXJcbiAgZ2xvYmFscy5zZWN1cmVSYW5kb20gPSBzZWN1cmVSYW5kb21cbn1cbi8vKioqIFVNRCBFTkRcblxuLy9vcHRpb25zLnR5cGUgaXMgdGhlIG9ubHkgdmFsaWQgb3B0aW9uXG5mdW5jdGlvbiBzZWN1cmVSYW5kb20oY291bnQsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge3R5cGU6ICdBcnJheSd9XG4gIC8vd2UgY2hlY2sgZm9yIHByb2Nlc3MucGlkIHRvIHByZXZlbnQgYnJvd3NlcmlmeSBmcm9tIHRyaWNraW5nIHVzXG4gIGlmICh0eXBlb2YgcHJvY2VzcyAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgcHJvY2Vzcy5waWQgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gbm9kZVJhbmRvbShjb3VudCwgb3B0aW9ucylcbiAgfSBlbHNlIHtcbiAgICB2YXIgY3J5cHRvID0gd2luZG93LmNyeXB0byB8fCB3aW5kb3cubXNDcnlwdG9cbiAgICBpZiAoIWNyeXB0bykgdGhyb3cgbmV3IEVycm9yKFwiWW91ciBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgd2luZG93LmNyeXB0by5cIilcbiAgICByZXR1cm4gYnJvd3NlclJhbmRvbShjb3VudCwgb3B0aW9ucylcbiAgfVxufVxuXG5mdW5jdGlvbiBub2RlUmFuZG9tKGNvdW50LCBvcHRpb25zKSB7XG4gIHZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKVxuICB2YXIgYnVmID0gY3J5cHRvLnJhbmRvbUJ5dGVzKGNvdW50KVxuXG4gIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIFtdLnNsaWNlLmNhbGwoYnVmKVxuICAgIGNhc2UgJ0J1ZmZlcic6XG4gICAgICByZXR1cm4gYnVmXG4gICAgY2FzZSAnVWludDhBcnJheSc6XG4gICAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoY291bnQpXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsgYXJyW2ldID0gYnVmLnJlYWRVSW50OChpKSB9XG4gICAgICByZXR1cm4gYXJyXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihvcHRpb25zLnR5cGUgKyBcIiBpcyB1bnN1cHBvcnRlZC5cIilcbiAgfVxufVxuXG5mdW5jdGlvbiBicm93c2VyUmFuZG9tKGNvdW50LCBvcHRpb25zKSB7XG4gIHZhciBuYXRpdmVBcnIgPSBuZXcgVWludDhBcnJheShjb3VudClcbiAgdmFyIGNyeXB0byA9IHdpbmRvdy5jcnlwdG8gfHwgd2luZG93Lm1zQ3J5cHRvXG4gIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmF0aXZlQXJyKVxuXG4gIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIFtdLnNsaWNlLmNhbGwobmF0aXZlQXJyKVxuICAgIGNhc2UgJ0J1ZmZlcic6XG4gICAgICB0cnkgeyB2YXIgYiA9IG5ldyBCdWZmZXIoMSkgfSBjYXRjaChlKSB7IHRocm93IG5ldyBFcnJvcignQnVmZmVyIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBlbnZpcm9ubWVudC4gVXNlIE5vZGUuanMgb3IgQnJvd3NlcmlmeSBmb3IgYnJvd3NlciBzdXBwb3J0LicpfVxuICAgICAgcmV0dXJuIG5ldyBCdWZmZXIobmF0aXZlQXJyKVxuICAgIGNhc2UgJ1VpbnQ4QXJyYXknOlxuICAgICAgcmV0dXJuIG5hdGl2ZUFyclxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3Iob3B0aW9ucy50eXBlICsgXCIgaXMgdW5zdXBwb3J0ZWQuXCIpXG4gIH1cbn1cblxuc2VjdXJlUmFuZG9tLnJhbmRvbUFycmF5ID0gZnVuY3Rpb24oYnl0ZUNvdW50KSB7XG4gIHJldHVybiBzZWN1cmVSYW5kb20oYnl0ZUNvdW50LCB7dHlwZTogJ0FycmF5J30pXG59XG5cbnNlY3VyZVJhbmRvbS5yYW5kb21VaW50OEFycmF5ID0gZnVuY3Rpb24oYnl0ZUNvdW50KSB7XG4gIHJldHVybiBzZWN1cmVSYW5kb20oYnl0ZUNvdW50LCB7dHlwZTogJ1VpbnQ4QXJyYXknfSlcbn1cblxuc2VjdXJlUmFuZG9tLnJhbmRvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ5dGVDb3VudCkge1xuICByZXR1cm4gc2VjdXJlUmFuZG9tKGJ5dGVDb3VudCwge3R5cGU6ICdCdWZmZXInfSlcbn1cblxuXG59KHRoaXMpO1xuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlclxuXG4vLyBwcm90b3R5cGUgY2xhc3MgZm9yIGhhc2ggZnVuY3Rpb25zXG5mdW5jdGlvbiBIYXNoIChibG9ja1NpemUsIGZpbmFsU2l6ZSkge1xuICB0aGlzLl9ibG9jayA9IEJ1ZmZlci5hbGxvYyhibG9ja1NpemUpXG4gIHRoaXMuX2ZpbmFsU2l6ZSA9IGZpbmFsU2l6ZVxuICB0aGlzLl9ibG9ja1NpemUgPSBibG9ja1NpemVcbiAgdGhpcy5fbGVuID0gMFxufVxuXG5IYXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmMgPSBlbmMgfHwgJ3V0ZjgnXG4gICAgZGF0YSA9IEJ1ZmZlci5mcm9tKGRhdGEsIGVuYylcbiAgfVxuXG4gIHZhciBibG9jayA9IHRoaXMuX2Jsb2NrXG4gIHZhciBibG9ja1NpemUgPSB0aGlzLl9ibG9ja1NpemVcbiAgdmFyIGxlbmd0aCA9IGRhdGEubGVuZ3RoXG4gIHZhciBhY2N1bSA9IHRoaXMuX2xlblxuXG4gIGZvciAodmFyIG9mZnNldCA9IDA7IG9mZnNldCA8IGxlbmd0aDspIHtcbiAgICB2YXIgYXNzaWduZWQgPSBhY2N1bSAlIGJsb2NrU2l6ZVxuICAgIHZhciByZW1haW5kZXIgPSBNYXRoLm1pbihsZW5ndGggLSBvZmZzZXQsIGJsb2NrU2l6ZSAtIGFzc2lnbmVkKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZW1haW5kZXI7IGkrKykge1xuICAgICAgYmxvY2tbYXNzaWduZWQgKyBpXSA9IGRhdGFbb2Zmc2V0ICsgaV1cbiAgICB9XG5cbiAgICBhY2N1bSArPSByZW1haW5kZXJcbiAgICBvZmZzZXQgKz0gcmVtYWluZGVyXG5cbiAgICBpZiAoKGFjY3VtICUgYmxvY2tTaXplKSA9PT0gMCkge1xuICAgICAgdGhpcy5fdXBkYXRlKGJsb2NrKVxuICAgIH1cbiAgfVxuXG4gIHRoaXMuX2xlbiArPSBsZW5ndGhcbiAgcmV0dXJuIHRoaXNcbn1cblxuSGFzaC5wcm90b3R5cGUuZGlnZXN0ID0gZnVuY3Rpb24gKGVuYykge1xuICB2YXIgcmVtID0gdGhpcy5fbGVuICUgdGhpcy5fYmxvY2tTaXplXG5cbiAgdGhpcy5fYmxvY2tbcmVtXSA9IDB4ODBcblxuICAvLyB6ZXJvIChyZW0gKyAxKSB0cmFpbGluZyBiaXRzLCB3aGVyZSAocmVtICsgMSkgaXMgdGhlIHNtYWxsZXN0XG4gIC8vIG5vbi1uZWdhdGl2ZSBzb2x1dGlvbiB0byB0aGUgZXF1YXRpb24gKGxlbmd0aCArIDEgKyAocmVtICsgMSkpID09PSBmaW5hbFNpemUgbW9kIGJsb2NrU2l6ZVxuICB0aGlzLl9ibG9jay5maWxsKDAsIHJlbSArIDEpXG5cbiAgaWYgKHJlbSA+PSB0aGlzLl9maW5hbFNpemUpIHtcbiAgICB0aGlzLl91cGRhdGUodGhpcy5fYmxvY2spXG4gICAgdGhpcy5fYmxvY2suZmlsbCgwKVxuICB9XG5cbiAgdmFyIGJpdHMgPSB0aGlzLl9sZW4gKiA4XG5cbiAgLy8gdWludDMyXG4gIGlmIChiaXRzIDw9IDB4ZmZmZmZmZmYpIHtcbiAgICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkJFKGJpdHMsIHRoaXMuX2Jsb2NrU2l6ZSAtIDQpXG5cbiAgLy8gdWludDY0XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxvd0JpdHMgPSAoYml0cyAmIDB4ZmZmZmZmZmYpID4+PiAwXG4gICAgdmFyIGhpZ2hCaXRzID0gKGJpdHMgLSBsb3dCaXRzKSAvIDB4MTAwMDAwMDAwXG5cbiAgICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkJFKGhpZ2hCaXRzLCB0aGlzLl9ibG9ja1NpemUgLSA4KVxuICAgIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyQkUobG93Qml0cywgdGhpcy5fYmxvY2tTaXplIC0gNClcbiAgfVxuXG4gIHRoaXMuX3VwZGF0ZSh0aGlzLl9ibG9jaylcbiAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoKClcblxuICByZXR1cm4gZW5jID8gaGFzaC50b1N0cmluZyhlbmMpIDogaGFzaFxufVxuXG5IYXNoLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ191cGRhdGUgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzcycpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gSGFzaFxuIiwidmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFNIQSAoYWxnb3JpdGhtKSB7XG4gIGFsZ29yaXRobSA9IGFsZ29yaXRobS50b0xvd2VyQ2FzZSgpXG5cbiAgdmFyIEFsZ29yaXRobSA9IGV4cG9ydHNbYWxnb3JpdGhtXVxuICBpZiAoIUFsZ29yaXRobSkgdGhyb3cgbmV3IEVycm9yKGFsZ29yaXRobSArICcgaXMgbm90IHN1cHBvcnRlZCAod2UgYWNjZXB0IHB1bGwgcmVxdWVzdHMpJylcblxuICByZXR1cm4gbmV3IEFsZ29yaXRobSgpXG59XG5cbmV4cG9ydHMuc2hhID0gcmVxdWlyZSg5NylcbmV4cG9ydHMuc2hhMSA9IHJlcXVpcmUoOTgpXG5leHBvcnRzLnNoYTIyNCA9IHJlcXVpcmUoOTkpXG5leHBvcnRzLnNoYTI1NiA9IHJlcXVpcmUoMTAwKVxuZXhwb3J0cy5zaGEzODQgPSByZXF1aXJlKDEwMSlcbmV4cG9ydHMuc2hhNTEyID0gcmVxdWlyZSgxMDIpXG4iLCIvKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0wLCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIFBVQiAxODAtMVxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBkZXJpdmVkIGZyb20gc2hhMS5qcyBvZiB0aGUgc2FtZSByZXBvc2l0b3J5LlxuICogVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBTSEEtMCBhbmQgU0hBLTEgaXMganVzdCBhIGJpdHdpc2Ugcm90YXRlIGxlZnRcbiAqIG9wZXJhdGlvbiB3YXMgYWRkZWQuXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBIYXNoID0gcmVxdWlyZSg5NSlcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcblxudmFyIEsgPSBbXG4gIDB4NWE4Mjc5OTksIDB4NmVkOWViYTEsIDB4OGYxYmJjZGMgfCAwLCAweGNhNjJjMWQ2IHwgMFxuXVxuXG52YXIgVyA9IG5ldyBBcnJheSg4MClcblxuZnVuY3Rpb24gU2hhICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGEsIEhhc2gpXG5cblNoYS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4Njc0NTIzMDFcbiAgdGhpcy5fYiA9IDB4ZWZjZGFiODlcbiAgdGhpcy5fYyA9IDB4OThiYWRjZmVcbiAgdGhpcy5fZCA9IDB4MTAzMjU0NzZcbiAgdGhpcy5fZSA9IDB4YzNkMmUxZjBcblxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiByb3RsNSAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDUpIHwgKG51bSA+Pj4gMjcpXG59XG5cbmZ1bmN0aW9uIHJvdGwzMCAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDMwKSB8IChudW0gPj4+IDIpXG59XG5cbmZ1bmN0aW9uIGZ0IChzLCBiLCBjLCBkKSB7XG4gIGlmIChzID09PSAwKSByZXR1cm4gKGIgJiBjKSB8ICgofmIpICYgZClcbiAgaWYgKHMgPT09IDIpIHJldHVybiAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZClcbiAgcmV0dXJuIGIgXiBjIF4gZFxufVxuXG5TaGEucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYSA9IHRoaXMuX2EgfCAwXG4gIHZhciBiID0gdGhpcy5fYiB8IDBcbiAgdmFyIGMgPSB0aGlzLl9jIHwgMFxuICB2YXIgZCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlID0gdGhpcy5fZSB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIFdbaV0gPSBNLnJlYWRJbnQzMkJFKGkgKiA0KVxuICBmb3IgKDsgaSA8IDgwOyArK2kpIFdbaV0gPSBXW2kgLSAzXSBeIFdbaSAtIDhdIF4gV1tpIC0gMTRdIF4gV1tpIC0gMTZdXG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCA4MDsgKytqKSB7XG4gICAgdmFyIHMgPSB+fihqIC8gMjApXG4gICAgdmFyIHQgPSAocm90bDUoYSkgKyBmdChzLCBiLCBjLCBkKSArIGUgKyBXW2pdICsgS1tzXSkgfCAwXG5cbiAgICBlID0gZFxuICAgIGQgPSBjXG4gICAgYyA9IHJvdGwzMChiKVxuICAgIGIgPSBhXG4gICAgYSA9IHRcbiAgfVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbn1cblxuU2hhLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMjApXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSB8IDAsIDApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2IgfCAwLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jIHwgMCwgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCB8IDAsIDEyKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9lIHwgMCwgMTYpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGFcbiIsIi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTEsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBWZXJzaW9uIDIuMWEgQ29weXJpZ2h0IFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDIuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBkZXRhaWxzLlxuICovXG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoNjUpXG52YXIgSGFzaCA9IHJlcXVpcmUoOTUpXG52YXIgQnVmZmVyID0gcmVxdWlyZSg5MykuQnVmZmVyXG5cbnZhciBLID0gW1xuICAweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjIHwgMCwgMHhjYTYyYzFkNiB8IDBcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoODApXG5cbmZ1bmN0aW9uIFNoYTEgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYTEsIEhhc2gpXG5cblNoYTEucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDY3NDUyMzAxXG4gIHRoaXMuX2IgPSAweGVmY2RhYjg5XG4gIHRoaXMuX2MgPSAweDk4YmFkY2ZlXG4gIHRoaXMuX2QgPSAweDEwMzI1NDc2XG4gIHRoaXMuX2UgPSAweGMzZDJlMWYwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gcm90bDEgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCAxKSB8IChudW0gPj4+IDMxKVxufVxuXG5mdW5jdGlvbiByb3RsNSAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDUpIHwgKG51bSA+Pj4gMjcpXG59XG5cbmZ1bmN0aW9uIHJvdGwzMCAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDMwKSB8IChudW0gPj4+IDIpXG59XG5cbmZ1bmN0aW9uIGZ0IChzLCBiLCBjLCBkKSB7XG4gIGlmIChzID09PSAwKSByZXR1cm4gKGIgJiBjKSB8ICgofmIpICYgZClcbiAgaWYgKHMgPT09IDIpIHJldHVybiAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZClcbiAgcmV0dXJuIGIgXiBjIF4gZFxufVxuXG5TaGExLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hIHwgMFxuICB2YXIgYiA9IHRoaXMuX2IgfCAwXG4gIHZhciBjID0gdGhpcy5fYyB8IDBcbiAgdmFyIGQgPSB0aGlzLl9kIHwgMFxuICB2YXIgZSA9IHRoaXMuX2UgfCAwXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgKytpKSBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgZm9yICg7IGkgPCA4MDsgKytpKSBXW2ldID0gcm90bDEoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSlcblxuICBmb3IgKHZhciBqID0gMDsgaiA8IDgwOyArK2opIHtcbiAgICB2YXIgcyA9IH5+KGogLyAyMClcbiAgICB2YXIgdCA9IChyb3RsNShhKSArIGZ0KHMsIGIsIGMsIGQpICsgZSArIFdbal0gKyBLW3NdKSB8IDBcblxuICAgIGUgPSBkXG4gICAgZCA9IGNcbiAgICBjID0gcm90bDMwKGIpXG4gICAgYiA9IGFcbiAgICBhID0gdFxuICB9XG5cbiAgdGhpcy5fYSA9IChhICsgdGhpcy5fYSkgfCAwXG4gIHRoaXMuX2IgPSAoYiArIHRoaXMuX2IpIHwgMFxuICB0aGlzLl9jID0gKGMgKyB0aGlzLl9jKSB8IDBcbiAgdGhpcy5fZCA9IChkICsgdGhpcy5fZCkgfCAwXG4gIHRoaXMuX2UgPSAoZSArIHRoaXMuX2UpIHwgMFxufVxuXG5TaGExLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMjApXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSB8IDAsIDApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2IgfCAwLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jIHwgMCwgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCB8IDAsIDEyKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9lIHwgMCwgMTYpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGExXG4iLCIvKipcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMjU2LCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIDE4MC0yXG4gKiBWZXJzaW9uIDIuMi1iZXRhIENvcHlyaWdodCBBbmdlbCBNYXJpbiwgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwOS5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBTaGEyNTYgPSByZXF1aXJlKDEwMClcbnZhciBIYXNoID0gcmVxdWlyZSg5NSlcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcblxudmFyIFcgPSBuZXcgQXJyYXkoNjQpXG5cbmZ1bmN0aW9uIFNoYTIyNCAoKSB7XG4gIHRoaXMuaW5pdCgpXG5cbiAgdGhpcy5fdyA9IFcgLy8gbmV3IEFycmF5KDY0KVxuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYTIyNCwgU2hhMjU2KVxuXG5TaGEyMjQucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweGMxMDU5ZWQ4XG4gIHRoaXMuX2IgPSAweDM2N2NkNTA3XG4gIHRoaXMuX2MgPSAweDMwNzBkZDE3XG4gIHRoaXMuX2QgPSAweGY3MGU1OTM5XG4gIHRoaXMuX2UgPSAweGZmYzAwYjMxXG4gIHRoaXMuX2YgPSAweDY4NTgxNTExXG4gIHRoaXMuX2cgPSAweDY0Zjk4ZmE3XG4gIHRoaXMuX2ggPSAweGJlZmE0ZmE0XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuU2hhMjI0LnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMjgpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEyMjRcbiIsIi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKDY1KVxudmFyIEhhc2ggPSByZXF1aXJlKDk1KVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlclxuXG52YXIgSyA9IFtcbiAgMHg0MjhBMkY5OCwgMHg3MTM3NDQ5MSwgMHhCNUMwRkJDRiwgMHhFOUI1REJBNSxcbiAgMHgzOTU2QzI1QiwgMHg1OUYxMTFGMSwgMHg5MjNGODJBNCwgMHhBQjFDNUVENSxcbiAgMHhEODA3QUE5OCwgMHgxMjgzNUIwMSwgMHgyNDMxODVCRSwgMHg1NTBDN0RDMyxcbiAgMHg3MkJFNUQ3NCwgMHg4MERFQjFGRSwgMHg5QkRDMDZBNywgMHhDMTlCRjE3NCxcbiAgMHhFNDlCNjlDMSwgMHhFRkJFNDc4NiwgMHgwRkMxOURDNiwgMHgyNDBDQTFDQyxcbiAgMHgyREU5MkM2RiwgMHg0QTc0ODRBQSwgMHg1Q0IwQTlEQywgMHg3NkY5ODhEQSxcbiAgMHg5ODNFNTE1MiwgMHhBODMxQzY2RCwgMHhCMDAzMjdDOCwgMHhCRjU5N0ZDNyxcbiAgMHhDNkUwMEJGMywgMHhENUE3OTE0NywgMHgwNkNBNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN0I3MEE4NSwgMHgyRTFCMjEzOCwgMHg0RDJDNkRGQywgMHg1MzM4MEQxMyxcbiAgMHg2NTBBNzM1NCwgMHg3NjZBMEFCQiwgMHg4MUMyQzkyRSwgMHg5MjcyMkM4NSxcbiAgMHhBMkJGRThBMSwgMHhBODFBNjY0QiwgMHhDMjRCOEI3MCwgMHhDNzZDNTFBMyxcbiAgMHhEMTkyRTgxOSwgMHhENjk5MDYyNCwgMHhGNDBFMzU4NSwgMHgxMDZBQTA3MCxcbiAgMHgxOUE0QzExNiwgMHgxRTM3NkMwOCwgMHgyNzQ4Nzc0QywgMHgzNEIwQkNCNSxcbiAgMHgzOTFDMENCMywgMHg0RUQ4QUE0QSwgMHg1QjlDQ0E0RiwgMHg2ODJFNkZGMyxcbiAgMHg3NDhGODJFRSwgMHg3OEE1NjM2RiwgMHg4NEM4NzgxNCwgMHg4Q0M3MDIwOCxcbiAgMHg5MEJFRkZGQSwgMHhBNDUwNkNFQiwgMHhCRUY5QTNGNywgMHhDNjcxNzhGMlxuXVxuXG52YXIgVyA9IG5ldyBBcnJheSg2NClcblxuZnVuY3Rpb24gU2hhMjU2ICgpIHtcbiAgdGhpcy5pbml0KClcblxuICB0aGlzLl93ID0gVyAvLyBuZXcgQXJyYXkoNjQpXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhMjU2LCBIYXNoKVxuXG5TaGEyNTYucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDZhMDllNjY3XG4gIHRoaXMuX2IgPSAweGJiNjdhZTg1XG4gIHRoaXMuX2MgPSAweDNjNmVmMzcyXG4gIHRoaXMuX2QgPSAweGE1NGZmNTNhXG4gIHRoaXMuX2UgPSAweDUxMGU1MjdmXG4gIHRoaXMuX2YgPSAweDliMDU2ODhjXG4gIHRoaXMuX2cgPSAweDFmODNkOWFiXG4gIHRoaXMuX2ggPSAweDViZTBjZDE5XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gY2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIG1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gc2lnbWEwICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gMiB8IHggPDwgMzApIF4gKHggPj4+IDEzIHwgeCA8PCAxOSkgXiAoeCA+Pj4gMjIgfCB4IDw8IDEwKVxufVxuXG5mdW5jdGlvbiBzaWdtYTEgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiA2IHwgeCA8PCAyNikgXiAoeCA+Pj4gMTEgfCB4IDw8IDIxKSBeICh4ID4+PiAyNSB8IHggPDwgNylcbn1cblxuZnVuY3Rpb24gZ2FtbWEwICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gNyB8IHggPDwgMjUpIF4gKHggPj4+IDE4IHwgeCA8PCAxNCkgXiAoeCA+Pj4gMylcbn1cblxuZnVuY3Rpb24gZ2FtbWExICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gMTcgfCB4IDw8IDE1KSBeICh4ID4+PiAxOSB8IHggPDwgMTMpIF4gKHggPj4+IDEwKVxufVxuXG5TaGEyNTYucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYSA9IHRoaXMuX2EgfCAwXG4gIHZhciBiID0gdGhpcy5fYiB8IDBcbiAgdmFyIGMgPSB0aGlzLl9jIHwgMFxuICB2YXIgZCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlID0gdGhpcy5fZSB8IDBcbiAgdmFyIGYgPSB0aGlzLl9mIHwgMFxuICB2YXIgZyA9IHRoaXMuX2cgfCAwXG4gIHZhciBoID0gdGhpcy5faCB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIFdbaV0gPSBNLnJlYWRJbnQzMkJFKGkgKiA0KVxuICBmb3IgKDsgaSA8IDY0OyArK2kpIFdbaV0gPSAoZ2FtbWExKFdbaSAtIDJdKSArIFdbaSAtIDddICsgZ2FtbWEwKFdbaSAtIDE1XSkgKyBXW2kgLSAxNl0pIHwgMFxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgNjQ7ICsraikge1xuICAgIHZhciBUMSA9IChoICsgc2lnbWExKGUpICsgY2goZSwgZiwgZykgKyBLW2pdICsgV1tqXSkgfCAwXG4gICAgdmFyIFQyID0gKHNpZ21hMChhKSArIG1haihhLCBiLCBjKSkgfCAwXG5cbiAgICBoID0gZ1xuICAgIGcgPSBmXG4gICAgZiA9IGVcbiAgICBlID0gKGQgKyBUMSkgfCAwXG4gICAgZCA9IGNcbiAgICBjID0gYlxuICAgIGIgPSBhXG4gICAgYSA9IChUMSArIFQyKSB8IDBcbiAgfVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbiAgdGhpcy5fZiA9IChmICsgdGhpcy5fZikgfCAwXG4gIHRoaXMuX2cgPSAoZyArIHRoaXMuX2cpIHwgMFxuICB0aGlzLl9oID0gKGggKyB0aGlzLl9oKSB8IDBcbn1cblxuU2hhMjU2LnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMzIpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2gsIDI4KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMjU2XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKDY1KVxudmFyIFNIQTUxMiA9IHJlcXVpcmUoMTAyKVxudmFyIEhhc2ggPSByZXF1aXJlKDk1KVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlclxuXG52YXIgVyA9IG5ldyBBcnJheSgxNjApXG5cbmZ1bmN0aW9uIFNoYTM4NCAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDEyOCwgMTEyKVxufVxuXG5pbmhlcml0cyhTaGEzODQsIFNIQTUxMilcblxuU2hhMzg0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9haCA9IDB4Y2JiYjlkNWRcbiAgdGhpcy5fYmggPSAweDYyOWEyOTJhXG4gIHRoaXMuX2NoID0gMHg5MTU5MDE1YVxuICB0aGlzLl9kaCA9IDB4MTUyZmVjZDhcbiAgdGhpcy5fZWggPSAweDY3MzMyNjY3XG4gIHRoaXMuX2ZoID0gMHg4ZWI0NGE4N1xuICB0aGlzLl9naCA9IDB4ZGIwYzJlMGRcbiAgdGhpcy5faGggPSAweDQ3YjU0ODFkXG5cbiAgdGhpcy5fYWwgPSAweGMxMDU5ZWQ4XG4gIHRoaXMuX2JsID0gMHgzNjdjZDUwN1xuICB0aGlzLl9jbCA9IDB4MzA3MGRkMTdcbiAgdGhpcy5fZGwgPSAweGY3MGU1OTM5XG4gIHRoaXMuX2VsID0gMHhmZmMwMGIzMVxuICB0aGlzLl9mbCA9IDB4Njg1ODE1MTFcbiAgdGhpcy5fZ2wgPSAweDY0Zjk4ZmE3XG4gIHRoaXMuX2hsID0gMHhiZWZhNGZhNFxuXG4gIHJldHVybiB0aGlzXG59XG5cblNoYTM4NC5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDQ4KVxuXG4gIGZ1bmN0aW9uIHdyaXRlSW50NjRCRSAoaCwgbCwgb2Zmc2V0KSB7XG4gICAgSC53cml0ZUludDMyQkUoaCwgb2Zmc2V0KVxuICAgIEgud3JpdGVJbnQzMkJFKGwsIG9mZnNldCArIDQpXG4gIH1cblxuICB3cml0ZUludDY0QkUodGhpcy5fYWgsIHRoaXMuX2FsLCAwKVxuICB3cml0ZUludDY0QkUodGhpcy5fYmgsIHRoaXMuX2JsLCA4KVxuICB3cml0ZUludDY0QkUodGhpcy5fY2gsIHRoaXMuX2NsLCAxNilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2RoLCB0aGlzLl9kbCwgMjQpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9laCwgdGhpcy5fZWwsIDMyKVxuICB3cml0ZUludDY0QkUodGhpcy5fZmgsIHRoaXMuX2ZsLCA0MClcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTM4NFxuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSg2NSlcbnZhciBIYXNoID0gcmVxdWlyZSg5NSlcbnZhciBCdWZmZXIgPSByZXF1aXJlKDkzKS5CdWZmZXJcblxudmFyIEsgPSBbXG4gIDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIsIDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QsXG4gIDB4YjVjMGZiY2YsIDB4ZWM0ZDNiMmYsIDB4ZTliNWRiYTUsIDB4ODE4OWRiYmMsXG4gIDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgsIDB4NTlmMTExZjEsIDB4YjYwNWQwMTksXG4gIDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIsIDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgsXG4gIDB4ZDgwN2FhOTgsIDB4YTMwMzAyNDIsIDB4MTI4MzViMDEsIDB4NDU3MDZmYmUsXG4gIDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMsIDB4NTUwYzdkYzMsIDB4ZDVmZmI0ZTIsXG4gIDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYsIDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEsXG4gIDB4OWJkYzA2YTcsIDB4MjVjNzEyMzUsIDB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTQsXG4gIDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIsIDB4ZWZiZTQ3ODYsIDB4Mzg0ZjI1ZTMsXG4gIDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUsIDB4MjQwY2ExY2MsIDB4NzdhYzljNjUsXG4gIDB4MmRlOTJjNmYsIDB4NTkyYjAyNzUsIDB4NGE3NDg0YWEsIDB4NmVhNmU0ODMsXG4gIDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQsIDB4NzZmOTg4ZGEsIDB4ODMxMTUzYjUsXG4gIDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIsIDB4YTgzMWM2NmQsIDB4MmRiNDMyMTAsXG4gIDB4YjAwMzI3YzgsIDB4OThmYjIxM2YsIDB4YmY1OTdmYzcsIDB4YmVlZjBlZTQsXG4gIDB4YzZlMDBiZjMsIDB4M2RhODhmYzIsIDB4ZDVhNzkxNDcsIDB4OTMwYWE3MjUsXG4gIDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYsIDB4MTQyOTI5NjcsIDB4MGEwZTZlNzAsXG4gIDB4MjdiNzBhODUsIDB4NDZkMjJmZmMsIDB4MmUxYjIxMzgsIDB4NWMyNmM5MjYsXG4gIDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQsIDB4NTMzODBkMTMsIDB4OWQ5NWIzZGYsXG4gIDB4NjUwYTczNTQsIDB4OGJhZjYzZGUsIDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgsXG4gIDB4ODFjMmM5MmUsIDB4NDdlZGFlZTYsIDB4OTI3MjJjODUsIDB4MTQ4MjM1M2IsXG4gIDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQsIDB4YTgxYTY2NGIsIDB4YmM0MjMwMDEsXG4gIDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEsIDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzAsXG4gIDB4ZDE5MmU4MTksIDB4ZDZlZjUyMTgsIDB4ZDY5OTA2MjQsIDB4NTU2NWE5MTAsXG4gIDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEsIDB4MTA2YWEwNzAsIDB4MzJiYmQxYjgsXG4gIDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgsIDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMsXG4gIDB4Mjc0ODc3NGMsIDB4ZGY4ZWViOTksIDB4MzRiMGJjYjUsIDB4ZTE5YjQ4YTgsXG4gIDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMsIDB4NGVkOGFhNGEsIDB4ZTM0MThhY2IsXG4gIDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMsIDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMsXG4gIDB4NzQ4ZjgyZWUsIDB4NWRlZmIyZmMsIDB4NzhhNTYzNmYsIDB4NDMxNzJmNjAsXG4gIDB4ODRjODc4MTQsIDB4YTFmMGFiNzIsIDB4OGNjNzAyMDgsIDB4MWE2NDM5ZWMsXG4gIDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgsIDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTksXG4gIDB4YmVmOWEzZjcsIDB4YjJjNjc5MTUsIDB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmIsXG4gIDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMsIDB4ZDE4NmI4YzcsIDB4MjFjMGMyMDcsXG4gIDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUsIDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgsXG4gIDB4MDZmMDY3YWEsIDB4NzIxNzZmYmEsIDB4MGE2MzdkYzUsIDB4YTJjODk4YTYsXG4gIDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUsIDB4MWI3MTBiMzUsIDB4MTMxYzQ3MWIsXG4gIDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQsIDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMsXG4gIDB4M2M5ZWJlMGEsIDB4MTVjOWJlYmMsIDB4NDMxZDY3YzQsIDB4OWMxMDBkNGMsXG4gIDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYsIDB4NTk3ZjI5OWMsIDB4ZmM2NTdlMmEsXG4gIDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMsIDB4NmM0NDE5OGMsIDB4NGE0NzU4MTdcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoMTYwKVxuXG5mdW5jdGlvbiBTaGE1MTIgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCAxMjgsIDExMilcbn1cblxuaW5oZXJpdHMoU2hhNTEyLCBIYXNoKVxuXG5TaGE1MTIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2FoID0gMHg2YTA5ZTY2N1xuICB0aGlzLl9iaCA9IDB4YmI2N2FlODVcbiAgdGhpcy5fY2ggPSAweDNjNmVmMzcyXG4gIHRoaXMuX2RoID0gMHhhNTRmZjUzYVxuICB0aGlzLl9laCA9IDB4NTEwZTUyN2ZcbiAgdGhpcy5fZmggPSAweDliMDU2ODhjXG4gIHRoaXMuX2doID0gMHgxZjgzZDlhYlxuICB0aGlzLl9oaCA9IDB4NWJlMGNkMTlcblxuICB0aGlzLl9hbCA9IDB4ZjNiY2M5MDhcbiAgdGhpcy5fYmwgPSAweDg0Y2FhNzNiXG4gIHRoaXMuX2NsID0gMHhmZTk0ZjgyYlxuICB0aGlzLl9kbCA9IDB4NWYxZDM2ZjFcbiAgdGhpcy5fZWwgPSAweGFkZTY4MmQxXG4gIHRoaXMuX2ZsID0gMHgyYjNlNmMxZlxuICB0aGlzLl9nbCA9IDB4ZmI0MWJkNmJcbiAgdGhpcy5faGwgPSAweDEzN2UyMTc5XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gQ2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIG1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gc2lnbWEwICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDI4IHwgeGwgPDwgNCkgXiAoeGwgPj4+IDIgfCB4IDw8IDMwKSBeICh4bCA+Pj4gNyB8IHggPDwgMjUpXG59XG5cbmZ1bmN0aW9uIHNpZ21hMSAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxNCB8IHhsIDw8IDE4KSBeICh4ID4+PiAxOCB8IHhsIDw8IDE0KSBeICh4bCA+Pj4gOSB8IHggPDwgMjMpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNylcbn1cblxuZnVuY3Rpb24gR2FtbWEwbCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNyB8IHhsIDw8IDI1KVxufVxuXG5mdW5jdGlvbiBHYW1tYTEgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMTkgfCB4bCA8PCAxMykgXiAoeGwgPj4+IDI5IHwgeCA8PCAzKSBeICh4ID4+PiA2KVxufVxuXG5mdW5jdGlvbiBHYW1tYTFsICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDE5IHwgeGwgPDwgMTMpIF4gKHhsID4+PiAyOSB8IHggPDwgMykgXiAoeCA+Pj4gNiB8IHhsIDw8IDI2KVxufVxuXG5mdW5jdGlvbiBnZXRDYXJyeSAoYSwgYikge1xuICByZXR1cm4gKGEgPj4+IDApIDwgKGIgPj4+IDApID8gMSA6IDBcbn1cblxuU2hhNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGFoID0gdGhpcy5fYWggfCAwXG4gIHZhciBiaCA9IHRoaXMuX2JoIHwgMFxuICB2YXIgY2ggPSB0aGlzLl9jaCB8IDBcbiAgdmFyIGRoID0gdGhpcy5fZGggfCAwXG4gIHZhciBlaCA9IHRoaXMuX2VoIHwgMFxuICB2YXIgZmggPSB0aGlzLl9maCB8IDBcbiAgdmFyIGdoID0gdGhpcy5fZ2ggfCAwXG4gIHZhciBoaCA9IHRoaXMuX2hoIHwgMFxuXG4gIHZhciBhbCA9IHRoaXMuX2FsIHwgMFxuICB2YXIgYmwgPSB0aGlzLl9ibCB8IDBcbiAgdmFyIGNsID0gdGhpcy5fY2wgfCAwXG4gIHZhciBkbCA9IHRoaXMuX2RsIHwgMFxuICB2YXIgZWwgPSB0aGlzLl9lbCB8IDBcbiAgdmFyIGZsID0gdGhpcy5fZmwgfCAwXG4gIHZhciBnbCA9IHRoaXMuX2dsIHwgMFxuICB2YXIgaGwgPSB0aGlzLl9obCB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpICs9IDIpIHtcbiAgICBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgICBXW2kgKyAxXSA9IE0ucmVhZEludDMyQkUoaSAqIDQgKyA0KVxuICB9XG4gIGZvciAoOyBpIDwgMTYwOyBpICs9IDIpIHtcbiAgICB2YXIgeGggPSBXW2kgLSAxNSAqIDJdXG4gICAgdmFyIHhsID0gV1tpIC0gMTUgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWEwID0gR2FtbWEwKHhoLCB4bClcbiAgICB2YXIgZ2FtbWEwbCA9IEdhbW1hMGwoeGwsIHhoKVxuXG4gICAgeGggPSBXW2kgLSAyICogMl1cbiAgICB4bCA9IFdbaSAtIDIgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWExID0gR2FtbWExKHhoLCB4bClcbiAgICB2YXIgZ2FtbWExbCA9IEdhbW1hMWwoeGwsIHhoKVxuXG4gICAgLy8gV1tpXSA9IGdhbW1hMCArIFdbaSAtIDddICsgZ2FtbWExICsgV1tpIC0gMTZdXG4gICAgdmFyIFdpN2ggPSBXW2kgLSA3ICogMl1cbiAgICB2YXIgV2k3bCA9IFdbaSAtIDcgKiAyICsgMV1cblxuICAgIHZhciBXaTE2aCA9IFdbaSAtIDE2ICogMl1cbiAgICB2YXIgV2kxNmwgPSBXW2kgLSAxNiAqIDIgKyAxXVxuXG4gICAgdmFyIFdpbCA9IChnYW1tYTBsICsgV2k3bCkgfCAwXG4gICAgdmFyIFdpaCA9IChnYW1tYTAgKyBXaTdoICsgZ2V0Q2FycnkoV2lsLCBnYW1tYTBsKSkgfCAwXG4gICAgV2lsID0gKFdpbCArIGdhbW1hMWwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBnYW1tYTEgKyBnZXRDYXJyeShXaWwsIGdhbW1hMWwpKSB8IDBcbiAgICBXaWwgPSAoV2lsICsgV2kxNmwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBXaTE2aCArIGdldENhcnJ5KFdpbCwgV2kxNmwpKSB8IDBcblxuICAgIFdbaV0gPSBXaWhcbiAgICBXW2kgKyAxXSA9IFdpbFxuICB9XG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCAxNjA7IGogKz0gMikge1xuICAgIFdpaCA9IFdbal1cbiAgICBXaWwgPSBXW2ogKyAxXVxuXG4gICAgdmFyIG1hamggPSBtYWooYWgsIGJoLCBjaClcbiAgICB2YXIgbWFqbCA9IG1haihhbCwgYmwsIGNsKVxuXG4gICAgdmFyIHNpZ21hMGggPSBzaWdtYTAoYWgsIGFsKVxuICAgIHZhciBzaWdtYTBsID0gc2lnbWEwKGFsLCBhaClcbiAgICB2YXIgc2lnbWExaCA9IHNpZ21hMShlaCwgZWwpXG4gICAgdmFyIHNpZ21hMWwgPSBzaWdtYTEoZWwsIGVoKVxuXG4gICAgLy8gdDEgPSBoICsgc2lnbWExICsgY2ggKyBLW2pdICsgV1tqXVxuICAgIHZhciBLaWggPSBLW2pdXG4gICAgdmFyIEtpbCA9IEtbaiArIDFdXG5cbiAgICB2YXIgY2hoID0gQ2goZWgsIGZoLCBnaClcbiAgICB2YXIgY2hsID0gQ2goZWwsIGZsLCBnbClcblxuICAgIHZhciB0MWwgPSAoaGwgKyBzaWdtYTFsKSB8IDBcbiAgICB2YXIgdDFoID0gKGhoICsgc2lnbWExaCArIGdldENhcnJ5KHQxbCwgaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgY2hsKSB8IDBcbiAgICB0MWggPSAodDFoICsgY2hoICsgZ2V0Q2FycnkodDFsLCBjaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgS2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgS2loICsgZ2V0Q2FycnkodDFsLCBLaWwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgV2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgV2loICsgZ2V0Q2FycnkodDFsLCBXaWwpKSB8IDBcblxuICAgIC8vIHQyID0gc2lnbWEwICsgbWFqXG4gICAgdmFyIHQybCA9IChzaWdtYTBsICsgbWFqbCkgfCAwXG4gICAgdmFyIHQyaCA9IChzaWdtYTBoICsgbWFqaCArIGdldENhcnJ5KHQybCwgc2lnbWEwbCkpIHwgMFxuXG4gICAgaGggPSBnaFxuICAgIGhsID0gZ2xcbiAgICBnaCA9IGZoXG4gICAgZ2wgPSBmbFxuICAgIGZoID0gZWhcbiAgICBmbCA9IGVsXG4gICAgZWwgPSAoZGwgKyB0MWwpIHwgMFxuICAgIGVoID0gKGRoICsgdDFoICsgZ2V0Q2FycnkoZWwsIGRsKSkgfCAwXG4gICAgZGggPSBjaFxuICAgIGRsID0gY2xcbiAgICBjaCA9IGJoXG4gICAgY2wgPSBibFxuICAgIGJoID0gYWhcbiAgICBibCA9IGFsXG4gICAgYWwgPSAodDFsICsgdDJsKSB8IDBcbiAgICBhaCA9ICh0MWggKyB0MmggKyBnZXRDYXJyeShhbCwgdDFsKSkgfCAwXG4gIH1cblxuICB0aGlzLl9hbCA9ICh0aGlzLl9hbCArIGFsKSB8IDBcbiAgdGhpcy5fYmwgPSAodGhpcy5fYmwgKyBibCkgfCAwXG4gIHRoaXMuX2NsID0gKHRoaXMuX2NsICsgY2wpIHwgMFxuICB0aGlzLl9kbCA9ICh0aGlzLl9kbCArIGRsKSB8IDBcbiAgdGhpcy5fZWwgPSAodGhpcy5fZWwgKyBlbCkgfCAwXG4gIHRoaXMuX2ZsID0gKHRoaXMuX2ZsICsgZmwpIHwgMFxuICB0aGlzLl9nbCA9ICh0aGlzLl9nbCArIGdsKSB8IDBcbiAgdGhpcy5faGwgPSAodGhpcy5faGwgKyBobCkgfCAwXG5cbiAgdGhpcy5fYWggPSAodGhpcy5fYWggKyBhaCArIGdldENhcnJ5KHRoaXMuX2FsLCBhbCkpIHwgMFxuICB0aGlzLl9iaCA9ICh0aGlzLl9iaCArIGJoICsgZ2V0Q2FycnkodGhpcy5fYmwsIGJsKSkgfCAwXG4gIHRoaXMuX2NoID0gKHRoaXMuX2NoICsgY2ggKyBnZXRDYXJyeSh0aGlzLl9jbCwgY2wpKSB8IDBcbiAgdGhpcy5fZGggPSAodGhpcy5fZGggKyBkaCArIGdldENhcnJ5KHRoaXMuX2RsLCBkbCkpIHwgMFxuICB0aGlzLl9laCA9ICh0aGlzLl9laCArIGVoICsgZ2V0Q2FycnkodGhpcy5fZWwsIGVsKSkgfCAwXG4gIHRoaXMuX2ZoID0gKHRoaXMuX2ZoICsgZmggKyBnZXRDYXJyeSh0aGlzLl9mbCwgZmwpKSB8IDBcbiAgdGhpcy5fZ2ggPSAodGhpcy5fZ2ggKyBnaCArIGdldENhcnJ5KHRoaXMuX2dsLCBnbCkpIHwgMFxuICB0aGlzLl9oaCA9ICh0aGlzLl9oaCArIGhoICsgZ2V0Q2FycnkodGhpcy5faGwsIGhsKSkgfCAwXG59XG5cblNoYTUxMi5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDY0KVxuXG4gIGZ1bmN0aW9uIHdyaXRlSW50NjRCRSAoaCwgbCwgb2Zmc2V0KSB7XG4gICAgSC53cml0ZUludDMyQkUoaCwgb2Zmc2V0KVxuICAgIEgud3JpdGVJbnQzMkJFKGwsIG9mZnNldCArIDQpXG4gIH1cblxuICB3cml0ZUludDY0QkUodGhpcy5fYWgsIHRoaXMuX2FsLCAwKVxuICB3cml0ZUludDY0QkUodGhpcy5fYmgsIHRoaXMuX2JsLCA4KVxuICB3cml0ZUludDY0QkUodGhpcy5fY2gsIHRoaXMuX2NsLCAxNilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2RoLCB0aGlzLl9kbCwgMjQpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9laCwgdGhpcy5fZWwsIDMyKVxuICB3cml0ZUludDY0QkUodGhpcy5fZmgsIHRoaXMuX2ZsLCA0MClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2doLCB0aGlzLl9nbCwgNDgpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9oaCwgdGhpcy5faGwsIDU2KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhNTEyXG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBFRSA9IHJlcXVpcmUoNjIpLkV2ZW50RW1pdHRlcjtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoNjUpO1xuXG5pbmhlcml0cyhTdHJlYW0sIEVFKTtcblN0cmVhbS5SZWFkYWJsZSA9IHJlcXVpcmUoODkpO1xuU3RyZWFtLldyaXRhYmxlID0gcmVxdWlyZSg5MSk7XG5TdHJlYW0uRHVwbGV4ID0gcmVxdWlyZSg3OCk7XG5TdHJlYW0uVHJhbnNmb3JtID0gcmVxdWlyZSg5MCk7XG5TdHJlYW0uUGFzc1Rocm91Z2ggPSByZXF1aXJlKDg4KTtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC40LnhcblN0cmVhbS5TdHJlYW0gPSBTdHJlYW07XG5cblxuXG4vLyBvbGQtc3R5bGUgc3RyZWFtcy4gIE5vdGUgdGhhdCB0aGUgcGlwZSBtZXRob2QgKHRoZSBvbmx5IHJlbGV2YW50XG4vLyBwYXJ0IG9mIHRoaXMgY2xhc3MpIGlzIG92ZXJyaWRkZW4gaW4gdGhlIFJlYWRhYmxlIGNsYXNzLlxuXG5mdW5jdGlvbiBTdHJlYW0oKSB7XG4gIEVFLmNhbGwodGhpcyk7XG59XG5cblN0cmVhbS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKGRlc3QsIG9wdGlvbnMpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgaWYgKGRlc3Qud3JpdGFibGUpIHtcbiAgICAgIGlmIChmYWxzZSA9PT0gZGVzdC53cml0ZShjaHVuaykgJiYgc291cmNlLnBhdXNlKSB7XG4gICAgICAgIHNvdXJjZS5wYXVzZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZGF0YScsIG9uZGF0YSk7XG5cbiAgZnVuY3Rpb24gb25kcmFpbigpIHtcbiAgICBpZiAoc291cmNlLnJlYWRhYmxlICYmIHNvdXJjZS5yZXN1bWUpIHtcbiAgICAgIHNvdXJjZS5yZXN1bWUoKTtcbiAgICB9XG4gIH1cblxuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIC8vIElmIHRoZSAnZW5kJyBvcHRpb24gaXMgbm90IHN1cHBsaWVkLCBkZXN0LmVuZCgpIHdpbGwgYmUgY2FsbGVkIHdoZW5cbiAgLy8gc291cmNlIGdldHMgdGhlICdlbmQnIG9yICdjbG9zZScgZXZlbnRzLiAgT25seSBkZXN0LmVuZCgpIG9uY2UuXG4gIGlmICghZGVzdC5faXNTdGRpbyAmJiAoIW9wdGlvbnMgfHwgb3B0aW9ucy5lbmQgIT09IGZhbHNlKSkge1xuICAgIHNvdXJjZS5vbignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5vbignY2xvc2UnLCBvbmNsb3NlKTtcbiAgfVxuXG4gIHZhciBkaWRPbkVuZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGlmICh0eXBlb2YgZGVzdC5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSBkZXN0LmRlc3Ryb3koKTtcbiAgfVxuXG4gIC8vIGRvbid0IGxlYXZlIGRhbmdsaW5nIHBpcGVzIHdoZW4gdGhlcmUgYXJlIGVycm9ycy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGNsZWFudXAoKTtcbiAgICBpZiAoRUUubGlzdGVuZXJDb3VudCh0aGlzLCAnZXJyb3InKSA9PT0gMCkge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCBzdHJlYW0gZXJyb3IgaW4gcGlwZS5cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2Vycm9yJywgb25lcnJvcik7XG4gIGRlc3Qub24oJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gcmVtb3ZlIGFsbCB0aGUgZXZlbnQgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZC5cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcbiAgfVxuXG4gIHNvdXJjZS5vbignZW5kJywgY2xlYW51cCk7XG4gIHNvdXJjZS5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0Lm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3QuZW1pdCgncGlwZScsIHNvdXJjZSk7XG5cbiAgLy8gQWxsb3cgZm9yIHVuaXgtbGlrZSB1c2FnZTogQS5waXBlKEIpLnBpcGUoQylcbiAgcmV0dXJuIGRlc3Q7XG59O1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoOTMpLkJ1ZmZlcjtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgaXNFbmNvZGluZyA9IEJ1ZmZlci5pc0VuY29kaW5nIHx8IGZ1bmN0aW9uIChlbmNvZGluZykge1xuICBlbmNvZGluZyA9ICcnICsgZW5jb2Rpbmc7XG4gIHN3aXRjaCAoZW5jb2RpbmcgJiYgZW5jb2RpbmcudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6Y2FzZSAndXRmOCc6Y2FzZSAndXRmLTgnOmNhc2UgJ2FzY2lpJzpjYXNlICdiaW5hcnknOmNhc2UgJ2Jhc2U2NCc6Y2FzZSAndWNzMic6Y2FzZSAndWNzLTInOmNhc2UgJ3V0ZjE2bGUnOmNhc2UgJ3V0Zi0xNmxlJzpjYXNlICdyYXcnOlxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX25vcm1hbGl6ZUVuY29kaW5nKGVuYykge1xuICBpZiAoIWVuYykgcmV0dXJuICd1dGY4JztcbiAgdmFyIHJldHJpZWQ7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmMpIHtcbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gJ3V0ZjgnO1xuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuICd1dGYxNmxlJztcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gJ2xhdGluMSc7XG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGVuYztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChyZXRyaWVkKSByZXR1cm47IC8vIHVuZGVmaW5lZFxuICAgICAgICBlbmMgPSAoJycgKyBlbmMpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHJpZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxufTtcblxuLy8gRG8gbm90IGNhY2hlIGBCdWZmZXIuaXNFbmNvZGluZ2Agd2hlbiBjaGVja2luZyBlbmNvZGluZyBuYW1lcyBhcyBzb21lXG4vLyBtb2R1bGVzIG1vbmtleS1wYXRjaCBpdCB0byBzdXBwb3J0IGFkZGl0aW9uYWwgZW5jb2RpbmdzXG5mdW5jdGlvbiBub3JtYWxpemVFbmNvZGluZyhlbmMpIHtcbiAgdmFyIG5lbmMgPSBfbm9ybWFsaXplRW5jb2RpbmcoZW5jKTtcbiAgaWYgKHR5cGVvZiBuZW5jICE9PSAnc3RyaW5nJyAmJiAoQnVmZmVyLmlzRW5jb2RpbmcgPT09IGlzRW5jb2RpbmcgfHwgIWlzRW5jb2RpbmcoZW5jKSkpIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuYyk7XG4gIHJldHVybiBuZW5jIHx8IGVuYztcbn1cblxuLy8gU3RyaW5nRGVjb2RlciBwcm92aWRlcyBhbiBpbnRlcmZhY2UgZm9yIGVmZmljaWVudGx5IHNwbGl0dGluZyBhIHNlcmllcyBvZlxuLy8gYnVmZmVycyBpbnRvIGEgc2VyaWVzIG9mIEpTIHN0cmluZ3Mgd2l0aG91dCBicmVha2luZyBhcGFydCBtdWx0aS1ieXRlXG4vLyBjaGFyYWN0ZXJzLlxuZXhwb3J0cy5TdHJpbmdEZWNvZGVyID0gU3RyaW5nRGVjb2RlcjtcbmZ1bmN0aW9uIFN0cmluZ0RlY29kZXIoZW5jb2RpbmcpIHtcbiAgdGhpcy5lbmNvZGluZyA9IG5vcm1hbGl6ZUVuY29kaW5nKGVuY29kaW5nKTtcbiAgdmFyIG5iO1xuICBzd2l0Y2ggKHRoaXMuZW5jb2RpbmcpIHtcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIHRoaXMudGV4dCA9IHV0ZjE2VGV4dDtcbiAgICAgIHRoaXMuZW5kID0gdXRmMTZFbmQ7XG4gICAgICBuYiA9IDQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd1dGY4JzpcbiAgICAgIHRoaXMuZmlsbExhc3QgPSB1dGY4RmlsbExhc3Q7XG4gICAgICBuYiA9IDQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgdGhpcy50ZXh0ID0gYmFzZTY0VGV4dDtcbiAgICAgIHRoaXMuZW5kID0gYmFzZTY0RW5kO1xuICAgICAgbmIgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBzaW1wbGVXcml0ZTtcbiAgICAgIHRoaXMuZW5kID0gc2ltcGxlRW5kO1xuICAgICAgcmV0dXJuO1xuICB9XG4gIHRoaXMubGFzdE5lZWQgPSAwO1xuICB0aGlzLmxhc3RUb3RhbCA9IDA7XG4gIHRoaXMubGFzdENoYXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobmIpO1xufVxuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChidWYpIHtcbiAgaWYgKGJ1Zi5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgdmFyIHI7XG4gIHZhciBpO1xuICBpZiAodGhpcy5sYXN0TmVlZCkge1xuICAgIHIgPSB0aGlzLmZpbGxMYXN0KGJ1Zik7XG4gICAgaWYgKHIgPT09IHVuZGVmaW5lZCkgcmV0dXJuICcnO1xuICAgIGkgPSB0aGlzLmxhc3ROZWVkO1xuICAgIHRoaXMubGFzdE5lZWQgPSAwO1xuICB9IGVsc2Uge1xuICAgIGkgPSAwO1xuICB9XG4gIGlmIChpIDwgYnVmLmxlbmd0aCkgcmV0dXJuIHIgPyByICsgdGhpcy50ZXh0KGJ1ZiwgaSkgOiB0aGlzLnRleHQoYnVmLCBpKTtcbiAgcmV0dXJuIHIgfHwgJyc7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQgPSB1dGY4RW5kO1xuXG4vLyBSZXR1cm5zIG9ubHkgY29tcGxldGUgY2hhcmFjdGVycyBpbiBhIEJ1ZmZlclxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUudGV4dCA9IHV0ZjhUZXh0O1xuXG4vLyBBdHRlbXB0cyB0byBjb21wbGV0ZSBhIHBhcnRpYWwgbm9uLVVURi04IGNoYXJhY3RlciB1c2luZyBieXRlcyBmcm9tIGEgQnVmZmVyXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5maWxsTGFzdCA9IGZ1bmN0aW9uIChidWYpIHtcbiAgaWYgKHRoaXMubGFzdE5lZWQgPD0gYnVmLmxlbmd0aCkge1xuICAgIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZCwgMCwgdGhpcy5sYXN0TmVlZCk7XG4gICAgcmV0dXJuIHRoaXMubGFzdENoYXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgdGhpcy5sYXN0VG90YWwpO1xuICB9XG4gIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZCwgMCwgYnVmLmxlbmd0aCk7XG4gIHRoaXMubGFzdE5lZWQgLT0gYnVmLmxlbmd0aDtcbn07XG5cbi8vIENoZWNrcyB0aGUgdHlwZSBvZiBhIFVURi04IGJ5dGUsIHdoZXRoZXIgaXQncyBBU0NJSSwgYSBsZWFkaW5nIGJ5dGUsIG9yIGFcbi8vIGNvbnRpbnVhdGlvbiBieXRlLiBJZiBhbiBpbnZhbGlkIGJ5dGUgaXMgZGV0ZWN0ZWQsIC0yIGlzIHJldHVybmVkLlxuZnVuY3Rpb24gdXRmOENoZWNrQnl0ZShieXRlKSB7XG4gIGlmIChieXRlIDw9IDB4N0YpIHJldHVybiAwO2Vsc2UgaWYgKGJ5dGUgPj4gNSA9PT0gMHgwNikgcmV0dXJuIDI7ZWxzZSBpZiAoYnl0ZSA+PiA0ID09PSAweDBFKSByZXR1cm4gMztlbHNlIGlmIChieXRlID4+IDMgPT09IDB4MUUpIHJldHVybiA0O1xuICByZXR1cm4gYnl0ZSA+PiA2ID09PSAweDAyID8gLTEgOiAtMjtcbn1cblxuLy8gQ2hlY2tzIGF0IG1vc3QgMyBieXRlcyBhdCB0aGUgZW5kIG9mIGEgQnVmZmVyIGluIG9yZGVyIHRvIGRldGVjdCBhblxuLy8gaW5jb21wbGV0ZSBtdWx0aS1ieXRlIFVURi04IGNoYXJhY3Rlci4gVGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyAoMiwgMywgb3IgNClcbi8vIG5lZWRlZCB0byBjb21wbGV0ZSB0aGUgVVRGLTggY2hhcmFjdGVyIChpZiBhcHBsaWNhYmxlKSBhcmUgcmV0dXJuZWQuXG5mdW5jdGlvbiB1dGY4Q2hlY2tJbmNvbXBsZXRlKHNlbGYsIGJ1ZiwgaSkge1xuICB2YXIgaiA9IGJ1Zi5sZW5ndGggLSAxO1xuICBpZiAoaiA8IGkpIHJldHVybiAwO1xuICB2YXIgbmIgPSB1dGY4Q2hlY2tCeXRlKGJ1ZltqXSk7XG4gIGlmIChuYiA+PSAwKSB7XG4gICAgaWYgKG5iID4gMCkgc2VsZi5sYXN0TmVlZCA9IG5iIC0gMTtcbiAgICByZXR1cm4gbmI7XG4gIH1cbiAgaWYgKC0taiA8IGkgfHwgbmIgPT09IC0yKSByZXR1cm4gMDtcbiAgbmIgPSB1dGY4Q2hlY2tCeXRlKGJ1ZltqXSk7XG4gIGlmIChuYiA+PSAwKSB7XG4gICAgaWYgKG5iID4gMCkgc2VsZi5sYXN0TmVlZCA9IG5iIC0gMjtcbiAgICByZXR1cm4gbmI7XG4gIH1cbiAgaWYgKC0taiA8IGkgfHwgbmIgPT09IC0yKSByZXR1cm4gMDtcbiAgbmIgPSB1dGY4Q2hlY2tCeXRlKGJ1ZltqXSk7XG4gIGlmIChuYiA+PSAwKSB7XG4gICAgaWYgKG5iID4gMCkge1xuICAgICAgaWYgKG5iID09PSAyKSBuYiA9IDA7ZWxzZSBzZWxmLmxhc3ROZWVkID0gbmIgLSAzO1xuICAgIH1cbiAgICByZXR1cm4gbmI7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbi8vIFZhbGlkYXRlcyBhcyBtYW55IGNvbnRpbnVhdGlvbiBieXRlcyBmb3IgYSBtdWx0aS1ieXRlIFVURi04IGNoYXJhY3RlciBhc1xuLy8gbmVlZGVkIG9yIGFyZSBhdmFpbGFibGUuIElmIHdlIHNlZSBhIG5vbi1jb250aW51YXRpb24gYnl0ZSB3aGVyZSB3ZSBleHBlY3Rcbi8vIG9uZSwgd2UgXCJyZXBsYWNlXCIgdGhlIHZhbGlkYXRlZCBjb250aW51YXRpb24gYnl0ZXMgd2UndmUgc2VlbiBzbyBmYXIgd2l0aFxuLy8gYSBzaW5nbGUgVVRGLTggcmVwbGFjZW1lbnQgY2hhcmFjdGVyICgnXFx1ZmZmZCcpLCB0byBtYXRjaCB2OCdzIFVURi04IGRlY29kaW5nXG4vLyBiZWhhdmlvci4gVGhlIGNvbnRpbnVhdGlvbiBieXRlIGNoZWNrIGlzIGluY2x1ZGVkIHRocmVlIHRpbWVzIGluIHRoZSBjYXNlXG4vLyB3aGVyZSBhbGwgb2YgdGhlIGNvbnRpbnVhdGlvbiBieXRlcyBmb3IgYSBjaGFyYWN0ZXIgZXhpc3QgaW4gdGhlIHNhbWUgYnVmZmVyLlxuLy8gSXQgaXMgYWxzbyBkb25lIHRoaXMgd2F5IGFzIGEgc2xpZ2h0IHBlcmZvcm1hbmNlIGluY3JlYXNlIGluc3RlYWQgb2YgdXNpbmcgYVxuLy8gbG9vcC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0V4dHJhQnl0ZXMoc2VsZiwgYnVmLCBwKSB7XG4gIGlmICgoYnVmWzBdICYgMHhDMCkgIT09IDB4ODApIHtcbiAgICBzZWxmLmxhc3ROZWVkID0gMDtcbiAgICByZXR1cm4gJ1xcdWZmZmQnO1xuICB9XG4gIGlmIChzZWxmLmxhc3ROZWVkID4gMSAmJiBidWYubGVuZ3RoID4gMSkge1xuICAgIGlmICgoYnVmWzFdICYgMHhDMCkgIT09IDB4ODApIHtcbiAgICAgIHNlbGYubGFzdE5lZWQgPSAxO1xuICAgICAgcmV0dXJuICdcXHVmZmZkJztcbiAgICB9XG4gICAgaWYgKHNlbGYubGFzdE5lZWQgPiAyICYmIGJ1Zi5sZW5ndGggPiAyKSB7XG4gICAgICBpZiAoKGJ1ZlsyXSAmIDB4QzApICE9PSAweDgwKSB7XG4gICAgICAgIHNlbGYubGFzdE5lZWQgPSAyO1xuICAgICAgICByZXR1cm4gJ1xcdWZmZmQnO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vLyBBdHRlbXB0cyB0byBjb21wbGV0ZSBhIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyIHVzaW5nIGJ5dGVzIGZyb20gYSBCdWZmZXIuXG5mdW5jdGlvbiB1dGY4RmlsbExhc3QoYnVmKSB7XG4gIHZhciBwID0gdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkO1xuICB2YXIgciA9IHV0ZjhDaGVja0V4dHJhQnl0ZXModGhpcywgYnVmLCBwKTtcbiAgaWYgKHIgIT09IHVuZGVmaW5lZCkgcmV0dXJuIHI7XG4gIGlmICh0aGlzLmxhc3ROZWVkIDw9IGJ1Zi5sZW5ndGgpIHtcbiAgICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCBwLCAwLCB0aGlzLmxhc3ROZWVkKTtcbiAgICByZXR1cm4gdGhpcy5sYXN0Q2hhci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCB0aGlzLmxhc3RUb3RhbCk7XG4gIH1cbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgcCwgMCwgYnVmLmxlbmd0aCk7XG4gIHRoaXMubGFzdE5lZWQgLT0gYnVmLmxlbmd0aDtcbn1cblxuLy8gUmV0dXJucyBhbGwgY29tcGxldGUgVVRGLTggY2hhcmFjdGVycyBpbiBhIEJ1ZmZlci4gSWYgdGhlIEJ1ZmZlciBlbmRlZCBvbiBhXG4vLyBwYXJ0aWFsIGNoYXJhY3RlciwgdGhlIGNoYXJhY3RlcidzIGJ5dGVzIGFyZSBidWZmZXJlZCB1bnRpbCB0aGUgcmVxdWlyZWRcbi8vIG51bWJlciBvZiBieXRlcyBhcmUgYXZhaWxhYmxlLlxuZnVuY3Rpb24gdXRmOFRleHQoYnVmLCBpKSB7XG4gIHZhciB0b3RhbCA9IHV0ZjhDaGVja0luY29tcGxldGUodGhpcywgYnVmLCBpKTtcbiAgaWYgKCF0aGlzLmxhc3ROZWVkKSByZXR1cm4gYnVmLnRvU3RyaW5nKCd1dGY4JywgaSk7XG4gIHRoaXMubGFzdFRvdGFsID0gdG90YWw7XG4gIHZhciBlbmQgPSBidWYubGVuZ3RoIC0gKHRvdGFsIC0gdGhpcy5sYXN0TmVlZCk7XG4gIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIDAsIGVuZCk7XG4gIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjgnLCBpLCBlbmQpO1xufVxuXG4vLyBGb3IgVVRGLTgsIGEgcmVwbGFjZW1lbnQgY2hhcmFjdGVyIGlzIGFkZGVkIHdoZW4gZW5kaW5nIG9uIGEgcGFydGlhbFxuLy8gY2hhcmFjdGVyLlxuZnVuY3Rpb24gdXRmOEVuZChidWYpIHtcbiAgdmFyIHIgPSBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xuICBpZiAodGhpcy5sYXN0TmVlZCkgcmV0dXJuIHIgKyAnXFx1ZmZmZCc7XG4gIHJldHVybiByO1xufVxuXG4vLyBVVEYtMTZMRSB0eXBpY2FsbHkgbmVlZHMgdHdvIGJ5dGVzIHBlciBjaGFyYWN0ZXIsIGJ1dCBldmVuIGlmIHdlIGhhdmUgYW4gZXZlblxuLy8gbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZSwgd2UgbmVlZCB0byBjaGVjayBpZiB3ZSBlbmQgb24gYSBsZWFkaW5nL2hpZ2hcbi8vIHN1cnJvZ2F0ZS4gSW4gdGhhdCBjYXNlLCB3ZSBuZWVkIHRvIHdhaXQgZm9yIHRoZSBuZXh0IHR3byBieXRlcyBpbiBvcmRlciB0b1xuLy8gZGVjb2RlIHRoZSBsYXN0IGNoYXJhY3RlciBwcm9wZXJseS5cbmZ1bmN0aW9uIHV0ZjE2VGV4dChidWYsIGkpIHtcbiAgaWYgKChidWYubGVuZ3RoIC0gaSkgJSAyID09PSAwKSB7XG4gICAgdmFyIHIgPSBidWYudG9TdHJpbmcoJ3V0ZjE2bGUnLCBpKTtcbiAgICBpZiAocikge1xuICAgICAgdmFyIGMgPSByLmNoYXJDb2RlQXQoci5sZW5ndGggLSAxKTtcbiAgICAgIGlmIChjID49IDB4RDgwMCAmJiBjIDw9IDB4REJGRikge1xuICAgICAgICB0aGlzLmxhc3ROZWVkID0gMjtcbiAgICAgICAgdGhpcy5sYXN0VG90YWwgPSA0O1xuICAgICAgICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAyXTtcbiAgICAgICAgdGhpcy5sYXN0Q2hhclsxXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gICAgICAgIHJldHVybiByLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH1cbiAgdGhpcy5sYXN0TmVlZCA9IDE7XG4gIHRoaXMubGFzdFRvdGFsID0gMjtcbiAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjE2bGUnLCBpLCBidWYubGVuZ3RoIC0gMSk7XG59XG5cbi8vIEZvciBVVEYtMTZMRSB3ZSBkbyBub3QgZXhwbGljaXRseSBhcHBlbmQgc3BlY2lhbCByZXBsYWNlbWVudCBjaGFyYWN0ZXJzIGlmIHdlXG4vLyBlbmQgb24gYSBwYXJ0aWFsIGNoYXJhY3Rlciwgd2Ugc2ltcGx5IGxldCB2OCBoYW5kbGUgdGhhdC5cbmZ1bmN0aW9uIHV0ZjE2RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSB7XG4gICAgdmFyIGVuZCA9IHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZDtcbiAgICByZXR1cm4gciArIHRoaXMubGFzdENoYXIudG9TdHJpbmcoJ3V0ZjE2bGUnLCAwLCBlbmQpO1xuICB9XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBiYXNlNjRUZXh0KGJ1ZiwgaSkge1xuICB2YXIgbiA9IChidWYubGVuZ3RoIC0gaSkgJSAzO1xuICBpZiAobiA9PT0gMCkgcmV0dXJuIGJ1Zi50b1N0cmluZygnYmFzZTY0JywgaSk7XG4gIHRoaXMubGFzdE5lZWQgPSAzIC0gbjtcbiAgdGhpcy5sYXN0VG90YWwgPSAzO1xuICBpZiAobiA9PT0gMSkge1xuICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICB9IGVsc2Uge1xuICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDJdO1xuICAgIHRoaXMubGFzdENoYXJbMV0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICB9XG4gIHJldHVybiBidWYudG9TdHJpbmcoJ2Jhc2U2NCcsIGksIGJ1Zi5sZW5ndGggLSBuKTtcbn1cblxuZnVuY3Rpb24gYmFzZTY0RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSByZXR1cm4gciArIHRoaXMubGFzdENoYXIudG9TdHJpbmcoJ2Jhc2U2NCcsIDAsIDMgLSB0aGlzLmxhc3ROZWVkKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIFBhc3MgYnl0ZXMgb24gdGhyb3VnaCBmb3Igc2luZ2xlLWJ5dGUgZW5jb2RpbmdzIChlLmcuIGFzY2lpLCBsYXRpbjEsIGhleClcbmZ1bmN0aW9uIHNpbXBsZVdyaXRlKGJ1Zikge1xuICByZXR1cm4gYnVmLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiBzaW1wbGVFbmQoYnVmKSB7XG4gIHJldHVybiBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xufSIsInZhciBuZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MvYnJvd3Nlci5qcycpLm5leHRUaWNrO1xudmFyIGFwcGx5ID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGltbWVkaWF0ZUlkcyA9IHt9O1xudmFyIG5leHRJbW1lZGlhdGVJZCA9IDA7XG5cbi8vIERPTSBBUElzLCBmb3IgY29tcGxldGVuZXNzXG5cbmV4cG9ydHMuc2V0VGltZW91dCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRUaW1lb3V0LCB3aW5kb3csIGFyZ3VtZW50cyksIGNsZWFyVGltZW91dCk7XG59O1xuZXhwb3J0cy5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRJbnRlcnZhbCwgd2luZG93LCBhcmd1bWVudHMpLCBjbGVhckludGVydmFsKTtcbn07XG5leHBvcnRzLmNsZWFyVGltZW91dCA9XG5leHBvcnRzLmNsZWFySW50ZXJ2YWwgPSBmdW5jdGlvbih0aW1lb3V0KSB7IHRpbWVvdXQuY2xvc2UoKTsgfTtcblxuZnVuY3Rpb24gVGltZW91dChpZCwgY2xlYXJGbikge1xuICB0aGlzLl9pZCA9IGlkO1xuICB0aGlzLl9jbGVhckZuID0gY2xlYXJGbjtcbn1cblRpbWVvdXQucHJvdG90eXBlLnVucmVmID0gVGltZW91dC5wcm90b3R5cGUucmVmID0gZnVuY3Rpb24oKSB7fTtcblRpbWVvdXQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX2NsZWFyRm4uY2FsbCh3aW5kb3csIHRoaXMuX2lkKTtcbn07XG5cbi8vIERvZXMgbm90IHN0YXJ0IHRoZSB0aW1lLCBqdXN0IHNldHMgdXAgdGhlIG1lbWJlcnMgbmVlZGVkLlxuZXhwb3J0cy5lbnJvbGwgPSBmdW5jdGlvbihpdGVtLCBtc2Vjcykge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gbXNlY3M7XG59O1xuXG5leHBvcnRzLnVuZW5yb2xsID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gLTE7XG59O1xuXG5leHBvcnRzLl91bnJlZkFjdGl2ZSA9IGV4cG9ydHMuYWN0aXZlID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG5cbiAgdmFyIG1zZWNzID0gaXRlbS5faWRsZVRpbWVvdXQ7XG4gIGlmIChtc2VjcyA+PSAwKSB7XG4gICAgaXRlbS5faWRsZVRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgaWYgKGl0ZW0uX29uVGltZW91dClcbiAgICAgICAgaXRlbS5fb25UaW1lb3V0KCk7XG4gICAgfSwgbXNlY3MpO1xuICB9XG59O1xuXG4vLyBUaGF0J3Mgbm90IGhvdyBub2RlLmpzIGltcGxlbWVudHMgaXQgYnV0IHRoZSBleHBvc2VkIGFwaSBpcyB0aGUgc2FtZS5cbmV4cG9ydHMuc2V0SW1tZWRpYXRlID0gdHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gXCJmdW5jdGlvblwiID8gc2V0SW1tZWRpYXRlIDogZnVuY3Rpb24oZm4pIHtcbiAgdmFyIGlkID0gbmV4dEltbWVkaWF0ZUlkKys7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzLmxlbmd0aCA8IDIgPyBmYWxzZSA6IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblxuICBpbW1lZGlhdGVJZHNbaWRdID0gdHJ1ZTtcblxuICBuZXh0VGljayhmdW5jdGlvbiBvbk5leHRUaWNrKCkge1xuICAgIGlmIChpbW1lZGlhdGVJZHNbaWRdKSB7XG4gICAgICAvLyBmbi5jYWxsKCkgaXMgZmFzdGVyIHNvIHdlIG9wdGltaXplIGZvciB0aGUgY29tbW9uIHVzZS1jYXNlXG4gICAgICAvLyBAc2VlIGh0dHA6Ly9qc3BlcmYuY29tL2NhbGwtYXBwbHktc2VndVxuICAgICAgaWYgKGFyZ3MpIHtcbiAgICAgICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmbi5jYWxsKG51bGwpO1xuICAgICAgfVxuICAgICAgLy8gUHJldmVudCBpZHMgZnJvbSBsZWFraW5nXG4gICAgICBleHBvcnRzLmNsZWFySW1tZWRpYXRlKGlkKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBpZDtcbn07XG5cbmV4cG9ydHMuY2xlYXJJbW1lZGlhdGUgPSB0eXBlb2YgY2xlYXJJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIiA/IGNsZWFySW1tZWRpYXRlIDogZnVuY3Rpb24oaWQpIHtcbiAgZGVsZXRlIGltbWVkaWF0ZUlkc1tpZF07XG59OyIsIlxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlcHJlY2F0ZTtcblxuLyoqXG4gKiBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICogUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLm5vRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRocm93RGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgdGhyb3cgYW4gRXJyb3Igd2hlbiBpbnZva2VkLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudHJhY2VEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCBpbnZva2UgYGNvbnNvbGUudHJhY2UoKWAgaW5zdGVhZCBvZiBgY29uc29sZS5lcnJvcigpYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBkZXByZWNhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgLSB0aGUgc3RyaW5nIHRvIHByaW50IHRvIHRoZSBjb25zb2xlIHdoZW4gYGZuYCBpcyBpbnZva2VkXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IGEgbmV3IFwiZGVwcmVjYXRlZFwiIHZlcnNpb24gb2YgYGZuYFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZXByZWNhdGUgKGZuLCBtc2cpIHtcbiAgaWYgKGNvbmZpZygnbm9EZXByZWNhdGlvbicpKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAoY29uZmlnKCd0aHJvd0RlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKGNvbmZpZygndHJhY2VEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgYGxvY2FsU3RvcmFnZWAgZm9yIGJvb2xlYW4gdmFsdWVzIGZvciB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGNvbmZpZyAobmFtZSkge1xuICAvLyBhY2Nlc3NpbmcgZ2xvYmFsLmxvY2FsU3RvcmFnZSBjYW4gdHJpZ2dlciBhIERPTUV4Y2VwdGlvbiBpbiBzYW5kYm94ZWQgaWZyYW1lc1xuICB0cnkge1xuICAgIGlmICghZ2xvYmFsLmxvY2FsU3RvcmFnZSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB2YWwgPSBnbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO1xuICBpZiAobnVsbCA9PSB2YWwpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJztcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNCdWZmZXIoYXJnKSB7XG4gIHJldHVybiBhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ29iamVjdCdcbiAgICAmJiB0eXBlb2YgYXJnLmNvcHkgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLmZpbGwgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLnJlYWRVSW50OCA9PT0gJ2Z1bmN0aW9uJztcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uKGYpIHtcbiAgaWYgKCFpc1N0cmluZyhmKSkge1xuICAgIHZhciBvYmplY3RzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9iamVjdHMucHVzaChpbnNwZWN0KGFyZ3VtZW50c1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0cy5qb2luKCcgJyk7XG4gIH1cblxuICB2YXIgaSA9IDE7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG4gIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uKHgpIHtcbiAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcbiAgICBpZiAoaSA+PSBsZW4pIHJldHVybiB4O1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJXMnOiByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclZCc6IHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVqJzpcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgfSk7XG4gIGZvciAodmFyIHggPSBhcmdzW2ldOyBpIDwgbGVuOyB4ID0gYXJnc1srK2ldKSB7XG4gICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcbiAgICAgIHN0ciArPSAnICcgKyB4O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn07XG5cblxuLy8gTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbi8vIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4vLyBJZiAtLW5vLWRlcHJlY2F0aW9uIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuZXhwb3J0cy5kZXByZWNhdGUgPSBmdW5jdGlvbihmbiwgbXNnKSB7XG4gIC8vIEFsbG93IGZvciBkZXByZWNhdGluZyB0aGluZ3MgaW4gdGhlIHByb2Nlc3Mgb2Ygc3RhcnRpbmcgdXAuXG4gIGlmIChpc1VuZGVmaW5lZChnbG9iYWwucHJvY2VzcykpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZXhwb3J0cy5kZXByZWNhdGUoZm4sIG1zZykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3Mubm9EZXByZWNhdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKHByb2Nlc3MudGhyb3dEZXByZWNhdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy50cmFjZURlcHJlY2F0aW9uKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59O1xuXG5cbnZhciBkZWJ1Z3MgPSB7fTtcbnZhciBkZWJ1Z0Vudmlyb247XG5leHBvcnRzLmRlYnVnbG9nID0gZnVuY3Rpb24oc2V0KSB7XG4gIGlmIChpc1VuZGVmaW5lZChkZWJ1Z0Vudmlyb24pKVxuICAgIGRlYnVnRW52aXJvbiA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgfHwgJyc7XG4gIHNldCA9IHNldC50b1VwcGVyQ2FzZSgpO1xuICBpZiAoIWRlYnVnc1tzZXRdKSB7XG4gICAgaWYgKG5ldyBSZWdFeHAoJ1xcXFxiJyArIHNldCArICdcXFxcYicsICdpJykudGVzdChkZWJ1Z0Vudmlyb24pKSB7XG4gICAgICB2YXIgcGlkID0gcHJvY2Vzcy5waWQ7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbXNnID0gZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignJXMgJWQ6ICVzJywgc2V0LCBwaWQsIG1zZyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge307XG4gICAgfVxuICB9XG4gIHJldHVybiBkZWJ1Z3Nbc2V0XTtcbn07XG5cblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIGFycmF5LmZvckVhY2goZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChrZXlzLmluZGV4T2YoJ21lc3NhZ2UnKSA+PSAwIHx8IGtleXMuaW5kZXhPZignZGVzY3JpcHRpb24nKSA+PSAwKSkge1xuICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgdmFyIG4gPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcbiAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmICghaGFzT3duUHJvcGVydHkodmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGN0eC5zZWVuLmluZGV4T2YoZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IG91dHB1dC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cbmZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXIpO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSByZXF1aXJlKCcuL3N1cHBvcnQvaXNCdWZmZXInKTtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZXhwb3J0cy5fZXh0ZW5kID0gZnVuY3Rpb24ob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZCk7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gIH1cbiAgcmV0dXJuIG9yaWdpbjtcbn07XG5cbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG4iXX0= +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJkaXN0L2Jyb3dzZXIuanMiLCJkaXN0L2NoYWluL3NyYy9BY2NvdW50TG9naW4uanMiLCJkaXN0L2NoYWluL3NyYy9DaGFpblR5cGVzLmpzIiwiZGlzdC9jaGFpbi9zcmMvT2JqZWN0SWQuanMiLCJkaXN0L2NoYWluL3NyYy9UcmFuc2FjdGlvbkJ1aWxkZXIuanMiLCJkaXN0L2NoYWluL3NyYy9zdGF0ZS5qcyIsImRpc3QvZWNjL2luZGV4LmpzIiwiZGlzdC9lY2Mvc3JjL0JyYWluS2V5LmpzIiwiZGlzdC9lY2Mvc3JjL0tleVV0aWxzLmpzIiwiZGlzdC9lY2Mvc3JjL1ByaXZhdGVLZXkuanMiLCJkaXN0L2VjYy9zcmMvUHVibGljS2V5LmpzIiwiZGlzdC9lY2Mvc3JjL2FkZHJlc3MuanMiLCJkaXN0L2VjYy9zcmMvYWVzLmpzIiwiZGlzdC9lY2Mvc3JjL2VjZHNhLmpzIiwiZGlzdC9lY2Mvc3JjL2Vjc2lnbmF0dXJlLmpzIiwiZGlzdC9lY2Mvc3JjL2VuZm9yY2VfdHlwZXMuanMiLCJkaXN0L2VjYy9zcmMvaGFzaC5qcyIsImRpc3QvZWNjL3NyYy9zaWduYXR1cmUuanMiLCJkaXN0L3NlcmlhbGl6ZXIvaW5kZXguanMiLCJkaXN0L3NlcmlhbGl6ZXIvc3JjL0Zhc3RQYXJzZXIuanMiLCJkaXN0L3NlcmlhbGl6ZXIvc3JjL1NlcmlhbGl6ZXJWYWxpZGF0aW9uLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9lcnJvcl93aXRoX2NhdXNlLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9vcGVyYXRpb25zLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9zZXJpYWxpemVyLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy90ZW1wbGF0ZS5qcyIsImRpc3Qvc2VyaWFsaXplci9zcmMvdHlwZXMuanMiLCJub2RlX21vZHVsZXMvYXNzZXJ0L2Fzc2VydC5qcyIsIm5vZGVfbW9kdWxlcy9iYXNlLXgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JpZ2kvbGliL2JpZ2kuanMiLCJub2RlX21vZHVsZXMvYmlnaS9saWIvY29udmVydC5qcyIsIm5vZGVfbW9kdWxlcy9iaWdpL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9iaWdpL3BhY2thZ2UuanNvbiIsIm5vZGVfbW9kdWxlcy9icm93c2VyLXJlc29sdmUvZW1wdHkuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JzNTgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnl0ZWJ1ZmZlci9kaXN0L2J5dGVidWZmZXIuanMiLCJub2RlX21vZHVsZXMvY2lwaGVyLWJhc2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzIiwibm9kZV9tb2R1bGVzL2NyZWF0ZS1oYXNoL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvbWQ1LmpzIiwibm9kZV9tb2R1bGVzL2NyZWF0ZS1obWFjL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhtYWMvbGVnYWN5LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9hZXMuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2NpcGhlci1jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9lbmMtYmFzZTY0LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9lbmMtaGV4LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9ldnBrZGYuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2htYWMuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL21kNS5qcyIsIm5vZGVfbW9kdWxlcy9jcnlwdG8tanMvc2hhMS5qcyIsIm5vZGVfbW9kdWxlcy9kZWVwLWVxdWFsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2RlZXAtZXF1YWwvbGliL2lzX2FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9kZWVwLWVxdWFsL2xpYi9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2VjdXJ2ZS9saWIvY3VydmUuanMiLCJub2RlX21vZHVsZXMvZWN1cnZlL2xpYi9jdXJ2ZXMuanNvbiIsIm5vZGVfbW9kdWxlcy9lY3VydmUvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2VjdXJ2ZS9saWIvbmFtZXMuanMiLCJub2RlX21vZHVsZXMvZWN1cnZlL2xpYi9wb2ludC5qcyIsIm5vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwibm9kZV9tb2R1bGVzL2hhc2gtYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2luaGVyaXRzL2luaGVyaXRzX2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvaXMtYnVmZmVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9uZy9kaXN0L2xvbmcuanMiLCJub2RlX21vZHVsZXMvbWQ1LmpzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcGVlcnBsYXlzanMtd3MvZGlzdC9zcmMvQXBpSW5zdGFuY2VzLmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0NoYWluQ29uZmlnLmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0NoYWluV2ViU29ja2V0LmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0Nvbm5lY3Rpb25NYW5hZ2VyLmpzIiwibm9kZV9tb2R1bGVzL3BlZXJwbGF5c2pzLXdzL2Rpc3Qvc3JjL0dyYXBoZW5lQXBpLmpzIiwibm9kZV9tb2R1bGVzL3Byb2Nlc3MtbmV4dGljay1hcmdzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LWJyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX2R1cGxleC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9CdWZmZXJMaXN0LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9kZXN0cm95LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0tYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLWJyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUtYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yaXBlbWQxNjAvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2FmZS1idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2VjdXJlLXJhbmRvbS9saWIvc2VjdXJlLXJhbmRvbS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvaGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2hhLmpzL3NoYS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhMS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhMjI0LmpzIiwibm9kZV9tb2R1bGVzL3NoYS5qcy9zaGEyNTYuanMiLCJub2RlX21vZHVsZXMvc2hhLmpzL3NoYTM4NC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhNTEyLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2xpYi9zdHJpbmdfZGVjb2Rlci5qcyIsIm5vZGVfbW9kdWxlcy90aW1lcnMtYnJvd3NlcmlmeS9tYWluLmpzIiwibm9kZV9tb2R1bGVzL3V0aWwtZGVwcmVjYXRlL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvdXRpbC9zdXBwb3J0L2lzQnVmZmVyQnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy91dGlsL3V0aWwuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlrQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDM09BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDblRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMxTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMvSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNwc0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDLy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMWVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3IrQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM3dkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbHFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdk9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMTJCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2dkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5U0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6ckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hMQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMS9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDck5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekVBO0FBQ0E7O0FDREE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7O0FDREE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25LQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3ZTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIlwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBQcml2YXRlS2V5OiByZXF1aXJlKFwiLi9lY2Mvc3JjL1ByaXZhdGVLZXlcIiksXG4gICAgUHVibGljS2V5OiByZXF1aXJlKFwiLi9lY2Mvc3JjL1B1YmxpY0tleVwiKSxcbiAgICBTaWduYXR1cmU6IHJlcXVpcmUoXCIuL2VjYy9zcmMvc2lnbmF0dXJlXCIpLFxuICAgIGtleTogcmVxdWlyZShcIi4vZWNjL3NyYy9LZXlVdGlsc1wiKSxcbiAgICBUcmFuc2FjdGlvbkJ1aWxkZXI6IHJlcXVpcmUoXCIuL2NoYWluL3NyYy9UcmFuc2FjdGlvbkJ1aWxkZXJcIiksXG4gICAgTG9naW46IHJlcXVpcmUoXCIuL2NoYWluL3NyYy9BY2NvdW50TG9naW5cIiksXG4gICAgZ3JhcGhlbmVXUzogcmVxdWlyZShcInBlZXJwbGF5c2pzLXdzXCIpXG59OyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoXCIuLi8uLi9lY2Mvc3JjL1ByaXZhdGVLZXlcIik7XG52YXIga2V5ID0gcmVxdWlyZShcIi4uLy4uL2VjYy9zcmMvS2V5VXRpbHNcIik7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoXCIuL3N0YXRlXCIpLFxuICAgIGdldCA9IF9yZXF1aXJlLmdldCxcbiAgICBzZXQgPSBfcmVxdWlyZS5zZXQ7XG5cbnZhciBfa2V5Q2FjaGVQcml2ID0ge307XG52YXIgX2tleUNhY2hlUHViID0ge307XG5cbnZhciBBY2NvdW50TG9naW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQWNjb3VudExvZ2luKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWNjb3VudExvZ2luKTtcblxuICAgICAgICB2YXIgc3RhdGUgPSB7IGxvZ2dlZEluOiBmYWxzZSwgcm9sZXM6IFtcImFjdGl2ZVwiLCBcIm93bmVyXCIsIFwibWVtb1wiXSB9O1xuICAgICAgICB0aGlzLmdldCA9IGdldChzdGF0ZSk7XG4gICAgICAgIHRoaXMuc2V0ID0gc2V0KHN0YXRlKTtcblxuICAgICAgICB0aGlzLnN1YnMgPSB7fTtcbiAgICB9XG5cbiAgICBfY3JlYXRlQ2xhc3MoQWNjb3VudExvZ2luLCBbe1xuICAgICAgICBrZXk6IFwiYWRkU3Vic2NyaXB0aW9uXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRTdWJzY3JpcHRpb24oY2IpIHtcbiAgICAgICAgICAgIHRoaXMuc3Vic1tjYl0gPSBjYjtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcInNldFJvbGVzXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRSb2xlcyhyb2xlcykge1xuICAgICAgICAgICAgdGhpcy5zZXQoXCJyb2xlc1wiLCByb2xlcyk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogXCJnZW5lcmF0ZUtleXNcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdlbmVyYXRlS2V5cyhhY2NvdW50TmFtZSwgcGFzc3dvcmQsIHJvbGVzLCBwcmVmaXgpIHtcbiAgICAgICAgICAgIHZhciBzdGFydCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICAgICAgaWYgKCFhY2NvdW50TmFtZSB8fCAhcGFzc3dvcmQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBY2NvdW50IG5hbWUgb3IgcGFzc3dvcmQgcmVxdWlyZWRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocGFzc3dvcmQubGVuZ3RoIDwgMTIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXNzd29yZCBtdXN0IGhhdmUgYXQgbGVhc3QgMTIgY2hhcmFjdGVyc1wiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHByaXZLZXlzID0ge307XG4gICAgICAgICAgICB2YXIgcHViS2V5cyA9IHt9O1xuXG4gICAgICAgICAgICAocm9sZXMgfHwgdGhpcy5nZXQoXCJyb2xlc1wiKSkuZm9yRWFjaChmdW5jdGlvbiAocm9sZSkge1xuICAgICAgICAgICAgICAgIHZhciBzZWVkID0gYWNjb3VudE5hbWUgKyByb2xlICsgcGFzc3dvcmQ7XG4gICAgICAgICAgICAgICAgdmFyIHBrZXkgPSBfa2V5Q2FjaGVQcml2W3NlZWRdID8gX2tleUNhY2hlUHJpdltzZWVkXSA6IFByaXZhdGVLZXkuZnJvbVNlZWQoa2V5Lm5vcm1hbGl6ZV9icmFpbktleShzZWVkKSk7XG4gICAgICAgICAgICAgICAgX2tleUNhY2hlUHJpdltzZWVkXSA9IHBrZXk7XG5cbiAgICAgICAgICAgICAgICBwcml2S2V5c1tyb2xlXSA9IHBrZXk7XG4gICAgICAgICAgICAgICAgcHViS2V5c1tyb2xlXSA9IF9rZXlDYWNoZVB1YltzZWVkXSA/IF9rZXlDYWNoZVB1YltzZWVkXSA6IHBrZXkudG9QdWJsaWNLZXkoKS50b1N0cmluZyhwcmVmaXgpO1xuXG4gICAgICAgICAgICAgICAgX2tleUNhY2hlUHViW3NlZWRdID0gcHViS2V5c1tyb2xlXTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4geyBwcml2S2V5czogcHJpdktleXMsIHB1YktleXM6IHB1YktleXMgfTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcImNoZWNrS2V5c1wiLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY2hlY2tLZXlzKF9yZWYpIHtcbiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgICAgIHZhciBhY2NvdW50TmFtZSA9IF9yZWYuYWNjb3VudE5hbWUsXG4gICAgICAgICAgICAgICAgcGFzc3dvcmQgPSBfcmVmLnBhc3N3b3JkLFxuICAgICAgICAgICAgICAgIGF1dGhzID0gX3JlZi5hdXRocztcblxuICAgICAgICAgICAgaWYgKCFhY2NvdW50TmFtZSB8fCAhcGFzc3dvcmQgfHwgIWF1dGhzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2hlY2tLZXlzOiBNaXNzaW5nIGlucHV0c1wiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBoYXNLZXkgPSBmYWxzZTtcblxuICAgICAgICAgICAgdmFyIF9sb29wID0gZnVuY3Rpb24gX2xvb3Aocm9sZSkge1xuICAgICAgICAgICAgICAgIHZhciBfZ2VuZXJhdGVLZXlzID0gX3RoaXMuZ2VuZXJhdGVLZXlzKGFjY291bnROYW1lLCBwYXNzd29yZCwgW3JvbGVdKSxcbiAgICAgICAgICAgICAgICAgICAgcHJpdktleXMgPSBfZ2VuZXJhdGVLZXlzLnByaXZLZXlzLFxuICAgICAgICAgICAgICAgICAgICBwdWJLZXlzID0gX2dlbmVyYXRlS2V5cy5wdWJLZXlzO1xuXG4gICAgICAgICAgICAgICAgYXV0aHNbcm9sZV0uZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXlbMF0gPT09IHB1YktleXNbcm9sZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc0tleSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXQocm9sZSwgeyBwcml2OiBwcml2S2V5c1tyb2xlXSwgcHViOiBwdWJLZXlzW3JvbGVdIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBmb3IgKHZhciByb2xlIGluIGF1dGhzKSB7XG4gICAgICAgICAgICAgICAgX2xvb3Aocm9sZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoaGFzS2V5KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXQoXCJuYW1lXCIsIGFjY291bnROYW1lKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5zZXQoXCJsb2dnZWRJblwiLCBoYXNLZXkpO1xuXG4gICAgICAgICAgICByZXR1cm4gaGFzS2V5O1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6IFwic2lnblRyYW5zYWN0aW9uXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaWduVHJhbnNhY3Rpb24odHIpIHtcbiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgICAgICB2YXIgbXlLZXlzID0ge307XG4gICAgICAgICAgICB2YXIgaGFzS2V5ID0gZmFsc2U7XG5cbiAgICAgICAgICAgIHRoaXMuZ2V0KFwicm9sZXNcIikuZm9yRWFjaChmdW5jdGlvbiAocm9sZSkge1xuICAgICAgICAgICAgICAgIHZhciBteUtleSA9IF90aGlzMi5nZXQocm9sZSk7XG4gICAgICAgICAgICAgICAgaWYgKG15S2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGhhc0tleSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiYWRkaW5nIHNpZ25lcjpcIiwgbXlLZXkucHViKTtcbiAgICAgICAgICAgICAgICAgICAgdHIuYWRkX3NpZ25lcihteUtleS5wcml2LCBteUtleS5wdWIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAoIWhhc0tleSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIllvdSBkbyBub3QgaGF2ZSBhbnkgcHJpdmF0ZSBrZXlzIHRvIHNpZ24gdGhpcyB0cmFuc2FjdGlvblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBBY2NvdW50TG9naW47XG59KCk7XG5cbnZhciBhY2NvdW50TG9naW4gPSBuZXcgQWNjb3VudExvZ2luKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gYWNjb3VudExvZ2luOyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgQ2hhaW5UeXBlcyA9IHt9O1xuXG5DaGFpblR5cGVzLnJlc2VydmVkX3NwYWNlcyA9IHtcbiAgcmVsYXRpdmVfcHJvdG9jb2xfaWRzOiAwLFxuICBwcm90b2NvbF9pZHM6IDEsXG4gIGltcGxlbWVudGF0aW9uX2lkczogMlxufTtcblxuQ2hhaW5UeXBlcy5vYmplY3RfdHlwZSA9IHtcbiAgXCJudWxsXCI6IDAsXG4gIGJhc2U6IDEsXG4gIGFjY291bnQ6IDIsXG4gIGFzc2V0OiAzLFxuICBmb3JjZV9zZXR0bGVtZW50OiA0LFxuICBjb21taXR0ZWVfbWVtYmVyOiA1LFxuICB3aXRuZXNzOiA2LFxuICBsaW1pdF9vcmRlcjogNyxcbiAgY2FsbF9vcmRlcjogOCxcbiAgY3VzdG9tOiA5LFxuICBwcm9wb3NhbDogMTAsXG4gIG9wZXJhdGlvbl9oaXN0b3J5OiAxMSxcbiAgd2l0aGRyYXdfcGVybWlzc2lvbjogMTIsXG4gIHZlc3RpbmdfYmFsYW5jZTogMTMsXG4gIHdvcmtlcjogMTQsXG4gIGJhbGFuY2U6IDE1LFxuICB0b3VybmFtZW50OiAxNixcbiAgdG91cm5hbWVudF9kZXRhaWxzOiAxNyxcbiAgbWF0Y2hfb2JqZWN0X3R5cGU6IDE4LFxuICBnYW1lOiAxOVxufTtcblxuQ2hhaW5UeXBlcy5pbXBsX29iamVjdF90eXBlID0ge1xuICBnbG9iYWxfcHJvcGVydHk6IDAsXG4gIGR5bmFtaWNfZ2xvYmFsX3Byb3BlcnR5OiAxLFxuICBpbmRleF9tZXRhOiAyLFxuICBhc3NldF9keW5hbWljX2RhdGE6IDMsXG4gIGFzc2V0X2JpdGFzc2V0X2RhdGE6IDQsXG4gIGFjY291bnRfYmFsYW5jZTogNSxcbiAgYWNjb3VudF9zdGF0aXN0aWNzOiA2LFxuICB0cmFuc2FjdGlvbjogNyxcbiAgYmxvY2tfc3VtbWFyeTogOCxcbiAgYWNjb3VudF90cmFuc2FjdGlvbl9oaXN0b3J5OiA5LFxuICBibGluZGVkX2JhbGFuY2U6IDEwLFxuICBjaGFpbl9wcm9wZXJ0eTogMTEsXG4gIHdpdG5lc3Nfc2NoZWR1bGU6IDEyLFxuICBidWRnZXRfcmVjb3JkOiAxMyxcbiAgc3BlY2lhbF9hdXRob3JpdHk6IDE0LFxuICBidXliYWNrOiAxNSxcbiAgZmJhX2FjY3VtdWxhdG9yOiAxNixcbiAgYXNzZXRfZGl2aWRlbmRfZGF0YTogMTcsXG4gIHBlbmRpbmdfZGl2aWRlbmRfcGF5b3V0X2JhbGFuY2VfZm9yX2hvbGRlcjogMTgsXG4gIGRpc3RyaWJ1dGVkX2RpdmlkZW5kX2JhbGFuY2VfZGF0YTogMTlcbn07XG5cbkNoYWluVHlwZXMudm90ZV90eXBlID0ge1xuICBjb21taXR0ZWU6IDAsXG4gIHdpdG5lc3M6IDEsXG4gIHdvcmtlcjogMlxufTtcblxuQ2hhaW5UeXBlcy5vcGVyYXRpb25zID0ge1xuICB0cmFuc2ZlcjogMCxcbiAgbGltaXRfb3JkZXJfY3JlYXRlOiAxLFxuICBsaW1pdF9vcmRlcl9jYW5jZWw6IDIsXG4gIGNhbGxfb3JkZXJfdXBkYXRlOiAzLFxuICBmaWxsX29yZGVyOiA0LFxuICBhY2NvdW50X2NyZWF0ZTogNSxcbiAgYWNjb3VudF91cGRhdGU6IDYsXG4gIGFjY291bnRfd2hpdGVsaXN0OiA3LFxuICBhY2NvdW50X3VwZ3JhZGU6IDgsXG4gIGFjY291bnRfdHJhbnNmZXI6IDksXG4gIGFzc2V0X2NyZWF0ZTogMTAsXG4gIGFzc2V0X3VwZGF0ZTogMTEsXG4gIGFzc2V0X3VwZGF0ZV9iaXRhc3NldDogMTIsXG4gIGFzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2VyczogMTMsXG4gIGFzc2V0X2lzc3VlOiAxNCxcbiAgYXNzZXRfcmVzZXJ2ZTogMTUsXG4gIGFzc2V0X2Z1bmRfZmVlX3Bvb2w6IDE2LFxuICBhc3NldF9zZXR0bGU6IDE3LFxuICBhc3NldF9nbG9iYWxfc2V0dGxlOiAxOCxcbiAgYXNzZXRfcHVibGlzaF9mZWVkOiAxOSxcbiAgd2l0bmVzc19jcmVhdGU6IDIwLFxuICB3aXRuZXNzX3VwZGF0ZTogMjEsXG4gIHByb3Bvc2FsX2NyZWF0ZTogMjIsXG4gIHByb3Bvc2FsX3VwZGF0ZTogMjMsXG4gIHByb3Bvc2FsX2RlbGV0ZTogMjQsXG4gIHdpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlOiAyNSxcbiAgd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGU6IDI2LFxuICB3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltOiAyNyxcbiAgd2l0aGRyYXdfcGVybWlzc2lvbl9kZWxldGU6IDI4LFxuICBjb21taXR0ZWVfbWVtYmVyX2NyZWF0ZTogMjksXG4gIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlOiAzMCxcbiAgY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnM6IDMxLFxuICB2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlOiAzMixcbiAgdmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3OiAzMyxcbiAgd29ya2VyX2NyZWF0ZTogMzQsXG4gIGN1c3RvbTogMzUsXG4gIGFzc2VydDogMzYsXG4gIGJhbGFuY2VfY2xhaW06IDM3LFxuICBvdmVycmlkZV90cmFuc2ZlcjogMzgsXG4gIHRyYW5zZmVyX3RvX2JsaW5kOiAzOSxcbiAgYmxpbmRfdHJhbnNmZXI6IDQwLFxuICB0cmFuc2Zlcl9mcm9tX2JsaW5kOiA0MSxcbiAgYXNzZXRfc2V0dGxlX2NhbmNlbDogNDIsXG4gIGFzc2V0X2NsYWltX2ZlZXM6IDQzLFxuICBmYmFfZGlzdHJpYnV0ZV9vcGVyYXRpb246IDQ0LFxuICB0b3VybmFtZW50X2NyZWF0ZTogNDUsXG4gIHRvdXJuYW1lbnRfam9pbjogNDYsXG4gIGdhbWVfbW92ZTogNDcsXG4gIGFzc2V0X3VwZGF0ZV9kaXZpZGVuZDogNDgsXG4gIGFzc2V0X2RpdmlkZW5kX2Rpc3RyaWJ1dGlvbjogNDlcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQ2hhaW5UeXBlczsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ2J5dGVidWZmZXInKSxcbiAgICBMb25nID0gX3JlcXVpcmUuTG9uZztcblxudmFyIHYgPSByZXF1aXJlKCcuLi8uLi9zZXJpYWxpemVyL3NyYy9TZXJpYWxpemVyVmFsaWRhdGlvbicpO1xuXG52YXIgREJfTUFYX0lOU1RBTkNFX0lEID0gTG9uZy5mcm9tTnVtYmVyKE1hdGgucG93KDIsIDQ4KSAtIDEpO1xuXG52YXIgT2JqZWN0SWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gT2JqZWN0SWQoc3BhY2UsIHR5cGUsIGluc3RhbmNlKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBPYmplY3RJZCk7XG5cbiAgICAgICAgdGhpcy5zcGFjZSA9IHNwYWNlO1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLmluc3RhbmNlID0gaW5zdGFuY2U7XG4gICAgICAgIHZhciBpbnN0YW5jZV9zdHJpbmcgPSB0aGlzLmluc3RhbmNlLnRvU3RyaW5nKCk7XG4gICAgICAgIHZhciBfT2JqZWN0SWQgPSB0aGlzLnNwYWNlICsgJy4nICsgdGhpcy50eXBlICsgJy4nICsgaW5zdGFuY2Vfc3RyaW5nO1xuICAgICAgICBpZiAoIXYuaXNfZGlnaXRzKGluc3RhbmNlX3N0cmluZykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyAoJ0ludmFsaWQgb2JqZWN0IGlkICcgKyBfT2JqZWN0SWQpKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfY3JlYXRlQ2xhc3MoT2JqZWN0SWQsIFt7XG4gICAgICAgIGtleTogJ3RvTG9uZycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiB0b0xvbmcoKSB7XG4gICAgICAgICAgICByZXR1cm4gTG9uZy5mcm9tTnVtYmVyKHRoaXMuc3BhY2UpLnNoaWZ0TGVmdCg1Nikub3IoTG9uZy5mcm9tTnVtYmVyKHRoaXMudHlwZSkuc2hpZnRMZWZ0KDQ4KS5vcih0aGlzLmluc3RhbmNlKSk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2FwcGVuZEJ5dGVCdWZmZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi53cml0ZVVpbnQ2NCh0aGlzLnRvTG9uZygpKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndG9TdHJpbmcnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zcGFjZSArICcuJyArIHRoaXMudHlwZSArICcuJyArIHRoaXMuaW5zdGFuY2UudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgIH1dLCBbe1xuICAgICAgICBrZXk6ICdmcm9tU3RyaW5nJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21TdHJpbmcodmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZS5zcGFjZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLnR5cGUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZS5pbnN0YW5jZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcGFyYW1zID0gdi5yZXF1aXJlX21hdGNoKC9eKFswLTldKylcXC4oWzAtOV0rKVxcLihbMC05XSspJC8sIHYucmVxdWlyZWQodmFsdWUsIFwiT2JqZWN0SWRcIiksIFwiT2JqZWN0SWRcIik7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE9iamVjdElkKHBhcnNlSW50KHBhcmFtc1sxXSksIHBhcnNlSW50KHBhcmFtc1syXSksIExvbmcuZnJvbVN0cmluZyhwYXJhbXNbM10pKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZnJvbUxvbmcnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUxvbmcobG9uZykge1xuICAgICAgICAgICAgdmFyIHNwYWNlID0gbG9uZy5zaGlmdFJpZ2h0KDU2KS50b0ludCgpO1xuICAgICAgICAgICAgdmFyIHR5cGUgPSBsb25nLnNoaWZ0UmlnaHQoNDgpLnRvSW50KCkgJiAweDAwZmY7XG4gICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBsb25nLmFuZChEQl9NQVhfSU5TVEFOQ0VfSUQpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RJZChzcGFjZSwgdHlwZSwgaW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdmcm9tQnl0ZUJ1ZmZlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0SWQuZnJvbUxvbmcoYi5yZWFkVWludDY0KCkpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIE9iamVjdElkO1xufSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdElkOyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX3NsaWNlZFRvQXJyYXkgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIHNsaWNlSXRlcmF0b3IoYXJyLCBpKSB7IHZhciBfYXJyID0gW107IHZhciBfbiA9IHRydWU7IHZhciBfZCA9IGZhbHNlOyB2YXIgX2UgPSB1bmRlZmluZWQ7IHRyeSB7IGZvciAodmFyIF9pID0gYXJyW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3M7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHsgX2Fyci5wdXNoKF9zLnZhbHVlKTsgaWYgKGkgJiYgX2Fyci5sZW5ndGggPT09IGkpIGJyZWFrOyB9IH0gY2F0Y2ggKGVycikgeyBfZCA9IHRydWU7IF9lID0gZXJyOyB9IGZpbmFsbHkgeyB0cnkgeyBpZiAoIV9uICYmIF9pW1wicmV0dXJuXCJdKSBfaVtcInJldHVyblwiXSgpOyB9IGZpbmFsbHkgeyBpZiAoX2QpIHRocm93IF9lOyB9IH0gcmV0dXJuIF9hcnI7IH0gcmV0dXJuIGZ1bmN0aW9uIChhcnIsIGkpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgeyByZXR1cm4gYXJyOyB9IGVsc2UgaWYgKFN5bWJvbC5pdGVyYXRvciBpbiBPYmplY3QoYXJyKSkgeyByZXR1cm4gc2xpY2VJdGVyYXRvcihhcnIsIGkpOyB9IGVsc2UgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZVwiKTsgfSB9OyB9KCk7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKFwiYXNzZXJ0XCIpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKFwiLi4vLi4vZWNjXCIpLFxuICAgIFNpZ25hdHVyZSA9IF9yZXF1aXJlLlNpZ25hdHVyZSxcbiAgICBQdWJsaWNLZXkgPSBfcmVxdWlyZS5QdWJsaWNLZXksXG4gICAgaGFzaCA9IF9yZXF1aXJlLmhhc2g7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKFwiLi4vLi4vc2VyaWFsaXplclwiKSxcbiAgICBvcHMgPSBfcmVxdWlyZTIub3BzO1xuXG52YXIgX3JlcXVpcmUzID0gcmVxdWlyZSgncGVlcnBsYXlzanMtd3MnKSxcbiAgICBBcGlzID0gX3JlcXVpcmUzLkFwaXMsXG4gICAgQ2hhaW5Db25maWcgPSBfcmVxdWlyZTMuQ2hhaW5Db25maWc7XG5cbnZhciBDaGFpblR5cGVzID0gcmVxdWlyZSgnLi9DaGFpblR5cGVzJyk7XG52YXIgaGVhZF9ibG9ja190aW1lX3N0cmluZztcblxudmFyIFRyYW5zYWN0aW9uQnVpbGRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBUcmFuc2FjdGlvbkJ1aWxkZXIoKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUcmFuc2FjdGlvbkJ1aWxkZXIpO1xuXG4gICAgICAgIHRoaXMucmVmX2Jsb2NrX251bSA9IDA7XG4gICAgICAgIHRoaXMucmVmX2Jsb2NrX3ByZWZpeCA9IDA7XG4gICAgICAgIHRoaXMuZXhwaXJhdGlvbiA9IDA7XG4gICAgICAgIHRoaXMub3BlcmF0aW9ucyA9IFtdO1xuICAgICAgICB0aGlzLnNpZ25hdHVyZXMgPSBbXTtcbiAgICAgICAgdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzID0gW107XG5cbiAgICAgICAgLy8gc2VtaS1wcml2YXRlIG1ldGhvZCBiaW5kaW5nc1xuICAgICAgICB0aGlzLl9icm9hZGNhc3QgPSBfYnJvYWRjYXN0LmJpbmQodGhpcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICAgIEBhcmcge3N0cmluZ30gbmFtZSAtIGxpa2UgXCJ0cmFuc2ZlclwiXG4gICAgICAgIEBhcmcge29iamVjdH0gb3BlcmF0aW9uIC0gSlNPTiBtYXRjaGNoaW5nIHRoZSBvcGVyYXRpb24ncyBmb3JtYXRcbiAgICAqL1xuXG5cbiAgICBfY3JlYXRlQ2xhc3MoVHJhbnNhY3Rpb25CdWlsZGVyLCBbe1xuICAgICAgICBrZXk6IFwiYWRkX3R5cGVfb3BlcmF0aW9uXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRfdHlwZV9vcGVyYXRpb24obmFtZSwgb3BlcmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmFkZF9vcGVyYXRpb24odGhpcy5nZXRfdHlwZV9vcGVyYXRpb24obmFtZSwgb3BlcmF0aW9uKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICAgIFRoaXMgZG9lcyBpdCBhbGw6IHNldCBmZWVzLCBmaW5hbGl6ZSwgc2lnbiwgYW5kIGJyb2FkY2FzdCAoaWYgd2FudGVkKS5cbiAgICAgICAgICAgICBAYXJnIHtDb25maWRlbnRpYWxXYWxsZXR9IGN3YWxsZXQgLSBtdXN0IGJlIHVubG9ja2VkLCB1c2VkIHRvIGdhdGhlciBzaWduaW5nIGtleXNcbiAgICAgICAgICAgICBAYXJnIHthcnJheTxzdHJpbmc+fSBbc2lnbmVyX3B1YmtleXMgPSBudWxsXSAtIE9wdGlvbmFsIFtcIkdQSEFiYzlEZWYwLi4uXCIsIC4uLl0uICBUaGVzZSBhcmUgYWRkaXRpb25hbCBzaWduaW5nIGtleXMuICBTb21lIGJhbGFuY2UgY2xhaW1zIHJlcXVpcmUgcHJvcHJpdGFyeSBhZGRyZXNzIGZvcm1hdHMsIHRoZSB3aXRuZXNzIG5vZGUgY2FuJ3QgdGVsbCB1cyB3aGljaCBvbmVzIGFyZSBuZWVkZWQgc28gdGhleSBtdXN0IGJlIHBhc3NlZCBpbi4gIElmIHRoZSB3aXRuZXNzIG5vZGUgY2FuIGZpZ3VyZSBvdXQgYSBzaWduaW5nIGtleSAobW9zdGx5IGFsbCBvdGhlciB0cmFuc2FjdGlvbnMpLCBpdCBzaG91bGQgbm90IGJlIHBhc3NlZCBpbiBoZXJlLlxuICAgICAgICAgICAgIEBhcmcge2Jvb2xlYW59IFticm9hZGNhc3QgPSBmYWxzZV1cbiAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcInByb2Nlc3NfdHJhbnNhY3Rpb25cIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHByb2Nlc3NfdHJhbnNhY3Rpb24oY3dhbGxldCkge1xuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICAgICAgdmFyIHNpZ25lcl9wdWJrZXlzID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBudWxsO1xuICAgICAgICAgICAgdmFyIGJyb2FkY2FzdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogZmFsc2U7XG5cblxuICAgICAgICAgICAgdmFyIHdhbGxldF9vYmplY3QgPSBjd2FsbGV0LndhbGxldC53YWxsZXRfb2JqZWN0O1xuICAgICAgICAgICAgaWYgKEFwaXMuaW5zdGFuY2UoKS5jaGFpbl9pZCAhPT0gd2FsbGV0X29iamVjdC5nZXQoXCJjaGFpbl9pZFwiKSkgcmV0dXJuIFByb21pc2UucmVqZWN0KFwiTWlzbWF0Y2hlZCBjaGFpbl9pZDsgZXhwZWN0aW5nIFwiICsgd2FsbGV0X29iamVjdC5nZXQoXCJjaGFpbl9pZFwiKSArIFwiLCBidXQgZ290IFwiICsgQXBpcy5pbnN0YW5jZSgpLmNoYWluX2lkKTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0X3JlcXVpcmVkX2ZlZXMoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2lnbmVyX3B1YmtleXNfYWRkZWQgPSB7fTtcbiAgICAgICAgICAgICAgICBpZiAoc2lnbmVyX3B1YmtleXMpIHtcblxuICAgICAgICAgICAgICAgICAgICAvLyBCYWxhbmNlIGNsYWltcyBhcmUgYnkgYWRkcmVzcywgb25seSB0aGUgcHJpdmF0ZVxuICAgICAgICAgICAgICAgICAgICAvLyBrZXkgaG9sZGVyIGNhbiBrbm93IGFib3V0IHRoZXNlIGFkZGl0aW9uYWxcbiAgICAgICAgICAgICAgICAgICAgLy8gcG90ZW50aWFsIGtleXMuXG4gICAgICAgICAgICAgICAgICAgIHZhciBwdWJrZXlzID0gY3dhbGxldC5nZXRQdWJrZXlzX2hhdmluZ19Qcml2YXRlS2V5KHNpZ25lcl9wdWJrZXlzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwdWJrZXlzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBzaWduaW5nIGtleVwiKTtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvciA9IHB1YmtleXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gKF9zdGVwID0gX2l0ZXJhdG9yLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHB1YmtleV9zdHJpbmcgPSBfc3RlcC52YWx1ZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcml2YXRlX2tleSA9IGN3YWxsZXQuZ2V0UHJpdmF0ZUtleShwdWJrZXlfc3RyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5hZGRfc2lnbmVyKHByaXZhdGVfa2V5LCBwdWJrZXlfc3RyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduZXJfcHVia2V5c19hZGRlZFtwdWJrZXlfc3RyaW5nXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IgPSBlcnI7XG4gICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiAmJiBfaXRlcmF0b3IucmV0dXJuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvci5yZXR1cm4oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMuZ2V0X3BvdGVudGlhbF9zaWduYXR1cmVzKCkudGhlbihmdW5jdGlvbiAoX3JlZikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcHVia2V5cyA9IF9yZWYucHVia2V5cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZHlzID0gX3JlZi5hZGR5cztcblxuICAgICAgICAgICAgICAgICAgICB2YXIgbXlfcHVia2V5cyA9IGN3YWxsZXQuZ2V0UHVia2V5c19oYXZpbmdfUHJpdmF0ZUtleShwdWJrZXlzLCBhZGR5cyk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy97Ly9UZXN0aW5nIG9ubHksIGRvbid0IHNlbmQgQWxsIHB1YmxpYyBrZXlzIVxuICAgICAgICAgICAgICAgICAgICAvLyAgICB2YXIgcHVia2V5c19hbGwgPSBQcml2YXRlS2V5U3RvcmUuZ2V0UHVia2V5cygpIC8vIEFsbCBwdWJsaWMga2V5c1xuICAgICAgICAgICAgICAgICAgICAvLyAgICB0aGlzLmdldF9yZXF1aXJlZF9zaWduYXR1cmVzKHB1YmtleXNfYWxsKS50aGVuKCByZXF1aXJlZF9wdWJrZXlfc3RyaW5ncyA9PlxuICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgY29uc29sZS5sb2coJ2dldF9yZXF1aXJlZF9zaWduYXR1cmVzIGFsbFxcdCcscmVxdWlyZWRfcHVia2V5X3N0cmluZ3Muc29ydCgpLCBwdWJrZXlzX2FsbCkpXG4gICAgICAgICAgICAgICAgICAgIC8vICAgIHRoaXMuZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMobXlfcHVia2V5cykudGhlbiggcmVxdWlyZWRfcHVia2V5X3N0cmluZ3MgPT5cbiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgIGNvbnNvbGUubG9nKCdnZXRfcmVxdWlyZWRfc2lnbmF0dXJlcyBub3JtYWxcXHQnLHJlcXVpcmVkX3B1YmtleV9zdHJpbmdzLnNvcnQoKSwgcHVia2V5cykpXG4gICAgICAgICAgICAgICAgICAgIC8vfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpcy5nZXRfcmVxdWlyZWRfc2lnbmF0dXJlcyhteV9wdWJrZXlzKS50aGVuKGZ1bmN0aW9uIChyZXF1aXJlZF9wdWJrZXlzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yMiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yMiA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IyID0gcmVxdWlyZWRfcHVia2V5c1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwMjsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMiA9IChfc3RlcDIgPSBfaXRlcmF0b3IyLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yID0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgX3B1YmtleV9zdHJpbmcgPSBfc3RlcDIudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNpZ25lcl9wdWJrZXlzX2FkZGVkW19wdWJrZXlfc3RyaW5nXSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcml2YXRlX2tleSA9IGN3YWxsZXQuZ2V0UHJpdmF0ZUtleShfcHVia2V5X3N0cmluZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcHJpdmF0ZV9rZXkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBub3QgaGFwcGVuLCBnZXRfcmVxdWlyZWRfc2lnbmF0dXJlcyB3aWxsIG9ubHlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJldHVybmVkIGtleXMgZnJvbSBteV9wdWJrZXlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIHNpZ25pbmcga2V5IGZvciBcIiArIF9wdWJrZXlfc3RyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuYWRkX3NpZ25lcihwcml2YXRlX2tleSwgX3B1YmtleV9zdHJpbmcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IyID0gZXJyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yICYmIF9pdGVyYXRvcjIucmV0dXJuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IyLnJldHVybigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJyb2FkY2FzdCA/IF90aGlzLmJyb2FkY2FzdCgpIDogX3RoaXMuc2VyaWFsaXplKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKiBUeXBpY2FsbHkgdGhpcyBpcyBjYWxsZWQgYXV0b21hdGljYWxseSBqdXN0IHByaW9yIHRvIHNpZ25pbmcuICBPbmNlIGZpbmFsaXplZCB0aGlzIHRyYW5zYWN0aW9uIGNhbiBub3QgYmUgY2hhbmdlZC4gKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcImZpbmFsaXplXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmaW5hbGl6ZSgpIHtcbiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXG4gICAgICAgICAgICAgICAgaWYgKF90aGlzMi50cl9idWZmZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYWxyZWFkeSBmaW5hbGl6ZWRcIik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShBcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcImdldF9vYmplY3RzXCIsIFtbXCIyLjEuMFwiXV0pLnRoZW4oZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZF9ibG9ja190aW1lX3N0cmluZyA9IHJbMF0udGltZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzMi5leHBpcmF0aW9uID09PSAwKSBfdGhpczIuZXhwaXJhdGlvbiA9IGJhc2VfZXhwaXJhdGlvbl9zZWMoKSArIENoYWluQ29uZmlnLmV4cGlyZV9pbl9zZWNzO1xuICAgICAgICAgICAgICAgICAgICBfdGhpczIucmVmX2Jsb2NrX251bSA9IHJbMF0uaGVhZF9ibG9ja19udW1iZXIgJiAweEZGRkY7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzMi5yZWZfYmxvY2tfcHJlZml4ID0gbmV3IEJ1ZmZlcihyWzBdLmhlYWRfYmxvY2tfaWQsICdoZXgnKS5yZWFkVUludDMyTEUoNCk7XG4gICAgICAgICAgICAgICAgICAgIC8vREVCVUcgY29uc29sZS5sb2coXCJyZWZfYmxvY2tcIixAcmVmX2Jsb2NrX251bSxAcmVmX2Jsb2NrX3ByZWZpeCxyKVxuXG4gICAgICAgICAgICAgICAgICAgIHZhciBpdGVyYWJsZSA9IF90aGlzMi5vcGVyYXRpb25zO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgb3A7IGkgPCBpdGVyYWJsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3AgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcFsxXVtcImZpbmFsaXplXCJdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BbMV0uZmluYWxpemUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIF90eXBlID0gb3BzLm9wZXJhdGlvbi5zdF9vcGVyYXRpb25zW29wWzBdXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoZXhCdWZmZXIgPSBfdHlwZS50b0J1ZmZlcihvcFsxXSkudG9TdHJpbmcoXCJoZXhcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIk9wZXJhdGlvbiAlczogJU8gPT4gJXMgKCVkIGJ5dGVzKVwiLCBfdHlwZS5vcGVyYXRpb25fbmFtZSwgb3BbMV0sIGhleEJ1ZmZlciwgaGV4QnVmZmVyLmxlbmd0aCAvIDIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF90aGlzMi50cl9idWZmZXIgPSBvcHMudHJhbnNhY3Rpb24udG9CdWZmZXIoX3RoaXMyKTtcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKiBAcmV0dXJuIHtzdHJpbmd9IGhleCB0cmFuc2FjdGlvbiBJRCAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6IFwiaWRcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGlkKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vdCBmaW5hbGl6ZWRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaGFzaC5zaGEyNTYodGhpcy50cl9idWZmZXIpLnRvU3RyaW5nKCdoZXgnKS5zdWJzdHJpbmcoMCwgNDApO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAgICBUeXBpY2FsbHkgb25lIHdpbGwgdXNlIHtAbGluayB0aGlzLmFkZF90eXBlX29wZXJhdGlvbn0gaW5zdGVhZC5cbiAgICAgICAgICAgIEBhcmcge2FycmF5fSBvcGVyYXRpb24gLSBbb3BlcmF0aW9uX2lkLCBvcGVyYXRpb25dXG4gICAgICAgICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogXCJhZGRfb3BlcmF0aW9uXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRfb3BlcmF0aW9uKG9wZXJhdGlvbikge1xuICAgICAgICAgICAgaWYgKHRoaXMudHJfYnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYWxyZWFkeSBmaW5hbGl6ZWRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhc3NlcnQob3BlcmF0aW9uLCBcIm9wZXJhdGlvblwiKTtcbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvcGVyYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0aW5nIGFycmF5IFtvcGVyYXRpb25faWQsIG9wZXJhdGlvbl1cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLm9wZXJhdGlvbnMucHVzaChvcGVyYXRpb24pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6IFwiZ2V0X3R5cGVfb3BlcmF0aW9uXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRfdHlwZV9vcGVyYXRpb24obmFtZSwgb3BlcmF0aW9uKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJhbHJlYWR5IGZpbmFsaXplZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFzc2VydChuYW1lLCBcIm5hbWVcIik7XG4gICAgICAgICAgICBhc3NlcnQob3BlcmF0aW9uLCBcIm9wZXJhdGlvblwiKTtcbiAgICAgICAgICAgIHZhciBfdHlwZSA9IG9wc1tuYW1lXTtcbiAgICAgICAgICAgIGFzc2VydChfdHlwZSwgXCJVbmtub3duIG9wZXJhdGlvbiBcIiArIG5hbWUpO1xuICAgICAgICAgICAgdmFyIG9wZXJhdGlvbl9pZCA9IENoYWluVHlwZXMub3BlcmF0aW9uc1tfdHlwZS5vcGVyYXRpb25fbmFtZV07XG4gICAgICAgICAgICBpZiAob3BlcmF0aW9uX2lkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bmtub3duIG9wZXJhdGlvbjogXCIgKyBfdHlwZS5vcGVyYXRpb25fbmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW9wZXJhdGlvbi5mZWUpIHtcbiAgICAgICAgICAgICAgICBvcGVyYXRpb24uZmVlID0geyBhbW91bnQ6IDAsIGFzc2V0X2lkOiAwIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobmFtZSA9PT0gJ3Byb3Bvc2FsX2NyZWF0ZScpIHtcbiAgICAgICAgICAgICAgICBvcGVyYXRpb24uZXhwaXJhdGlvbl90aW1lIHx8IChvcGVyYXRpb24uZXhwaXJhdGlvbl90aW1lID0gYmFzZV9leHBpcmF0aW9uX3NlYygpICsgQ2hhaW5Db25maWcuZXhwaXJlX2luX3NlY3NfcHJvcG9zYWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG9wZXJhdGlvbl9pbnN0YW5jZSA9IF90eXBlLmZyb21PYmplY3Qob3BlcmF0aW9uKTtcbiAgICAgICAgICAgIHJldHVybiBbb3BlcmF0aW9uX2lkLCBvcGVyYXRpb25faW5zdGFuY2VdO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqIG9wdGlvbmFsOiB0aGVyZSBpcyBhIGRlYWZ1bHQgZXhwaXJhdGlvbiAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6IFwic2V0X2V4cGlyZV9zZWNvbmRzXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRfZXhwaXJlX3NlY29uZHMoc2VjKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJhbHJlYWR5IGZpbmFsaXplZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV4cGlyYXRpb24gPSBiYXNlX2V4cGlyYXRpb25fc2VjKCkgKyBzZWM7XG4gICAgICAgIH1cblxuICAgICAgICAvKiBXcmFwcyB0aGlzIHRyYW5zYWN0aW9uIGluIGEgcHJvcG9zYWxfY3JlYXRlIHRyYW5zYWN0aW9uICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogXCJwcm9wb3NlXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBwcm9wb3NlKHByb3Bvc2FsX2NyZWF0ZV9vcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJhbHJlYWR5IGZpbmFsaXplZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdGhpcy5vcGVyYXRpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImFkZCBvcGVyYXRpb24gZmlyc3RcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGFzc2VydChwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucywgXCJwcm9wb3NhbF9jcmVhdGVfb3B0aW9uc1wiKTtcbiAgICAgICAgICAgIGFzc2VydChwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucy5mZWVfcGF5aW5nX2FjY291bnQsIFwicHJvcG9zYWxfY3JlYXRlX29wdGlvbnMuZmVlX3BheWluZ19hY2NvdW50XCIpO1xuXG4gICAgICAgICAgICB2YXIgcHJvcG9zZWRfb3BzID0gdGhpcy5vcGVyYXRpb25zLm1hcChmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBvcDogb3AgfTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLm9wZXJhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuc2lnbmF0dXJlcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzID0gW107XG4gICAgICAgICAgICBwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucy5wcm9wb3NlZF9vcHMgPSBwcm9wb3NlZF9vcHM7XG4gICAgICAgICAgICB0aGlzLmFkZF90eXBlX29wZXJhdGlvbihcInByb3Bvc2FsX2NyZWF0ZVwiLCBwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcImhhc19wcm9wb3NlZF9vcGVyYXRpb25cIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGhhc19wcm9wb3NlZF9vcGVyYXRpb24oKSB7XG4gICAgICAgICAgICB2YXIgaGFzUHJvcG9zZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5vcGVyYXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKFwicHJvcG9zZWRfb3BzXCIgaW4gdGhpcy5vcGVyYXRpb25zW2ldWzFdKSB7XG4gICAgICAgICAgICAgICAgICAgIGhhc1Byb3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gaGFzUHJvcG9zZWQ7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogb3B0aW9uYWw6IHRoZSBmZWVzIGNhbiBiZSBvYnRhaW5lZCBmcm9tIHRoZSB3aXRuZXNzIG5vZGUgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcInNldF9yZXF1aXJlZF9mZWVzXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRfcmVxdWlyZWRfZmVlcyhhc3NldF9pZCkge1xuICAgICAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgICAgICAgICAgIHZhciBmZWVfcG9vbDtcbiAgICAgICAgICAgIGlmICh0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImFscmVhZHkgZmluYWxpemVkXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCF0aGlzLm9wZXJhdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYWRkIG9wZXJhdGlvbnMgZmlyc3RcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgb3BlcmF0aW9ucyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIG9wOyBpIDwgdGhpcy5vcGVyYXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgb3AgPSB0aGlzLm9wZXJhdGlvbnNbaV07XG4gICAgICAgICAgICAgICAgb3BlcmF0aW9ucy5wdXNoKG9wcy5vcGVyYXRpb24udG9PYmplY3Qob3ApKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFhc3NldF9pZCkge1xuICAgICAgICAgICAgICAgIHZhciBvcDFfZmVlID0gb3BlcmF0aW9uc1swXVsxXS5mZWU7XG4gICAgICAgICAgICAgICAgaWYgKG9wMV9mZWUgJiYgb3AxX2ZlZS5hc3NldF9pZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhc3NldF9pZCA9IG9wMV9mZWUuYXNzZXRfaWQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXNzZXRfaWQgPSBcIjEuMy4wXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcHJvbWlzZXMgPSBbQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoXCJnZXRfcmVxdWlyZWRfZmVlc1wiLCBbb3BlcmF0aW9ucywgYXNzZXRfaWRdKV07XG5cbiAgICAgICAgICAgIHZhciBmZWVBc3NldFByb21pc2UgPSBudWxsO1xuICAgICAgICAgICAgaWYgKGFzc2V0X2lkICE9PSBcIjEuMy4wXCIpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGhhbmRsZXMgdGhlIGZhbGxiYWNrIHRvIHBheWluZyBmZWVzIGluIEJUUyBpZiB0aGUgZmVlIHBvb2wgaXMgZW1wdHkuXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChBcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcImdldF9yZXF1aXJlZF9mZWVzXCIsIFtvcGVyYXRpb25zLCBcIjEuMy4wXCJdKSk7XG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChBcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcImdldF9vYmplY3RzXCIsIFtbYXNzZXRfaWRdXSkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oZnVuY3Rpb24gKHJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgICB2YXIgX3Jlc3VsdHMgPSBfc2xpY2VkVG9BcnJheShyZXN1bHRzLCAzKSxcbiAgICAgICAgICAgICAgICAgICAgZmVlcyA9IF9yZXN1bHRzWzBdLFxuICAgICAgICAgICAgICAgICAgICBjb3JlRmVlcyA9IF9yZXN1bHRzWzFdLFxuICAgICAgICAgICAgICAgICAgICBhc3NldCA9IF9yZXN1bHRzWzJdO1xuXG4gICAgICAgICAgICAgICAgYXNzZXQgPSBhc3NldCA/IGFzc2V0WzBdIDogbnVsbDtcblxuICAgICAgICAgICAgICAgIHZhciBkeW5hbWljUHJvbWlzZSA9IGFzc2V0X2lkICE9PSBcIjEuMy4wXCIgJiYgYXNzZXQgPyBBcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcImdldF9vYmplY3RzXCIsIFtbYXNzZXQuZHluYW1pY19hc3NldF9kYXRhX2lkXV0pIDogbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZHluYW1pY1Byb21pc2UudGhlbihmdW5jdGlvbiAoZHluYW1pY09iamVjdCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXNzZXRfaWQgIT09IFwiMS4zLjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmVlX3Bvb2wgPSBkeW5hbWljT2JqZWN0ID8gZHluYW1pY09iamVjdFswXS5mZWVfcG9vbCA6IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG90YWxGZWVzID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwLCBmZWU7IGogPCBjb3JlRmVlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlZSA9IGNvcmVGZWVzW2pdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsRmVlcyArPSBmZWUuYW1vdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodG90YWxGZWVzID4gcGFyc2VJbnQoZmVlX3Bvb2wsIDEwKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlZXMgPSBjb3JlRmVlcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NldF9pZCA9IFwiMS4zLjBcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFByb3Bvc2VkIHRyYW5zYWN0aW9ucyBuZWVkIHRvIGJlIGZsYXR0ZW5lZFxuICAgICAgICAgICAgICAgICAgICB2YXIgZmxhdF9hc3NldHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZsYXR0ZW4gPSBmdW5jdGlvbiBmbGF0dGVuKG9iaikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgPSAwLCBpdGVtOyBrIDwgb2JqLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0gPSBvYmpba107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYXR0ZW4oaXRlbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGF0X2Fzc2V0cy5wdXNoKG9iaik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGZsYXR0ZW4oZmVlcyk7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIGFzc2V0X2luZGV4ID0gMDtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgc2V0X2ZlZSA9IGZ1bmN0aW9uIHNldF9mZWUob3BlcmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9wZXJhdGlvbi5mZWUgfHwgb3BlcmF0aW9uLmZlZS5hbW91bnQgPT09IDAgfHwgb3BlcmF0aW9uLmZlZS5hbW91bnQudG9TdHJpbmcgJiYgb3BlcmF0aW9uLmZlZS5hbW91bnQudG9TdHJpbmcoKSA9PT0gXCIwXCIgLy8gTG9uZ1xuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5mZWUgPSBmbGF0X2Fzc2V0c1thc3NldF9pbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwibmV3IG9wZXJhdGlvbi5mZWVcIiwgb3BlcmF0aW9uLmZlZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIm9sZCBvcGVyYXRpb24uZmVlXCIsIG9wZXJhdGlvbi5mZWUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXRfaW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcGVyYXRpb24ucHJvcG9zZWRfb3BzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHkgPSAwOyB5IDwgb3BlcmF0aW9uLnByb3Bvc2VkX29wcy5sZW5ndGg7IHkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChzZXRfZmVlKG9wZXJhdGlvbi5wcm9wb3NlZF9vcHNbeV0ub3BbMV0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9cmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IF90aGlzMy5vcGVyYXRpb25zLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0X2ZlZShfdGhpczMub3BlcmF0aW9uc1tfaV1bMV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy9ERUJVRyBjb25zb2xlLmxvZygnLi4uIGdldF9yZXF1aXJlZF9mZWVzJyxvcGVyYXRpb25zLGFzc2V0X2lkLGZsYXRfYXNzZXRzKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogXCJnZXRfcG90ZW50aWFsX3NpZ25hdHVyZXNcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldF9wb3RlbnRpYWxfc2lnbmF0dXJlcygpIHtcbiAgICAgICAgICAgIHZhciB0cl9vYmplY3QgPSBvcHMuc2lnbmVkX3RyYW5zYWN0aW9uLnRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtBcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcImdldF9wb3RlbnRpYWxfc2lnbmF0dXJlc1wiLCBbdHJfb2JqZWN0XSksIEFwaXMuaW5zdGFuY2UoKS5kYl9hcGkoKS5leGVjKFwiZ2V0X3BvdGVudGlhbF9hZGRyZXNzX3NpZ25hdHVyZXNcIiwgW3RyX29iamVjdF0pXSkudGhlbihmdW5jdGlvbiAocmVzdWx0cykge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHB1YmtleXM6IHJlc3VsdHNbMF0sIGFkZHlzOiByZXN1bHRzWzFdIH07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcImdldF9yZXF1aXJlZF9zaWduYXR1cmVzXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRfcmVxdWlyZWRfc2lnbmF0dXJlcyhhdmFpbGFibGVfa2V5cykge1xuICAgICAgICAgICAgaWYgKCFhdmFpbGFibGVfa2V5cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB0cl9vYmplY3QgPSBvcHMuc2lnbmVkX3RyYW5zYWN0aW9uLnRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgLy9ERUJVRyBjb25zb2xlLmxvZygnLi4uIHRyX29iamVjdCcsdHJfb2JqZWN0KVxuICAgICAgICAgICAgcmV0dXJuIEFwaXMuaW5zdGFuY2UoKS5kYl9hcGkoKS5leGVjKFwiZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXNcIiwgW3RyX29iamVjdCwgYXZhaWxhYmxlX2tleXNdKS50aGVuKGZ1bmN0aW9uIChyZXF1aXJlZF9wdWJsaWNfa2V5cykge1xuICAgICAgICAgICAgICAgIC8vREVCVUcgY29uc29sZS5sb2coJy4uLiBnZXRfcmVxdWlyZWRfc2lnbmF0dXJlcycscmVxdWlyZWRfcHVibGljX2tleXMpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVpcmVkX3B1YmxpY19rZXlzO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogXCJhZGRfc2lnbmVyXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRfc2lnbmVyKHByaXZhdGVfa2V5KSB7XG4gICAgICAgICAgICB2YXIgcHVibGljX2tleSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKTtcblxuXG4gICAgICAgICAgICBhc3NlcnQocHJpdmF0ZV9rZXkuZCwgXCJyZXF1aXJlZCBQcml2YXRlS2V5IG9iamVjdFwiKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc2lnbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYWxyZWFkeSBzaWduZWRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXB1YmxpY19rZXkuUSkge1xuICAgICAgICAgICAgICAgIHB1YmxpY19rZXkgPSBQdWJsaWNLZXkuZnJvbVB1YmxpY0tleVN0cmluZyhwdWJsaWNfa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHByZXZlbnQgZHVwbGljYXRlc1xuICAgICAgICAgICAgdmFyIHNwSGV4ID0gcHJpdmF0ZV9rZXkudG9IZXgoKTtcbiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyA9IHRydWU7XG4gICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IzID0gZmFsc2U7XG4gICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IzID0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjMgPSB0aGlzLnNpZ25lcl9wcml2YXRlX2tleXNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDM7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMgPSAoX3N0ZXAzID0gX2l0ZXJhdG9yMy5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyA9IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwID0gX3N0ZXAzLnZhbHVlO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChzcFswXS50b0hleCgpID09PSBzcEhleCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMyA9IHRydWU7XG4gICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IzID0gZXJyO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24zICYmIF9pdGVyYXRvcjMucmV0dXJuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IzLnJldHVybigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnNpZ25lcl9wcml2YXRlX2tleXMucHVzaChbcHJpdmF0ZV9rZXksIHB1YmxpY19rZXldKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcInNpZ25cIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpZ24oKSB7XG4gICAgICAgICAgICB2YXIgY2hhaW5faWQgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IEFwaXMuaW5zdGFuY2UoKS5jaGFpbl9pZDtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vdCBmaW5hbGl6ZWRcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zaWduZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJhbHJlYWR5IHNpZ25lZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRyYW5zYWN0aW9uIHdhcyBub3Qgc2lnbmVkLiBEbyB5b3UgaGF2ZSBhIHByaXZhdGUga2V5PyBbbm9fc2lnbmVyc11cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZW5kID0gdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyAwIDwgZW5kID8gaSA8IGVuZCA6IGkgPiBlbmQ7IDAgPCBlbmQgPyBpKysgOiBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgX3NpZ25lcl9wcml2YXRlX2tleXMkID0gX3NsaWNlZFRvQXJyYXkodGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzW2ldLCAyKSxcbiAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZV9rZXkgPSBfc2lnbmVyX3ByaXZhdGVfa2V5cyRbMF0sXG4gICAgICAgICAgICAgICAgICAgIHB1YmxpY19rZXkgPSBfc2lnbmVyX3ByaXZhdGVfa2V5cyRbMV07XG5cbiAgICAgICAgICAgICAgICB2YXIgc2lnID0gU2lnbmF0dXJlLnNpZ25CdWZmZXIoQnVmZmVyLmNvbmNhdChbbmV3IEJ1ZmZlcihjaGFpbl9pZCwgJ2hleCcpLCB0aGlzLnRyX2J1ZmZlcl0pLCBwcml2YXRlX2tleSwgcHVibGljX2tleSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zaWduYXR1cmVzLnB1c2goc2lnLnRvQnVmZmVyKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzID0gW107XG4gICAgICAgICAgICB0aGlzLnNpZ25lZCA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogXCJzZXJpYWxpemVcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNlcmlhbGl6ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiBvcHMuc2lnbmVkX3RyYW5zYWN0aW9uLnRvT2JqZWN0KHRoaXMpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6IFwidG9PYmplY3RcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvT2JqZWN0KCkge1xuICAgICAgICAgICAgcmV0dXJuIG9wcy5zaWduZWRfdHJhbnNhY3Rpb24udG9PYmplY3QodGhpcyk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogXCJicm9hZGNhc3RcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJyb2FkY2FzdCh3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKSB7XG4gICAgICAgICAgICB2YXIgX3RoaXM0ID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKHRoaXMudHJfYnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Jyb2FkY2FzdCh3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmluYWxpemUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzNC5fYnJvYWRjYXN0KHdhc19icm9hZGNhc3RfY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uQnVpbGRlcjtcbn0oKTtcblxudmFyIGJhc2VfZXhwaXJhdGlvbl9zZWMgPSBmdW5jdGlvbiBiYXNlX2V4cGlyYXRpb25fc2VjKCkge1xuICAgIHZhciBoZWFkX2Jsb2NrX3NlYyA9IE1hdGguY2VpbChnZXRIZWFkQmxvY2tEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7XG4gICAgdmFyIG5vd19zZWMgPSBNYXRoLmNlaWwoRGF0ZS5ub3coKSAvIDEwMDApO1xuICAgIC8vIFRoZSBoZWFkIGJsb2NrIHRpbWUgc2hvdWxkIGJlIHVwZGF0ZWQgZXZlcnkgMyBzZWNvbmRzLiAgSWYgaXQgaXNuJ3RcbiAgICAvLyB0aGVuIGhlbHAgdGhlIHRyYW5zYWN0aW9uIHRvIGV4cGlyZSAodXNlIGhlYWRfYmxvY2tfc2VjKVxuICAgIGlmIChub3dfc2VjIC0gaGVhZF9ibG9ja19zZWMgPiAzMCkge1xuICAgICAgICByZXR1cm4gaGVhZF9ibG9ja19zZWM7XG4gICAgfVxuICAgIC8vIElmIHRoZSB1c2VyJ3MgY2xvY2sgaXMgdmVyeSBmYXIgYmVoaW5kLCB1c2UgdGhlIGhlYWQgYmxvY2sgdGltZS5cbiAgICByZXR1cm4gTWF0aC5tYXgobm93X3NlYywgaGVhZF9ibG9ja19zZWMpO1xufTtcblxuZnVuY3Rpb24gX2Jyb2FkY2FzdCh3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKSB7XG4gICAgdmFyIF90aGlzNSA9IHRoaXM7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXG4gICAgICAgIGlmICghX3RoaXM1LnNpZ25lZCkge1xuICAgICAgICAgICAgX3RoaXM1LnNpZ24oKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIV90aGlzNS50cl9idWZmZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vdCBmaW5hbGl6ZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFfdGhpczUuc2lnbmF0dXJlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vdCBzaWduZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFfdGhpczUub3BlcmF0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vIG9wZXJhdGlvbnNcIik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdHJfb2JqZWN0ID0gb3BzLnNpZ25lZF90cmFuc2FjdGlvbi50b09iamVjdChfdGhpczUpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZygnLi4uIGJyb2FkY2FzdF90cmFuc2FjdGlvbl93aXRoX2NhbGxiYWNrICEhIScpXG4gICAgICAgIEFwaXMuaW5zdGFuY2UoKS5uZXR3b3JrX2FwaSgpLmV4ZWMoXCJicm9hZGNhc3RfdHJhbnNhY3Rpb25fd2l0aF9jYWxsYmFja1wiLCBbZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzKTtcbiAgICAgICAgfSwgdHJfb2JqZWN0XSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKCcuLi4gYnJvYWRjYXN0IHN1Y2Nlc3MsIHdhaXRpbmcgZm9yIGNhbGxiYWNrJylcbiAgICAgICAgICAgIGlmICh3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKSB3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2cgbWF5IGJlIHJlZHVuZGFudCBmb3IgbmV0d29yayBlcnJvcnMsIG90aGVyIGVycm9ycyBjb3VsZCBvY2N1clxuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuICAgICAgICAgICAgaWYgKCFtZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IFwiXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWplY3QobmV3IEVycm9yKG1lc3NhZ2UgKyBcIlxcblwiICsgJ2dyYXBoZW5lLWNyeXB0byAnICsgJyBkaWdlc3QgJyArIGhhc2guc2hhMjU2KF90aGlzNS50cl9idWZmZXIpLnRvU3RyaW5nKCdoZXgnKSArICcgdHJhbnNhY3Rpb24gJyArIF90aGlzNS50cl9idWZmZXIudG9TdHJpbmcoJ2hleCcpICsgJyAnICsgSlNPTi5zdHJpbmdpZnkodHJfb2JqZWN0KSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRIZWFkQmxvY2tEYXRlKCkge1xuICAgIHJldHVybiB0aW1lU3RyaW5nVG9EYXRlKGhlYWRfYmxvY2tfdGltZV9zdHJpbmcpO1xufVxuXG5mdW5jdGlvbiB0aW1lU3RyaW5nVG9EYXRlKHRpbWVfc3RyaW5nKSB7XG4gICAgaWYgKCF0aW1lX3N0cmluZykgcmV0dXJuIG5ldyBEYXRlKFwiMTk3MC0wMS0wMVQwMDowMDowMC4wMDBaXCIpO1xuICAgIGlmICghL1okLy50ZXN0KHRpbWVfc3RyaW5nKSkgLy9kb2VzIG5vdCBlbmQgaW4gWlxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY3J5cHRvbm9tZXgvZ3JhcGhlbmUvaXNzdWVzLzM2OFxuICAgICAgICB0aW1lX3N0cmluZyA9IHRpbWVfc3RyaW5nICsgXCJaXCI7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHRpbWVfc3RyaW5nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc2FjdGlvbkJ1aWxkZXI7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmZ1bmN0aW9uIGdldChzdGF0ZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHJldHVybiBzdGF0ZVtrZXldIHx8IFwiXCI7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gc2V0KHN0YXRlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICAgIHN0YXRlW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgZ2V0OiBnZXQsXG4gICAgc2V0OiBzZXRcbn07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIEFkZHJlc3M6IHJlcXVpcmUoXCIuL3NyYy9hZGRyZXNzXCIpLFxuICAgIEFlczogcmVxdWlyZShcIi4vc3JjL2Flc1wiKSxcbiAgICBQcml2YXRlS2V5OiByZXF1aXJlKFwiLi9zcmMvUHJpdmF0ZUtleVwiKSxcbiAgICBQdWJsaWNLZXk6IHJlcXVpcmUoXCIuL3NyYy9QdWJsaWNLZXlcIiksXG4gICAgU2lnbmF0dXJlOiByZXF1aXJlKFwiLi9zcmMvc2lnbmF0dXJlXCIpLFxuICAgIGJyYWluS2V5OiByZXF1aXJlKFwiLi9zcmMvQnJhaW5LZXlcIiksXG4gICAgaGFzaDogcmVxdWlyZShcIi4vc3JjL2hhc2hcIiksXG4gICAga2V5OiByZXF1aXJlKFwiLi9zcmMvS2V5VXRpbHNcIilcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG5vcm1hbGl6ZShicmFpbktleSkge1xuICAgIGlmICh0eXBlb2YgYnJhaW5LZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInN0cmluZyByZXF1aXJlZCBmb3IgYnJhaW5LZXlcIik7XG4gICAgfVxuICAgIGJyYWluS2V5ID0gYnJhaW5LZXkudHJpbSgpO1xuICAgIHJldHVybiBicmFpbktleS5zcGxpdCgvW1xcdFxcblxcdlxcZlxcciBdKy8pLmpvaW4oJyAnKTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgX3NsaWNlZFRvQXJyYXkgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIHNsaWNlSXRlcmF0b3IoYXJyLCBpKSB7IHZhciBfYXJyID0gW107IHZhciBfbiA9IHRydWU7IHZhciBfZCA9IGZhbHNlOyB2YXIgX2UgPSB1bmRlZmluZWQ7IHRyeSB7IGZvciAodmFyIF9pID0gYXJyW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3M7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHsgX2Fyci5wdXNoKF9zLnZhbHVlKTsgaWYgKGkgJiYgX2Fyci5sZW5ndGggPT09IGkpIGJyZWFrOyB9IH0gY2F0Y2ggKGVycikgeyBfZCA9IHRydWU7IF9lID0gZXJyOyB9IGZpbmFsbHkgeyB0cnkgeyBpZiAoIV9uICYmIF9pW1wicmV0dXJuXCJdKSBfaVtcInJldHVyblwiXSgpOyB9IGZpbmFsbHkgeyBpZiAoX2QpIHRocm93IF9lOyB9IH0gcmV0dXJuIF9hcnI7IH0gcmV0dXJuIGZ1bmN0aW9uIChhcnIsIGkpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgeyByZXR1cm4gYXJyOyB9IGVsc2UgaWYgKFN5bWJvbC5pdGVyYXRvciBpbiBPYmplY3QoYXJyKSkgeyByZXR1cm4gc2xpY2VJdGVyYXRvcihhcnIsIGkpOyB9IGVsc2UgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZVwiKTsgfSB9OyB9KCk7XG5cbnZhciBrZXk7XG52YXIgUHJpdmF0ZUtleSA9IHJlcXVpcmUoJy4vUHJpdmF0ZUtleScpO1xudmFyIFB1YmxpY0tleSA9IHJlcXVpcmUoJy4vUHVibGljS2V5Jyk7XG52YXIgQWRkcmVzcyA9IHJlcXVpcmUoJy4vYWRkcmVzcycpO1xudmFyIEFlcyA9IHJlcXVpcmUoJy4vYWVzJyk7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnLi9oYXNoJyk7XG4vLyB2YXIgZGljdGlvbmFyeSA9IHJlcXVpcmUoJy4vZGljdGlvbmFyeV9lbicpO1xudmFyIHNlY3VyZVJhbmRvbSA9IHJlcXVpcmUoJ3NlY3VyZS1yYW5kb20nKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncGVlcnBsYXlzanMtd3MnKSxcbiAgICBDaGFpbkNvbmZpZyA9IF9yZXF1aXJlLkNoYWluQ29uZmlnO1xuXG4vLyBoYXNoIGZvciAuMjUgc2Vjb25kXG5cblxudmFyIEhBU0hfUE9XRVJfTUlMTFMgPSAyNTA7XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5ID0ge1xuXG4gICAgLyoqIFVzZXMgMSBzZWNvbmQgb2YgaGFzaGluZyBwb3dlciB0byBjcmVhdGUgYSBrZXkvcGFzc3dvcmQgY2hlY2tzdW0uICBBblxuICAgIGltcGxlbWVudGF0aW9uIGNhbiByZS1jYWxsIHRoaXMgbWV0aG9kIHdpdGggdGhlIHNhbWUgcGFzc3dvcmQgdG8gcmUtbWF0Y2hcbiAgICB0aGUgc3RyZW5ndGggb2YgdGhlIENQVSAoZWl0aGVyIGFmdGVyIG1vdmluZyBmcm9tIGEgZGVza3RvcCB0byBhIG1vYmlsZSxcbiAgICBtb2JpbGUgdG8gZGVza3RvcCwgb3IgTiB5ZWFycyBmcm9tIG5vdyB3aGVuIENQVXMgYXJlIHByZXN1bWFibHkgc3Ryb25nZXIpLlxuICAgICBBIHNhbHQgaXMgdXNlZCBmb3IgYWxsIHRoZSBub3JtYWwgcmVhc29ucy4uLlxuICAgICBAcmV0dXJuIG9iamVjdCB7XG4gICAgICAgIGFlc19wcml2YXRlOiBBZXMsXG4gICAgICAgIGNoZWNrc3VtOiBcIntoYXNoX2l0ZXJhdGlvbl9jb3VudH0se3NhbHR9LHtjaGVja3N1bX1cIlxuICAgIH1cbiAgICAqL1xuICAgIGFlc19jaGVja3N1bTogZnVuY3Rpb24gYWVzX2NoZWNrc3VtKHBhc3N3b3JkKSB7XG4gICAgICAgIGlmICghKHR5cGVvZiBwYXNzd29yZCA9PT0gXCJzdHJpbmdcIikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBcInBhc3N3b3JkIHN0cmluZyByZXF1aXJlZFwiKCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNhbHQgPSBzZWN1cmVSYW5kb20ucmFuZG9tQnVmZmVyKDQpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgdmFyIGl0ZXJhdGlvbnMgPSAwO1xuICAgICAgICB2YXIgc2VjcmV0ID0gc2FsdCArIHBhc3N3b3JkO1xuICAgICAgICAvLyBoYXNoIGZvciAuMSBzZWNvbmRcbiAgICAgICAgdmFyIHN0YXJ0X3QgPSBEYXRlLm5vdygpO1xuICAgICAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0X3QgPCBIQVNIX1BPV0VSX01JTExTKSB7XG4gICAgICAgICAgICBzZWNyZXQgPSBoYXNoLnNoYTI1NihzZWNyZXQpO1xuICAgICAgICAgICAgaXRlcmF0aW9ucyArPSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNoZWNrc3VtID0gaGFzaC5zaGEyNTYoc2VjcmV0KTtcbiAgICAgICAgdmFyIGNoZWNrc3VtX3N0cmluZyA9IFtpdGVyYXRpb25zLCBzYWx0LnRvU3RyaW5nKCdoZXgnKSwgY2hlY2tzdW0uc2xpY2UoMCwgNCkudG9TdHJpbmcoJ2hleCcpXS5qb2luKCcsJyk7XG5cbiAgICAgICAgcmV0dXJuIHsgYWVzX3ByaXZhdGU6IEFlcy5mcm9tU2VlZChzZWNyZXQpLFxuICAgICAgICAgICAgY2hlY2tzdW06IGNoZWNrc3VtX3N0cmluZ1xuICAgICAgICB9O1xuICAgIH0sXG5cblxuICAgIC8qKiBQcm92aWRlIGEgbWF0Y2hpbmcgcGFzc3dvcmQgYW5kIGtleV9jaGVja3N1bS4gIEEgXCJ3cm9uZyBwYXNzd29yZFwiXG4gICAgZXJyb3IgaXMgdGhyb3duIGlmIHRoZSBwYXNzd29yZCBkb2VzIG5vdCBtYXRjaC4gIElmIHRoaXMgbWV0aG9kIHRha2VzXG4gICAgbXVjaCBtb3JlIG9yIGxlc3MgdGhhbiAxIHNlY29uZCB0byByZXR1cm4sIG9uZSBzaG91bGQgY29uc2lkZXIgdXBkYXRpbmdcbiAgICBhbGwgZW5jeXJwdGVkIGZpZWxkcyB1c2luZyBhIG5ldyBrZXkua2V5X2NoZWNrc3VtLlxuICAgICovXG4gICAgYWVzX3ByaXZhdGU6IGZ1bmN0aW9uIGFlc19wcml2YXRlKHBhc3N3b3JkLCBrZXlfY2hlY2tzdW0pIHtcbiAgICAgICAgdmFyIF9rZXlfY2hlY2tzdW0kc3BsaXQgPSBrZXlfY2hlY2tzdW0uc3BsaXQoJywnKSxcbiAgICAgICAgICAgIF9rZXlfY2hlY2tzdW0kc3BsaXQyID0gX3NsaWNlZFRvQXJyYXkoX2tleV9jaGVja3N1bSRzcGxpdCwgMyksXG4gICAgICAgICAgICBpdGVyYXRpb25zID0gX2tleV9jaGVja3N1bSRzcGxpdDJbMF0sXG4gICAgICAgICAgICBzYWx0ID0gX2tleV9jaGVja3N1bSRzcGxpdDJbMV0sXG4gICAgICAgICAgICBjaGVja3N1bSA9IF9rZXlfY2hlY2tzdW0kc3BsaXQyWzJdO1xuXG4gICAgICAgIHZhciBzZWNyZXQgPSBzYWx0ICsgcGFzc3dvcmQ7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyAwIDwgaXRlcmF0aW9ucyA/IGkgPCBpdGVyYXRpb25zIDogaSA+IGl0ZXJhdGlvbnM7IDAgPCBpdGVyYXRpb25zID8gaSsrIDogaSsrKSB7XG4gICAgICAgICAgICBzZWNyZXQgPSBoYXNoLnNoYTI1NihzZWNyZXQpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBuZXdfY2hlY2tzdW0gPSBoYXNoLnNoYTI1NihzZWNyZXQpO1xuICAgICAgICBpZiAoIShuZXdfY2hlY2tzdW0uc2xpY2UoMCwgNCkudG9TdHJpbmcoJ2hleCcpID09PSBjaGVja3N1bSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIndyb25nIHBhc3N3b3JkXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBBZXMuZnJvbVNlZWQoc2VjcmV0KTtcbiAgICB9LFxuXG5cbiAgICAvKipcbiAgICAgICAgQSB3ZWVrIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yIGNhbiBydW4gb3V0IG9mIGVudHJvcHkuICBUaGlzIHNob3VsZCBlbnN1cmUgZXZlbiB0aGUgd29yc3QgcmFuZG9tIG51bWJlciBpbXBsZW1lbnRhdGlvbiB3aWxsIGJlIHJlYXNvbmFibHkgc2FmZS5cbiAgICAgICAgIEBwYXJhbTEgc3RyaW5nIGVudHJvcHkgb2YgYXQgbGVhc3QgMzIgYnl0ZXNcbiAgICAqL1xuICAgIHJhbmRvbTMyQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gcmFuZG9tMzJCeXRlQnVmZmVyKCkge1xuICAgICAgICB2YXIgZW50cm9weSA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogdGhpcy5icm93c2VyRW50cm9weSgpO1xuXG5cbiAgICAgICAgaWYgKCEodHlwZW9mIGVudHJvcHkgPT09ICdzdHJpbmcnKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwic3RyaW5nIHJlcXVpcmVkIGZvciBlbnRyb3B5XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVudHJvcHkubGVuZ3RoIDwgMzIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImV4cGVjdGluZyBhdCBsZWFzdCAzMiBieXRlcyBvZiBlbnRyb3B5XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0YXJ0X3QgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIHdoaWxlIChEYXRlLm5vdygpIC0gc3RhcnRfdCA8IEhBU0hfUE9XRVJfTUlMTFMpIHtcbiAgICAgICAgICAgIGVudHJvcHkgPSBoYXNoLnNoYTI1NihlbnRyb3B5KTtcbiAgICAgICAgfXZhciBoYXNoX2FycmF5ID0gW107XG4gICAgICAgIGhhc2hfYXJyYXkucHVzaChlbnRyb3B5KTtcblxuICAgICAgICAvLyBIYXNoaW5nIGZvciAxIHNlY29uZCBtYXkgaGVscHMgdGhlIGNvbXB1dGVyIGlzIG5vdCBsb3cgb24gZW50cm9weSAodGhpcyBtZXRob2QgbWF5IGJlIGNhbGxlZCBiYWNrLXRvLWJhY2spLlxuICAgICAgICBoYXNoX2FycmF5LnB1c2goc2VjdXJlUmFuZG9tLnJhbmRvbUJ1ZmZlcigzMikpO1xuXG4gICAgICAgIHJldHVybiBoYXNoLnNoYTI1NihCdWZmZXIuY29uY2F0KGhhc2hfYXJyYXkpKTtcbiAgICB9LFxuXG5cbiAgICBzdWdnZXN0X2JyYWluX2tleTogZnVuY3Rpb24gc3VnZ2VzdF9icmFpbl9rZXkoKSB7XG4gICAgICAgIHZhciBkaWN0aW9uYXJ5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBcIixcIjtcbiAgICAgICAgdmFyIGVudHJvcHkgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHRoaXMuYnJvd3NlckVudHJvcHkoKTtcblxuXG4gICAgICAgIHZhciByYW5kb21CdWZmZXIgPSB0aGlzLnJhbmRvbTMyQnl0ZUJ1ZmZlcihlbnRyb3B5KTtcblxuICAgICAgICB2YXIgd29yZF9jb3VudCA9IDE2O1xuICAgICAgICB2YXIgZGljdGlvbmFyeV9saW5lcyA9IGRpY3Rpb25hcnkuc3BsaXQoJywnKTtcblxuICAgICAgICBpZiAoIShkaWN0aW9uYXJ5X2xpbmVzLmxlbmd0aCA9PT0gNDk3NDQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGluZyAnICsgNDk3NDQgKyAnIGJ1dCBnb3QgJyArIGRpY3Rpb25hcnlfbGluZXMubGVuZ3RoICsgJyBkaWN0aW9uYXJ5IHdvcmRzJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgYnJhaW5rZXkgPSBbXTtcbiAgICAgICAgdmFyIGVuZCA9IHdvcmRfY291bnQgKiAyO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5kOyBpICs9IDIpIHtcblxuICAgICAgICAgICAgLy8gcmFuZG9tQnVmZmVyIGhhcyAyNTYgYml0cyAvIDE2IGJpdHMgcGVyIHdvcmQgPT0gMTYgd29yZHNcbiAgICAgICAgICAgIHZhciBudW0gPSAocmFuZG9tQnVmZmVyW2ldIDw8IDgpICsgcmFuZG9tQnVmZmVyW2kgKyAxXTtcblxuICAgICAgICAgICAgLy8gY29udmVydCBpbnRvIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMSAoaW5jbHVzaXZlKVxuICAgICAgICAgICAgdmFyIHJuZE11bHRpcGxpZXIgPSBudW0gLyBNYXRoLnBvdygyLCAxNik7XG4gICAgICAgICAgICB2YXIgd29yZEluZGV4ID0gTWF0aC5yb3VuZChkaWN0aW9uYXJ5X2xpbmVzLmxlbmd0aCAqIHJuZE11bHRpcGxpZXIpO1xuXG4gICAgICAgICAgICBicmFpbmtleS5wdXNoKGRpY3Rpb25hcnlfbGluZXNbd29yZEluZGV4XSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMubm9ybWFsaXplX2JyYWluS2V5KGJyYWlua2V5LmpvaW4oJyAnKSk7XG4gICAgfSxcblxuICAgIGdldF9yYW5kb21fa2V5OiBmdW5jdGlvbiBnZXRfcmFuZG9tX2tleShlbnRyb3B5KSB7XG4gICAgICAgIHJldHVybiBQcml2YXRlS2V5LmZyb21CdWZmZXIodGhpcy5yYW5kb20zMkJ5dGVCdWZmZXIoZW50cm9weSkpO1xuICAgIH0sXG4gICAgZ2V0X2JyYWluUHJpdmF0ZUtleTogZnVuY3Rpb24gZ2V0X2JyYWluUHJpdmF0ZUtleShicmFpbktleSkge1xuICAgICAgICB2YXIgc2VxdWVuY2UgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDA7XG5cbiAgICAgICAgaWYgKHNlcXVlbmNlIDwgMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBzZXF1ZW5jZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBicmFpbktleSA9IGtleS5ub3JtYWxpemVfYnJhaW5LZXkoYnJhaW5LZXkpO1xuICAgICAgICByZXR1cm4gUHJpdmF0ZUtleS5mcm9tQnVmZmVyKGhhc2guc2hhMjU2KGhhc2guc2hhNTEyKGJyYWluS2V5ICsgXCIgXCIgKyBzZXF1ZW5jZSkpKTtcbiAgICB9LFxuXG5cbiAgICAvLyBUdXJuIGludmlzaWJsZSBzcGFjZSBsaWtlIGNoYXJhY3RlcnMgaW50byBhIHNpbmdsZSBzcGFjZVxuICAgIG5vcm1hbGl6ZV9icmFpbktleTogZnVuY3Rpb24gbm9ybWFsaXplX2JyYWluS2V5KGJyYWluS2V5KSB7XG4gICAgICAgIGlmICghKHR5cGVvZiBicmFpbktleSA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzdHJpbmcgcmVxdWlyZWQgZm9yIGJyYWluS2V5XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJhaW5LZXkgPSBicmFpbktleS50cmltKCk7XG4gICAgICAgIHJldHVybiBicmFpbktleS5zcGxpdCgvW1xcdFxcblxcdlxcZlxcciBdKy8pLmpvaW4oJyAnKTtcbiAgICB9LFxuICAgIGJyb3dzZXJFbnRyb3B5OiBmdW5jdGlvbiBicm93c2VyRW50cm9weSgpIHtcblxuICAgICAgICB2YXIgZW50cm9weVN0ciA9IFwiXCI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBlbnRyb3B5U3RyID0gbmV3IERhdGUoKS50b1N0cmluZygpICsgXCIgXCIgKyB3aW5kb3cuc2NyZWVuLmhlaWdodCArIFwiIFwiICsgd2luZG93LnNjcmVlbi53aWR0aCArIFwiIFwiICsgd2luZG93LnNjcmVlbi5jb2xvckRlcHRoICsgXCIgXCIgKyBcIiBcIiArIHdpbmRvdy5zY3JlZW4uYXZhaWxIZWlnaHQgKyBcIiBcIiArIHdpbmRvdy5zY3JlZW4uYXZhaWxXaWR0aCArIFwiIFwiICsgd2luZG93LnNjcmVlbi5waXhlbERlcHRoICsgbmF2aWdhdG9yLmxhbmd1YWdlICsgXCIgXCIgKyB3aW5kb3cubG9jYXRpb24gKyBcIiBcIiArIHdpbmRvdy5oaXN0b3J5Lmxlbmd0aDtcblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIG1pbWVUeXBlOyBpIDwgbmF2aWdhdG9yLm1pbWVUeXBlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIG1pbWVUeXBlID0gbmF2aWdhdG9yLm1pbWVUeXBlc1tpXTtcbiAgICAgICAgICAgICAgICBlbnRyb3B5U3RyICs9IG1pbWVUeXBlLmRlc2NyaXB0aW9uICsgXCIgXCIgKyBtaW1lVHlwZS50eXBlICsgXCIgXCIgKyBtaW1lVHlwZS5zdWZmaXhlcyArIFwiIFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5sb2coXCJJTkZPXFx0YnJvd3NlckVudHJvcHkgZ2F0aGVyZWRcIik7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAvL25vZGVqczpSZWZlcmVuY2VFcnJvcjogd2luZG93IGlzIG5vdCBkZWZpbmVkXG4gICAgICAgICAgICBlbnRyb3B5U3RyID0gaGFzaC5zaGEyNTYobmV3IERhdGUoKS50b1N0cmluZygpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBiID0gbmV3IEJ1ZmZlcihlbnRyb3B5U3RyKTtcbiAgICAgICAgZW50cm9weVN0ciArPSBiLnRvU3RyaW5nKCdiaW5hcnknKSArIFwiIFwiICsgbmV3IERhdGUoKS50b1N0cmluZygpO1xuICAgICAgICByZXR1cm4gZW50cm9weVN0cjtcbiAgICB9LFxuXG5cbiAgICAvLyBAcmV0dXJuIGFycmF5IG9mIDUgbGVnYWN5IGFkZHJlc3NlcyBmb3IgYSBwdWJrZXkgc3RyaW5nIHBhcmFtZXRlci5cbiAgICBhZGRyZXNzZXM6IGZ1bmN0aW9uIGFkZHJlc3NlcyhwdWJrZXkpIHtcbiAgICAgICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBDaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgICAgICB2YXIgcHVibGljX2tleSA9IFB1YmxpY0tleS5mcm9tUHVibGljS2V5U3RyaW5nKHB1YmtleSwgYWRkcmVzc19wcmVmaXgpO1xuICAgICAgICAvLyBTIEwgTyBXXG4gICAgICAgIHZhciBhZGRyZXNzX3N0cmluZyA9IFtBZGRyZXNzLmZyb21QdWJsaWMocHVibGljX2tleSwgZmFsc2UsIDApLnRvU3RyaW5nKGFkZHJlc3NfcHJlZml4KSwgLy8gYnRjX3VuY29tcHJlc3NlZFxuICAgICAgICBBZGRyZXNzLmZyb21QdWJsaWMocHVibGljX2tleSwgdHJ1ZSwgMCkudG9TdHJpbmcoYWRkcmVzc19wcmVmaXgpLCAvLyBidGNfY29tcHJlc3NlZFxuICAgICAgICBBZGRyZXNzLmZyb21QdWJsaWMocHVibGljX2tleSwgZmFsc2UsIDU2KS50b1N0cmluZyhhZGRyZXNzX3ByZWZpeCksIC8vIHB0c191bmNvbXByZXNzZWRcbiAgICAgICAgQWRkcmVzcy5mcm9tUHVibGljKHB1YmxpY19rZXksIHRydWUsIDU2KS50b1N0cmluZyhhZGRyZXNzX3ByZWZpeCksIC8vIHB0c19jb21wcmVzc2VkXG4gICAgICAgIHB1YmxpY19rZXkudG9BZGRyZXNzU3RyaW5nKGFkZHJlc3NfcHJlZml4KSAvLyBidHNfc2hvcnQsIG1vc3QgcmVjZW50IGZvcm1hdFxuICAgICAgICBdO1xuICAgICAgICByZXR1cm4gYWRkcmVzc19zdHJpbmc7XG4gICAgfVxufTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBlY3VydmUgPSByZXF1aXJlKCdlY3VydmUnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnZWN1cnZlJyksXG4gICAgUG9pbnQgPSBfcmVxdWlyZS5Qb2ludCxcbiAgICBnZXRDdXJ2ZUJ5TmFtZSA9IF9yZXF1aXJlLmdldEN1cnZlQnlOYW1lO1xuXG52YXIgc2VjcDI1NmsxID0gZ2V0Q3VydmVCeU5hbWUoJ3NlY3AyNTZrMScpO1xudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCdiaWdpJyk7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdiczU4JyksXG4gICAgZW5jb2RlID0gX3JlcXVpcmUyLmVuY29kZSxcbiAgICBkZWNvZGUgPSBfcmVxdWlyZTIuZGVjb2RlO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG52YXIgaGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpO1xudmFyIFB1YmxpY0tleSA9IHJlcXVpcmUoJy4vUHVibGljS2V5Jyk7XG52YXIgZGVlcEVxdWFsID0gcmVxdWlyZShcImRlZXAtZXF1YWxcIik7XG5cbnZhciBHID0gc2VjcDI1NmsxLkcsXG4gICAgbiA9IHNlY3AyNTZrMS5uO1xuXG52YXIgUHJpdmF0ZUtleSA9IGZ1bmN0aW9uICgpIHtcblxuICAgIC8qKlxuICAgICAgICBAcHJpdmF0ZSBzZWUgc3RhdGljIGZ1bmN0aW9uc1xuICAgICAgICBAcGFyYW0ge0JpZ0ludGVnZXJ9XG4gICAgKi9cbiAgICBmdW5jdGlvbiBQcml2YXRlS2V5KGQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFByaXZhdGVLZXkpO1xuXG4gICAgICAgIHRoaXMuZCA9IGQ7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNsYXNzKFByaXZhdGVLZXksIFt7XG4gICAgICAgIGtleTogJ3RvV2lmJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvV2lmKCkge1xuICAgICAgICAgICAgdmFyIHByaXZhdGVfa2V5ID0gdGhpcy50b0J1ZmZlcigpO1xuICAgICAgICAgICAgLy8gY2hlY2tzdW0gaW5jbHVkZXMgdGhlIHZlcnNpb25cbiAgICAgICAgICAgIHByaXZhdGVfa2V5ID0gQnVmZmVyLmNvbmNhdChbbmV3IEJ1ZmZlcihbMHg4MF0pLCBwcml2YXRlX2tleV0pO1xuICAgICAgICAgICAgdmFyIGNoZWNrc3VtID0gaGFzaC5zaGEyNTYocHJpdmF0ZV9rZXkpO1xuICAgICAgICAgICAgY2hlY2tzdW0gPSBoYXNoLnNoYTI1NihjaGVja3N1bSk7XG4gICAgICAgICAgICBjaGVja3N1bSA9IGNoZWNrc3VtLnNsaWNlKDAsIDQpO1xuICAgICAgICAgICAgdmFyIHByaXZhdGVfd2lmID0gQnVmZmVyLmNvbmNhdChbcHJpdmF0ZV9rZXksIGNoZWNrc3VtXSk7XG4gICAgICAgICAgICByZXR1cm4gZW5jb2RlKHByaXZhdGVfd2lmKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgICAgQHJldHVybiB7UG9pbnR9XG4gICAgICAgICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3RvUHVibGljS2V5UG9pbnQnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdG9QdWJsaWNLZXlQb2ludCgpIHtcbiAgICAgICAgICAgIHZhciBRO1xuICAgICAgICAgICAgcmV0dXJuIFEgPSBzZWNwMjU2azEuRy5tdWx0aXBseSh0aGlzLmQpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICd0b1B1YmxpY0tleScsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiB0b1B1YmxpY0tleSgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnB1YmxpY19rZXkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wdWJsaWNfa2V5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHVibGljX2tleSA9IFB1YmxpY0tleS5mcm9tUG9pbnQodGhpcy50b1B1YmxpY0tleVBvaW50KCkpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICd0b0J1ZmZlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiB0b0J1ZmZlcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmQudG9CdWZmZXIoMzIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqIEVDSUVTICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2dldF9zaGFyZWRfc2VjcmV0JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldF9zaGFyZWRfc2VjcmV0KHB1YmxpY19rZXkpIHtcbiAgICAgICAgICAgIHZhciBsZWdhY3kgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IGZhbHNlO1xuXG4gICAgICAgICAgICBwdWJsaWNfa2V5ID0gdG9QdWJsaWMocHVibGljX2tleSk7XG4gICAgICAgICAgICB2YXIgS0IgPSBwdWJsaWNfa2V5LnRvVW5jb21wcmVzc2VkKCkudG9CdWZmZXIoKTtcbiAgICAgICAgICAgIHZhciBLQlAgPSBQb2ludC5mcm9tQWZmaW5lKHNlY3AyNTZrMSwgQmlnSW50ZWdlci5mcm9tQnVmZmVyKEtCLnNsaWNlKDEsIDMzKSksIC8vIHhcbiAgICAgICAgICAgIEJpZ0ludGVnZXIuZnJvbUJ1ZmZlcihLQi5zbGljZSgzMywgNjUpKSAvLyB5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdmFyIHIgPSB0aGlzLnRvQnVmZmVyKCk7XG4gICAgICAgICAgICB2YXIgUCA9IEtCUC5tdWx0aXBseShCaWdJbnRlZ2VyLmZyb21CdWZmZXIocikpO1xuICAgICAgICAgICAgdmFyIFMgPSBQLmFmZmluZVgudG9CdWZmZXIoeyBzaXplOiAzMiB9KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICB0aGUgaW5wdXQgdG8gc2hhNTEyIG11c3QgYmUgZXhhY3RseSAzMi1ieXRlcywgdG8gbWF0Y2ggdGhlIGMrKyBpbXBsZW1lbnRhdGlvblxuICAgICAgICAgICAgb2YgZ2V0X3NoYXJlZF9zZWNyZXQuICBSaWdodCBub3cgUyB3aWxsIGJlIHNob3J0ZXIgaWYgdGhlIG1vc3Qgc2lnbmlmaWNhbnRcbiAgICAgICAgICAgIGJ5dGUocykgaXMgemVyby4gIFBhZCBpdCBiYWNrIHRvIHRoZSBmdWxsIDMyLWJ5dGVzXG4gICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKCFsZWdhY3kgJiYgUy5sZW5ndGggPCAzMikge1xuICAgICAgICAgICAgICAgIHBhZCA9IG5ldyBCdWZmZXIoMzIgLSBTLmxlbmd0aCkuZmlsbCgwKTtcbiAgICAgICAgICAgICAgICBTID0gQnVmZmVyLmNvbmNhdChbcGFkLCBTXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNIQTUxMiB1c2VkIGluIEVDSUVTXG4gICAgICAgICAgICByZXR1cm4gaGFzaC5zaGE1MTIoUyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAvKiogRUNJRVMgKGRvZXMgbm90IGFsd2F5cyBtYXRjaCB0aGUgUG9pbnQuZnJvbUFmZmluZSB2ZXJzaW9uIGFib3ZlKSAqL1xuICAgICAgICAvLyBnZXRfc2hhcmVkX3NlY3JldChwdWJsaWNfa2V5KXtcbiAgICAgICAgLy8gICAgIHB1YmxpY19rZXkgPSB0b1B1YmxpYyhwdWJsaWNfa2V5KVxuICAgICAgICAvLyAgICAgdmFyIFAgPSBwdWJsaWNfa2V5LlEubXVsdGlwbHkoIHRoaXMuZCApO1xuICAgICAgICAvLyAgICAgdmFyIFMgPSBQLmFmZmluZVgudG9CdWZmZXIoe3NpemU6IDMyfSk7XG4gICAgICAgIC8vICAgICAvLyBFQ0lFUywgYWRkcyBhbiBleHRyYSBzaGE1MTJcbiAgICAgICAgLy8gICAgIHJldHVybiBoYXNoLnNoYTUxMihTKTtcbiAgICAgICAgLy8gfVxuXG4gICAgICAgIC8qKiBAdGhyb3dzIHtFcnJvcn0gLSBvdmVyZmxvdyBvZiB0aGUga2V5IGNvdWxkIG5vdCBiZSBkZXJpdmVkICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2NoaWxkJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNoaWxkKG9mZnNldCkge1xuICAgICAgICAgICAgb2Zmc2V0ID0gQnVmZmVyLmNvbmNhdChbdGhpcy50b1B1YmxpY0tleSgpLnRvQnVmZmVyKCksIG9mZnNldF0pO1xuICAgICAgICAgICAgb2Zmc2V0ID0gaGFzaC5zaGEyNTYob2Zmc2V0KTtcbiAgICAgICAgICAgIHZhciBjID0gQmlnSW50ZWdlci5mcm9tQnVmZmVyKG9mZnNldCk7XG5cbiAgICAgICAgICAgIGlmIChjLmNvbXBhcmVUbyhuKSA+PSAwKSB0aHJvdyBuZXcgRXJyb3IoXCJDaGlsZCBvZmZzZXQgd2VudCBvdXQgb2YgYm91bmRzLCB0cnkgYWdhaW5cIik7XG5cbiAgICAgICAgICAgIHZhciBkZXJpdmVkID0gdGhpcy5kLmFkZChjKTsgLy8ubW9kKG4pXG5cbiAgICAgICAgICAgIGlmIChkZXJpdmVkLnNpZ251bSgpID09PSAwKSB0aHJvdyBuZXcgRXJyb3IoXCJDaGlsZCBvZmZzZXQgZGVyaXZlZCB0byBhbiBpbnZhbGlkIGtleSwgdHJ5IGFnYWluXCIpO1xuXG4gICAgICAgICAgICByZXR1cm4gbmV3IFByaXZhdGVLZXkoZGVyaXZlZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiA8aGVscGVyX2Z1bmN0aW9ucz4gKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndG9CeXRlQnVmZmVyJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvQnl0ZUJ1ZmZlcigpIHtcbiAgICAgICAgICAgIHZhciBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgICAgICAgICAgdGhpcy5hcHBlbmRCeXRlQnVmZmVyKGIpO1xuICAgICAgICAgICAgcmV0dXJuIGIuY29weSgwLCBiLm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3RvSGV4JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvSGV4KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9CdWZmZXIoKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiA8L2hlbHBlcl9mdW5jdGlvbnM+ICovXG5cbiAgICB9XSwgW3tcbiAgICAgICAga2V5OiAnZnJvbUJ1ZmZlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tQnVmZmVyKGJ1Zikge1xuICAgICAgICAgICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGluZyBwYXJhbXRlciB0byBiZSBhIEJ1ZmZlciB0eXBlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKDMyICE9PSBidWYubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1dBUk46IEV4cGVjdGluZyAzMiBieXRlcywgaW5zdGVhZCBnb3QgJyArIGJ1Zi5sZW5ndGggKyAnLCBzdGFjayB0cmFjZTonLCBuZXcgRXJyb3IoKS5zdGFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYnVmLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVtcHR5IGJ1ZmZlclwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJpdmF0ZUtleShCaWdJbnRlZ2VyLmZyb21CdWZmZXIoYnVmKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogQGFyZyB7c3RyaW5nfSBzZWVkIC0gYW55IGxlbmd0aCBzdHJpbmcuICBUaGlzIGlzIHByaXZhdGUsIHRoZSBzYW1lIHNlZWQgcHJvZHVjZXMgdGhlIHNhbWUgcHJpdmF0ZSBrZXkgZXZlcnkgdGltZS4gICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2Zyb21TZWVkJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21TZWVkKHNlZWQpIHtcbiAgICAgICAgICAgIC8vIGdlbmVyYXRlX3ByaXZhdGVfa2V5XG4gICAgICAgICAgICBpZiAoISh0eXBlb2Ygc2VlZCA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzZWVkIG11c3QgYmUgb2YgdHlwZSBzdHJpbmcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBQcml2YXRlS2V5LmZyb21CdWZmZXIoaGFzaC5zaGEyNTYoc2VlZCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqIEByZXR1cm4ge3N0cmluZ30gV2FsbGV0IEltcG9ydCBGb3JtYXQgKHN0aWxsIGEgc2VjcmV0LCBOb3QgZW5jcnlwdGVkKSAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICdmcm9tV2lmJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21XaWYoX3ByaXZhdGVfd2lmKSB7XG4gICAgICAgICAgICB2YXIgcHJpdmF0ZV93aWYgPSBuZXcgQnVmZmVyKGRlY29kZShfcHJpdmF0ZV93aWYpKTtcbiAgICAgICAgICAgIHZhciB2ZXJzaW9uID0gcHJpdmF0ZV93aWYucmVhZFVJbnQ4KDApO1xuICAgICAgICAgICAgYXNzZXJ0LmVxdWFsKDB4ODAsIHZlcnNpb24sICdFeHBlY3RlZCB2ZXJzaW9uICcgKyAweDgwICsgJywgaW5zdGVhZCBnb3QgJyArIHZlcnNpb24pO1xuICAgICAgICAgICAgLy8gY2hlY2tzdW0gaW5jbHVkZXMgdGhlIHZlcnNpb25cbiAgICAgICAgICAgIHZhciBwcml2YXRlX2tleSA9IHByaXZhdGVfd2lmLnNsaWNlKDAsIC00KTtcbiAgICAgICAgICAgIHZhciBjaGVja3N1bSA9IHByaXZhdGVfd2lmLnNsaWNlKC00KTtcbiAgICAgICAgICAgIHZhciBuZXdfY2hlY2tzdW0gPSBoYXNoLnNoYTI1Nihwcml2YXRlX2tleSk7XG4gICAgICAgICAgICBuZXdfY2hlY2tzdW0gPSBoYXNoLnNoYTI1NihuZXdfY2hlY2tzdW0pO1xuICAgICAgICAgICAgbmV3X2NoZWNrc3VtID0gbmV3X2NoZWNrc3VtLnNsaWNlKDAsIDQpO1xuICAgICAgICAgICAgdmFyIGlzRXF1YWwgPSBkZWVwRXF1YWwoY2hlY2tzdW0sIG5ld19jaGVja3N1bSk7IC8vLCAnSW52YWxpZCBjaGVja3N1bSdcbiAgICAgICAgICAgIGlmICghaXNFcXVhbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNoZWNrc3VtIGRpZCBub3QgbWF0Y2hcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwcml2YXRlX2tleSA9IHByaXZhdGVfa2V5LnNsaWNlKDEpO1xuICAgICAgICAgICAgcHJpdmF0ZV9rZXkgPSBwcml2YXRlX2tleS5zbGljZSgwLCAzMik7XG4gICAgICAgICAgICByZXR1cm4gUHJpdmF0ZUtleS5mcm9tQnVmZmVyKHByaXZhdGVfa2V5KTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZnJvbUhleCcsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tSGV4KGhleCkge1xuICAgICAgICAgICAgcmV0dXJuIFByaXZhdGVLZXkuZnJvbUJ1ZmZlcihuZXcgQnVmZmVyKGhleCwgJ2hleCcpKTtcbiAgICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBQcml2YXRlS2V5O1xufSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByaXZhdGVLZXk7XG5cbnZhciB0b1B1YmxpYyA9IGZ1bmN0aW9uIHRvUHVibGljKGRhdGEpIHtcbiAgICByZXR1cm4gZGF0YSA9PSBudWxsID8gZGF0YSA6IGRhdGEuUSA/IGRhdGEgOiBQdWJsaWNLZXkuZnJvbVN0cmluZ09yVGhyb3coZGF0YSk7XG59OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCdiaWdpJyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ2VjdXJ2ZScpLFxuICAgIFBvaW50ID0gX3JlcXVpcmUuUG9pbnQsXG4gICAgZ2V0Q3VydmVCeU5hbWUgPSBfcmVxdWlyZS5nZXRDdXJ2ZUJ5TmFtZTtcblxudmFyIHNlY3AyNTZrMSA9IGdldEN1cnZlQnlOYW1lKCdzZWNwMjU2azEnKTtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ2JzNTgnKSxcbiAgICBlbmNvZGUgPSBfcmVxdWlyZTIuZW5jb2RlLFxuICAgIGRlY29kZSA9IF9yZXF1aXJlMi5kZWNvZGU7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbnZhciBfcmVxdWlyZTMgPSByZXF1aXJlKCdwZWVycGxheXNqcy13cycpLFxuICAgIENoYWluQ29uZmlnID0gX3JlcXVpcmUzLkNoYWluQ29uZmlnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG52YXIgZGVlcEVxdWFsID0gcmVxdWlyZShcImRlZXAtZXF1YWxcIik7XG5cbnZhciBHID0gc2VjcDI1NmsxLkcsXG4gICAgbiA9IHNlY3AyNTZrMS5uO1xuXG52YXIgUHVibGljS2V5ID0gZnVuY3Rpb24gKCkge1xuXG4gICAgLyoqIEBwYXJhbSB7UG9pbnR9IHB1YmxpYyBrZXkgKi9cbiAgICBmdW5jdGlvbiBQdWJsaWNLZXkoUSkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUHVibGljS2V5KTtcblxuICAgICAgICB0aGlzLlEgPSBRO1xuICAgIH1cblxuICAgIF9jcmVhdGVDbGFzcyhQdWJsaWNLZXksIFt7XG4gICAgICAgIGtleTogJ3RvQnVmZmVyJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvQnVmZmVyKCkge1xuICAgICAgICAgICAgdmFyIGNvbXByZXNzZWQgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRoaXMuUSA/IHRoaXMuUS5jb21wcmVzc2VkIDogbnVsbDtcblxuICAgICAgICAgICAgaWYgKHRoaXMuUSA9PT0gbnVsbCkgcmV0dXJuIG5ldyBCdWZmZXIoJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsICdoZXgnKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLlEuZ2V0RW5jb2RlZChjb21wcmVzc2VkKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndG9VbmNvbXByZXNzZWQnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdG9VbmNvbXByZXNzZWQoKSB7XG4gICAgICAgICAgICB2YXIgYnVmID0gdGhpcy5RLmdldEVuY29kZWQoZmFsc2UpO1xuICAgICAgICAgICAgdmFyIHBvaW50ID0gUG9pbnQuZGVjb2RlRnJvbShzZWNwMjU2azEsIGJ1Zik7XG4gICAgICAgICAgICByZXR1cm4gUHVibGljS2V5LmZyb21Qb2ludChwb2ludCk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogYnRzOjpibG9ja2NoYWluOjphZGRyZXNzICh1bmlxdWUgYnV0IG5vdCBhIGZ1bGwgcHVibGljIGtleSkgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndG9CbG9ja2NoYWluQWRkcmVzcycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiB0b0Jsb2NrY2hhaW5BZGRyZXNzKCkge1xuICAgICAgICAgICAgdmFyIHB1Yl9idWYgPSB0aGlzLnRvQnVmZmVyKCk7XG4gICAgICAgICAgICB2YXIgcHViX3NoYSA9IGhhc2guc2hhNTEyKHB1Yl9idWYpO1xuICAgICAgICAgICAgcmV0dXJuIGhhc2gucmlwZW1kMTYwKHB1Yl9zaGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqIEFsaWFzIGZvciB7QGxpbmsgdG9QdWJsaWNLZXlTdHJpbmd9ICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3RvU3RyaW5nJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBDaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9QdWJsaWNLZXlTdHJpbmcoYWRkcmVzc19wcmVmaXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAgICBGdWxsIHB1YmxpYyBrZXlcbiAgICAgICAgICAgIHtyZXR1cm59IHN0cmluZ1xuICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICd0b1B1YmxpY0tleVN0cmluZycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiB0b1B1YmxpY0tleVN0cmluZygpIHtcbiAgICAgICAgICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICAgICAgICAgIHZhciBwdWJfYnVmID0gdGhpcy50b0J1ZmZlcigpO1xuICAgICAgICAgICAgdmFyIGNoZWNrc3VtID0gaGFzaC5yaXBlbWQxNjAocHViX2J1Zik7XG4gICAgICAgICAgICAvLyBTbGljZSBmcm9tIHRoZSBidWZmZXIgZGlyZWN0bHksIHNsaWNpbmcgZnJvbSB0aGUgY2hlY2tzdW0gVWludDhhcnJheSB3aWxsIHJldHVybiB0aGUgZW50aXJlIGFycmF5IGVhY2ggdGltZS5cbiAgICAgICAgICAgIHZhciBzbGljZWQgPSBuZXcgVWludDhBcnJheShjaGVja3N1bS5idWZmZXIuc2xpY2UoMCwgNCkpO1xuXG4gICAgICAgICAgICAvLyBjb25jYXQgb25seSBhY2NlcHRzIGJ1ZmZlcnMgc28gaW5pdGlhbGl6ZSB0aGUgc2xpY2VkIFVpbnQ4YXJyYXkgYXMgYSBCdWZmZXIuXG4gICAgICAgICAgICB2YXIgYWRkeSA9IEJ1ZmZlci5jb25jYXQoW3B1Yl9idWYsIEJ1ZmZlci5mcm9tKHNsaWNlZCldKTtcbiAgICAgICAgICAgIHJldHVybiBhZGRyZXNzX3ByZWZpeCArIGVuY29kZShhZGR5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgICAgQGFyZyB7c3RyaW5nfSBwdWJsaWNfa2V5IC0gbGlrZSBHUEhYeXouLi5cbiAgICAgICAgICAgIEBhcmcge3N0cmluZ30gYWRkcmVzc19wcmVmaXggLSBsaWtlIEdQSFxuICAgICAgICAgICAgQHJldHVybiBQdWJsaWNLZXkgb3IgYG51bGxgIChpZiB0aGUgcHVibGljX2tleSBzdHJpbmcgaXMgaW52YWxpZClcbiAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndG9BZGRyZXNzU3RyaW5nJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvQWRkcmVzc1N0cmluZygpIHtcbiAgICAgICAgICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICAgICAgICAgIHZhciBwdWJfYnVmID0gdGhpcy50b0J1ZmZlcigpO1xuICAgICAgICAgICAgdmFyIHB1Yl9zaGEgPSBoYXNoLnNoYTUxMihwdWJfYnVmKTtcbiAgICAgICAgICAgIHZhciBhZGR5ID0gaGFzaC5yaXBlbWQxNjAocHViX3NoYSk7XG4gICAgICAgICAgICB2YXIgY2hlY2tzdW0gPSBoYXNoLnJpcGVtZDE2MChhZGR5KTtcbiAgICAgICAgICAgIGFkZHkgPSBCdWZmZXIuY29uY2F0KFthZGR5LCBjaGVja3N1bS5zbGljZSgwLCA0KV0pO1xuICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3NfcHJlZml4ICsgZW5jb2RlKGFkZHkpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICd0b1B0c0FkZHknLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdG9QdHNBZGR5KCkge1xuICAgICAgICAgICAgdmFyIHB1Yl9idWYgPSB0aGlzLnRvQnVmZmVyKCk7XG4gICAgICAgICAgICB2YXIgcHViX3NoYSA9IGhhc2guc2hhMjU2KHB1Yl9idWYpO1xuICAgICAgICAgICAgdmFyIGFkZHkgPSBoYXNoLnJpcGVtZDE2MChwdWJfc2hhKTtcbiAgICAgICAgICAgIGFkZHkgPSBCdWZmZXIuY29uY2F0KFtuZXcgQnVmZmVyKFsweDM4XSksIGFkZHldKTsgLy92ZXJzaW9uIDU2KGRlY2ltYWwpXG5cbiAgICAgICAgICAgIHZhciBjaGVja3N1bSA9IGhhc2guc2hhMjU2KGFkZHkpO1xuICAgICAgICAgICAgY2hlY2tzdW0gPSBoYXNoLnNoYTI1NihjaGVja3N1bSk7XG5cbiAgICAgICAgICAgIGFkZHkgPSBCdWZmZXIuY29uY2F0KFthZGR5LCBjaGVja3N1bS5zbGljZSgwLCA0KV0pO1xuICAgICAgICAgICAgcmV0dXJuIGVuY29kZShhZGR5KTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnY2hpbGQnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY2hpbGQob2Zmc2V0KSB7XG5cbiAgICAgICAgICAgIGFzc2VydChCdWZmZXIuaXNCdWZmZXIob2Zmc2V0KSwgXCJCdWZmZXIgcmVxdWlyZWQ6IG9mZnNldFwiKTtcbiAgICAgICAgICAgIGFzc2VydC5lcXVhbChvZmZzZXQubGVuZ3RoLCAzMiwgXCJvZmZzZXQgbGVuZ3RoXCIpO1xuXG4gICAgICAgICAgICBvZmZzZXQgPSBCdWZmZXIuY29uY2F0KFt0aGlzLnRvQnVmZmVyKCksIG9mZnNldF0pO1xuICAgICAgICAgICAgb2Zmc2V0ID0gaGFzaC5zaGEyNTYob2Zmc2V0KTtcblxuICAgICAgICAgICAgdmFyIGMgPSBCaWdJbnRlZ2VyLmZyb21CdWZmZXIob2Zmc2V0KTtcblxuICAgICAgICAgICAgaWYgKGMuY29tcGFyZVRvKG4pID49IDApIHRocm93IG5ldyBFcnJvcihcIkNoaWxkIG9mZnNldCB3ZW50IG91dCBvZiBib3VuZHMsIHRyeSBhZ2FpblwiKTtcblxuICAgICAgICAgICAgdmFyIGNHID0gRy5tdWx0aXBseShjKTtcbiAgICAgICAgICAgIHZhciBRcHJpbWUgPSB0aGlzLlEuYWRkKGNHKTtcblxuICAgICAgICAgICAgaWYgKHNlY3AyNTZrMS5pc0luZmluaXR5KFFwcmltZSkpIHRocm93IG5ldyBFcnJvcihcIkNoaWxkIG9mZnNldCBkZXJpdmVkIHRvIGFuIGludmFsaWQga2V5LCB0cnkgYWdhaW5cIik7XG5cbiAgICAgICAgICAgIHJldHVybiBQdWJsaWNLZXkuZnJvbVBvaW50KFFwcmltZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiA8SEVYPiAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICd0b0J5dGVCdWZmZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdG9CeXRlQnVmZmVyKCkge1xuICAgICAgICAgICAgdmFyIGIgPSBuZXcgQnl0ZUJ1ZmZlcihCeXRlQnVmZmVyLkRFRkFVTFRfQ0FQQUNJVFksIEJ5dGVCdWZmZXIuTElUVExFX0VORElBTik7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZEJ5dGVCdWZmZXIoYik7XG4gICAgICAgICAgICByZXR1cm4gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndG9IZXgnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdG9IZXgoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50b0J1ZmZlcigpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgfVxuICAgIH1dLCBbe1xuICAgICAgICBrZXk6ICdmcm9tQmluYXJ5JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21CaW5hcnkoYmluKSB7XG4gICAgICAgICAgICByZXR1cm4gUHVibGljS2V5LmZyb21CdWZmZXIobmV3IEJ1ZmZlcihiaW4sICdiaW5hcnknKSk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2Zyb21CdWZmZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgICAgIGlmIChidWZmZXIudG9TdHJpbmcoJ2hleCcpID09PSAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJykgcmV0dXJuIG5ldyBQdWJsaWNLZXkobnVsbCk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFB1YmxpY0tleShQb2ludC5kZWNvZGVGcm9tKHNlY3AyNTZrMSwgYnVmZmVyKSk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2Zyb21Qb2ludCcsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tUG9pbnQocG9pbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHVibGljS2V5KHBvaW50KTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZnJvbVB1YmxpY0tleVN0cmluZycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tUHVibGljS2V5U3RyaW5nKHB1YmxpY19rZXkpIHtcbiAgICAgICAgICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tU3RyaW5nT3JUaHJvdyhwdWJsaWNfa2V5LCBhZGRyZXNzX3ByZWZpeCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICAgIEBhcmcge3N0cmluZ30gcHVibGljX2tleSAtIGxpa2UgR1BIWHl6Li4uXG4gICAgICAgICAgICBAYXJnIHtzdHJpbmd9IGFkZHJlc3NfcHJlZml4IC0gbGlrZSBHUEhcbiAgICAgICAgICAgIEB0aHJvd3Mge0Vycm9yfSBpZiBwdWJsaWMga2V5IGlzIGludmFsaWRcbiAgICAgICAgICAgIEByZXR1cm4gUHVibGljS2V5XG4gICAgICAgICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2Zyb21TdHJpbmdPclRocm93JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21TdHJpbmdPclRocm93KHB1YmxpY19rZXkpIHtcbiAgICAgICAgICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICAgICAgICAgIHZhciBwcmVmaXggPSBwdWJsaWNfa2V5LnNsaWNlKDAsIGFkZHJlc3NfcHJlZml4Lmxlbmd0aCk7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwoYWRkcmVzc19wcmVmaXgsIHByZWZpeCwgJ0V4cGVjdGluZyBrZXkgdG8gYmVnaW4gd2l0aCAnICsgYWRkcmVzc19wcmVmaXggKyAnLCBpbnN0ZWFkIGdvdCAnICsgcHJlZml4KTtcbiAgICAgICAgICAgIHB1YmxpY19rZXkgPSBwdWJsaWNfa2V5LnNsaWNlKGFkZHJlc3NfcHJlZml4Lmxlbmd0aCk7XG5cbiAgICAgICAgICAgIHB1YmxpY19rZXkgPSBuZXcgQnVmZmVyKGRlY29kZShwdWJsaWNfa2V5KSwgJ2JpbmFyeScpO1xuICAgICAgICAgICAgdmFyIGNoZWNrc3VtID0gcHVibGljX2tleS5zbGljZSgtNCk7XG4gICAgICAgICAgICBwdWJsaWNfa2V5ID0gcHVibGljX2tleS5zbGljZSgwLCAtNCk7XG4gICAgICAgICAgICB2YXIgbmV3X2NoZWNrc3VtID0gaGFzaC5yaXBlbWQxNjAocHVibGljX2tleSk7XG4gICAgICAgICAgICBuZXdfY2hlY2tzdW0gPSBuZXdfY2hlY2tzdW0uc2xpY2UoMCwgNCk7XG4gICAgICAgICAgICB2YXIgaXNFcXVhbCA9IGRlZXBFcXVhbChjaGVja3N1bSwgbmV3X2NoZWNrc3VtKTsgLy8sICdJbnZhbGlkIGNoZWNrc3VtJ1xuICAgICAgICAgICAgaWYgKCFpc0VxdWFsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2hlY2tzdW0gZGlkIG5vdCBtYXRjaFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBQdWJsaWNLZXkuZnJvbUJ1ZmZlcihwdWJsaWNfa2V5KTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZnJvbUhleCcsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tSGV4KGhleCkge1xuICAgICAgICAgICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tQnVmZmVyKG5ldyBCdWZmZXIoaGV4LCAnaGV4JykpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdmcm9tUHVibGljS2V5U3RyaW5nSGV4JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21QdWJsaWNLZXlTdHJpbmdIZXgoaGV4KSB7XG4gICAgICAgICAgICByZXR1cm4gUHVibGljS2V5LmZyb21QdWJsaWNLZXlTdHJpbmcobmV3IEJ1ZmZlcihoZXgsICdoZXgnKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiA8L0hFWD4gKi9cblxuICAgIH1dKTtcblxuICAgIHJldHVybiBQdWJsaWNLZXk7XG59KCk7XG5cbm1vZHVsZS5leHBvcnRzID0gUHVibGljS2V5OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdwZWVycGxheXNqcy13cycpLFxuICAgIENoYWluQ29uZmlnID0gX3JlcXVpcmUuQ2hhaW5Db25maWc7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdiczU4JyksXG4gICAgZW5jb2RlID0gX3JlcXVpcmUyLmVuY29kZSxcbiAgICBkZWNvZGUgPSBfcmVxdWlyZTIuZGVjb2RlO1xuXG52YXIgZGVlcEVxdWFsID0gcmVxdWlyZShcImRlZXAtZXF1YWxcIik7XG5cbi8qKiBBZGRyZXNzZXMgYXJlIHNob3J0ZW5lZCBub24tcmV2ZXJzYWJsZSBoYXNoZXMgb2YgYSBwdWJsaWMga2V5LiAgVGhlIGZ1bGwgUHVibGljS2V5IGlzIHByZWZlcnJlZC5cbiAgICBAZGVwcmVjYXRlZFxuKi9cblxudmFyIEFkZHJlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQWRkcmVzcyhhZGR5KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBZGRyZXNzKTtcblxuICAgICAgICB0aGlzLmFkZHkgPSBhZGR5O1xuICAgIH1cblxuICAgIF9jcmVhdGVDbGFzcyhBZGRyZXNzLCBbe1xuICAgICAgICBrZXk6ICd0b0J1ZmZlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiB0b0J1ZmZlcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFkZHk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3RvU3RyaW5nJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBDaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgICAgICAgICAgdmFyIGNoZWNrc3VtID0gaGFzaC5yaXBlbWQxNjAodGhpcy5hZGR5KTtcbiAgICAgICAgICAgIHZhciBhZGR5ID0gQnVmZmVyLmNvbmNhdChbdGhpcy5hZGR5LCBjaGVja3N1bS5zbGljZSgwLCA0KV0pO1xuICAgICAgICAgICAgcmV0dXJuIGFkZHJlc3NfcHJlZml4ICsgZW5jb2RlKGFkZHkpO1xuICAgICAgICB9XG4gICAgfV0sIFt7XG4gICAgICAgIGtleTogJ2Zyb21CdWZmZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgICAgIHZhciBfaGFzaCA9IGhhc2guc2hhNTEyKGJ1ZmZlcik7XG4gICAgICAgICAgICB2YXIgYWRkeSA9IGhhc2gucmlwZW1kMTYwKF9oYXNoKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQWRkcmVzcyhhZGR5KTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZnJvbVN0cmluZycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tU3RyaW5nKHN0cmluZykge1xuICAgICAgICAgICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBDaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgICAgICAgICAgdmFyIHByZWZpeCA9IHN0cmluZy5zbGljZSgwLCBhZGRyZXNzX3ByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgYXNzZXJ0LmVxdWFsKGFkZHJlc3NfcHJlZml4LCBwcmVmaXgsICdFeHBlY3Rpbmcga2V5IHRvIGJlZ2luIHdpdGggJyArIGFkZHJlc3NfcHJlZml4ICsgJywgaW5zdGVhZCBnb3QgJyArIHByZWZpeCk7XG4gICAgICAgICAgICB2YXIgYWRkeSA9IHN0cmluZy5zbGljZShhZGRyZXNzX3ByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgYWRkeSA9IG5ldyBCdWZmZXIoZGVjb2RlKGFkZHkpLCAnYmluYXJ5Jyk7XG4gICAgICAgICAgICB2YXIgY2hlY2tzdW0gPSBhZGR5LnNsaWNlKC00KTtcbiAgICAgICAgICAgIGFkZHkgPSBhZGR5LnNsaWNlKDAsIC00KTtcbiAgICAgICAgICAgIHZhciBuZXdfY2hlY2tzdW0gPSBoYXNoLnJpcGVtZDE2MChhZGR5KTtcbiAgICAgICAgICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS5zbGljZSgwLCA0KTtcbiAgICAgICAgICAgIHZhciBpc0VxdWFsID0gZGVlcEVxdWFsKGNoZWNrc3VtLCBuZXdfY2hlY2tzdW0pOyAvLywgJ0ludmFsaWQgY2hlY2tzdW0nXG4gICAgICAgICAgICBpZiAoIWlzRXF1YWwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDaGVja3N1bSBkaWQgbm90IG1hdGNoXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBBZGRyZXNzKGFkZHkpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdmcm9tUHVibGljJyxcblxuXG4gICAgICAgIC8qKiBAcmV0dXJuIEFkZHJlc3MgLSBDb21wcmVzc2VkIFBUUyBmb3JtYXQgKGJ5IGRlZmF1bHQpICovXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tUHVibGljKHB1YmxpY19rZXkpIHtcbiAgICAgICAgICAgIHZhciBjb21wcmVzc2VkID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB0cnVlO1xuICAgICAgICAgICAgdmFyIHZlcnNpb24gPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IDU2O1xuXG4gICAgICAgICAgICB2YXIgc2hhMiA9IGhhc2guc2hhMjU2KHB1YmxpY19rZXkudG9CdWZmZXIoY29tcHJlc3NlZCkpO1xuICAgICAgICAgICAgdmFyIHJlcCA9IGhhc2gucmlwZW1kMTYwKHNoYTIpO1xuICAgICAgICAgICAgdmFyIHZlcnNpb25CdWZmZXIgPSBuZXcgQnVmZmVyKDEpO1xuICAgICAgICAgICAgdmVyc2lvbkJ1ZmZlci53cml0ZVVJbnQ4KDB4RkYgJiB2ZXJzaW9uLCAwKTtcbiAgICAgICAgICAgIHZhciBhZGRyID0gQnVmZmVyLmNvbmNhdChbdmVyc2lvbkJ1ZmZlciwgcmVwXSk7XG4gICAgICAgICAgICB2YXIgY2hlY2sgPSBoYXNoLnNoYTI1NihhZGRyKTtcbiAgICAgICAgICAgIGNoZWNrID0gaGFzaC5zaGEyNTYoY2hlY2spO1xuICAgICAgICAgICAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2FkZHIsIGNoZWNrLnNsaWNlKDAsIDQpXSk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEFkZHJlc3MoaGFzaC5yaXBlbWQxNjAoYnVmZmVyKSk7XG4gICAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gQWRkcmVzcztcbn0oKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBZGRyZXNzOyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG4vLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qc1xudmFyIEFFUyA9IHJlcXVpcmUoXCJjcnlwdG8tanMvYWVzXCIpO1xudmFyIGVuY0hleCA9IHJlcXVpcmUoXCJjcnlwdG8tanMvZW5jLWhleFwiKTtcbnZhciBlbmNCYXNlNjQgPSByZXF1aXJlKFwiY3J5cHRvLWpzL2VuYy1iYXNlNjRcIik7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZShcImFzc2VydFwiKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZShcImJ5dGVidWZmZXJcIiksXG4gICAgTG9uZyA9IF9yZXF1aXJlLkxvbmc7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnLi9oYXNoJyk7XG5cbi8qKiBQcm92aWRlcyBzeW1ldHJpYyBlbmNyeXB0IGFuZCBkZWNyeXB0IHZpYSBBRVMuICovXG5cbnZhciBBZXMgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAvKiogQHByaXZhdGUgKi9cbiAgICBmdW5jdGlvbiBBZXMoaXYsIGtleSkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWVzKTtcblxuICAgICAgICB0aGlzLml2ID0gaXYsIHRoaXMua2V5ID0ga2V5O1xuICAgIH1cblxuICAgIC8qKiBUaGlzIGlzIGFuIGV4Y2VsbGVudCB3YXkgdG8gZW5zdXJlIHRoYXQgYWxsIHJlZmVyZW5jZXMgdG8gQWVzIGNhbiBub3Qgb3BlcmF0ZSBhbnltb3JlIChleGFtcGxlOiBhIHdhbGxldCBiZWNvbWVzIGxvY2tlZCkuICBBbiBhcHBsaWNhdGlvbiBzaG91bGQgZW5zdXJlIHRoZXJlIGlzIG9ubHkgb25lIEFlcyBvYmplY3QgaW5zdGFuY2UgZm9yIGEgZ2l2ZW4gc2VjcmV0IGBzZWVkYC4gKi9cblxuXG4gICAgX2NyZWF0ZUNsYXNzKEFlcywgW3tcbiAgICAgICAga2V5OiBcImNsZWFyXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLml2ID0gdGhpcy5rZXkgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogQGFyZyB7c3RyaW5nfSBzZWVkIC0gc2VjcmV0IHNlZWQgbWF5IGJlIHVzZWQgdG8gZW5jcnlwdCBvciBkZWNyeXB0LiAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6IFwiX2RlY3J5cHRfd29yZF9hcnJheVwiLFxuXG5cbiAgICAgICAgLyoqIEBwcml2YXRlICovXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBfZGVjcnlwdF93b3JkX2FycmF5KGNpcGhlcikge1xuICAgICAgICAgICAgLy8gaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvI0N1c3RvbV9LZXlfYW5kX0lWXG4gICAgICAgICAgICAvLyBzZWUgd2FsbGV0X3JlY29yZHMuY3BwIG1hc3Rlcl9rZXk6OmRlY3J5cHRfa2V5XG4gICAgICAgICAgICByZXR1cm4gQUVTLmRlY3J5cHQoeyBjaXBoZXJ0ZXh0OiBjaXBoZXIsIHNhbHQ6IG51bGwgfSwgdGhpcy5rZXksIHsgaXY6IHRoaXMuaXYgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogQHByaXZhdGUgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcIl9lbmNyeXB0X3dvcmRfYXJyYXlcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9lbmNyeXB0X3dvcmRfYXJyYXkocGxhaW50ZXh0KSB7XG4gICAgICAgICAgICAvL2h0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL2lzc3Vlcy9kZXRhaWw/aWQ9ODVcbiAgICAgICAgICAgIHZhciBjaXBoZXIgPSBBRVMuZW5jcnlwdChwbGFpbnRleHQsIHRoaXMua2V5LCB7IGl2OiB0aGlzLml2IH0pO1xuICAgICAgICAgICAgcmV0dXJuIGVuY0Jhc2U2NC5wYXJzZShjaXBoZXIudG9TdHJpbmcoKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICAgICAgQGFyZyB7c3RyaW5nfSBjaXBoZXJ0ZXh0XG4gICAgICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9IGJpbmFyeVxuICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6IFwiZGVjcnlwdFwiLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZGVjcnlwdChjaXBoZXJ0ZXh0KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0ID0gbmV3IEJ1ZmZlcihjaXBoZXJ0ZXh0LCAnYmluYXJ5Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaXBoZXJ0ZXh0KSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImJ1ZmZlciByZXF1aXJlZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFzc2VydChjaXBoZXJ0ZXh0LCBcIk1pc3NpbmcgY2lwaGVyIHRleHRcIik7XG4gICAgICAgICAgICAvLyBoZXggaXMgdGhlIG9ubHkgY29tbW9uIGZvcm1hdFxuICAgICAgICAgICAgdmFyIGhleCA9IHRoaXMuZGVjcnlwdEhleChjaXBoZXJ0ZXh0LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihoZXgsICdoZXgnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgICAgICBAYXJnIHtzdHJpbmd9IHBsYWludGV4dFxuICAgICAgICAgICAgQHJldHVybiB7QnVmZmVyfSBiaW5hcnlcbiAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcImVuY3J5cHRcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGVuY3J5cHQocGxhaW50ZXh0KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHBsYWludGV4dCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIHBsYWludGV4dCA9IG5ldyBCdWZmZXIocGxhaW50ZXh0LCAnYmluYXJ5Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwbGFpbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYnVmZmVyIHJlcXVpcmVkXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy9hc3NlcnQgcGxhaW50ZXh0LCBcIk1pc3NpbmcgcGxhaW4gdGV4dFwiXG4gICAgICAgICAgICAvLyBoZXggaXMgdGhlIG9ubHkgY29tbW9uIGZvcm1hdFxuICAgICAgICAgICAgdmFyIGhleCA9IHRoaXMuZW5jcnlwdEhleChwbGFpbnRleHQudG9TdHJpbmcoJ2hleCcpKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQnVmZmVyKGhleCwgJ2hleCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHVzZSBhIGNoZWNrc3VtLCB0aGUgcmV0dXJuZWQgZGF0YSBtdXN0IGJlIHZhbGlkYXRlZCBzb21lIG90aGVyIHdheS5cbiAgICAgICAgICAgIEBhcmcge3N0cmluZ3xCdWZmZXJ9IHBsYWludGV4dFxuICAgICAgICAgICAgQHJldHVybiB7c3RyaW5nfSBoZXhcbiAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcImVuY3J5cHRUb0hleFwiLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZW5jcnlwdFRvSGV4KHBsYWludGV4dCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBwbGFpbnRleHQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICBwbGFpbnRleHQgPSBuZXcgQnVmZmVyKHBsYWludGV4dCwgJ2JpbmFyeScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocGxhaW50ZXh0KSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImJ1ZmZlciByZXF1aXJlZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vYXNzZXJ0IHBsYWludGV4dCwgXCJNaXNzaW5nIHBsYWluIHRleHRcIlxuICAgICAgICAgICAgLy8gaGV4IGlzIHRoZSBvbmx5IGNvbW1vbiBmb3JtYXRcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY3J5cHRIZXgocGxhaW50ZXh0LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICAgICAgQGFyZyB7c3RyaW5nfSBjaXBoZXIgLSBoZXhcbiAgICAgICAgICAgIEByZXR1cm4ge3N0cmluZ30gYmluYXJ5IChjb3VsZCBlYXNpbHkgYmUgcmVhZGFibGUgdGV4dClcbiAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcImRlY3J5cHRIZXhcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRlY3J5cHRIZXgoY2lwaGVyKSB7XG4gICAgICAgICAgICBhc3NlcnQoY2lwaGVyLCBcIk1pc3NpbmcgY2lwaGVyIHRleHRcIik7XG4gICAgICAgICAgICAvLyBDb252ZXJ0IGRhdGEgaW50byB3b3JkIGFycmF5cyAodXNlZCBieSBDcnlwdG8pXG4gICAgICAgICAgICB2YXIgY2lwaGVyX2FycmF5ID0gZW5jSGV4LnBhcnNlKGNpcGhlcik7XG4gICAgICAgICAgICB2YXIgcGxhaW53b3JkcyA9IHRoaXMuX2RlY3J5cHRfd29yZF9hcnJheShjaXBoZXJfYXJyYXkpO1xuICAgICAgICAgICAgcmV0dXJuIGVuY0hleC5zdHJpbmdpZnkocGxhaW53b3Jkcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICAgICAgQGFyZyB7c3RyaW5nfSBjaXBoZXIgLSBoZXhcbiAgICAgICAgICAgIEByZXR1cm4ge0J1ZmZlcn0gZW5jb2RlZCBhcyBzcGVjaWZpZWQgYnkgdGhlIHBhcmFtZXRlclxuICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6IFwiZGVjcnlwdEhleFRvQnVmZmVyXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkZWNyeXB0SGV4VG9CdWZmZXIoY2lwaGVyKSB7XG4gICAgICAgICAgICBhc3NlcnQoY2lwaGVyLCBcIk1pc3NpbmcgY2lwaGVyIHRleHRcIik7XG4gICAgICAgICAgICAvLyBDb252ZXJ0IGRhdGEgaW50byB3b3JkIGFycmF5cyAodXNlZCBieSBDcnlwdG8pXG4gICAgICAgICAgICB2YXIgY2lwaGVyX2FycmF5ID0gZW5jSGV4LnBhcnNlKGNpcGhlcik7XG4gICAgICAgICAgICB2YXIgcGxhaW53b3JkcyA9IHRoaXMuX2RlY3J5cHRfd29yZF9hcnJheShjaXBoZXJfYXJyYXkpO1xuICAgICAgICAgICAgdmFyIHBsYWluaGV4ID0gZW5jSGV4LnN0cmluZ2lmeShwbGFpbndvcmRzKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQnVmZmVyKHBsYWluaGV4LCAnaGV4Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICAgICAgQGFyZyB7c3RyaW5nfSBjaXBoZXIgLSBoZXhcbiAgICAgICAgICAgIEBhcmcge3N0cmluZ30gW2VuY29kaW5nID0gJ2JpbmFyeSddIC0gYSB2YWxpZCBCdWZmZXIgZW5jb2RpbmdcbiAgICAgICAgICAgIEByZXR1cm4ge1N0cmluZ30gZW5jb2RlZCBhcyBzcGVjaWZpZWQgYnkgdGhlIHBhcmFtZXRlclxuICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6IFwiZGVjcnlwdEhleFRvVGV4dFwiLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZGVjcnlwdEhleFRvVGV4dChjaXBoZXIpIHtcbiAgICAgICAgICAgIHZhciBlbmNvZGluZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogJ2JpbmFyeSc7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY3J5cHRIZXhUb0J1ZmZlcihjaXBoZXIpLnRvU3RyaW5nKGVuY29kaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgICAgICBAYXJnIHtzdHJpbmd9IHBsYWluaGV4IC0gaGV4IGZvcm1hdFxuICAgICAgICAgICAgQHJldHVybiB7U3RyaW5nfSBoZXhcbiAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcImVuY3J5cHRIZXhcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGVuY3J5cHRIZXgocGxhaW5oZXgpIHtcbiAgICAgICAgICAgIHZhciBwbGFpbl9hcnJheSA9IGVuY0hleC5wYXJzZShwbGFpbmhleCk7XG4gICAgICAgICAgICB2YXIgY2lwaGVyX2FycmF5ID0gdGhpcy5fZW5jcnlwdF93b3JkX2FycmF5KHBsYWluX2FycmF5KTtcbiAgICAgICAgICAgIHJldHVybiBlbmNIZXguc3RyaW5naWZ5KGNpcGhlcl9hcnJheSk7XG4gICAgICAgIH1cbiAgICB9XSwgW3tcbiAgICAgICAga2V5OiBcImZyb21TZWVkXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tU2VlZChzZWVkKSB7XG4gICAgICAgICAgICBpZiAoc2VlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwic2VlZCBpcyByZXF1aXJlZFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBfaGFzaCA9IGhhc2guc2hhNTEyKHNlZWQpO1xuICAgICAgICAgICAgX2hhc2ggPSBfaGFzaC50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgICAgICAvLyBERUJVRyBjb25zb2xlLmxvZygnLi4uIGZyb21TZWVkIF9oYXNoJyxfaGFzaClcbiAgICAgICAgICAgIHJldHVybiBBZXMuZnJvbVNoYTUxMihfaGFzaCk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogXCJmcm9tU2hhNTEyXCIsXG5cblxuICAgICAgICAvKiogQGFyZyB7c3RyaW5nfSBoYXNoIC0gQSAxMjggYnl0ZSBoZXggc3RyaW5nLCB0eXBpY2FsbHkgb25lIHdvdWxkIGNhbGwge0BsaW5rIGZyb21TZWVkfSBpbnN0ZWFkLiAqL1xuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbVNoYTUxMihoYXNoKSB7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwoaGFzaC5sZW5ndGgsIDEyOCwgXCJBIFNoYTUxMiBpbiBIRVggc2hvdWxkIGJlIDEyOCBjaGFyYWN0ZXJzIGxvbmcsIGluc3RlYWQgZ290IFwiICsgaGFzaC5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIGl2ID0gZW5jSGV4LnBhcnNlKGhhc2guc3Vic3RyaW5nKDY0LCA5NikpO1xuICAgICAgICAgICAgdmFyIGtleSA9IGVuY0hleC5wYXJzZShoYXNoLnN1YnN0cmluZygwLCA2NCkpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBBZXMoaXYsIGtleSk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogXCJmcm9tQnVmZmVyXCIsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tQnVmZmVyKGJ1Zikge1xuICAgICAgICAgICAgYXNzZXJ0KEJ1ZmZlci5pc0J1ZmZlcihidWYpLCBcIkV4cGVjdGluZyBCdWZmZXJcIik7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwoYnVmLmxlbmd0aCwgNjQsIFwiQSBTaGE1MTIgQnVmZmVyIHNob3VsZCBiZSA2NCBjaGFyYWN0ZXJzIGxvbmcsIGluc3RlYWQgZ290IFwiICsgYnVmLmxlbmd0aCk7XG4gICAgICAgICAgICByZXR1cm4gQWVzLmZyb21TaGE1MTIoYnVmLnRvU3RyaW5nKFwiaGV4XCIpKTtcbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICAgIEB0aHJvd3Mge0Vycm9yfSAtIFwiSW52YWxpZCBLZXksIC4uLlwiXG4gICAgICAgICAgICBAYXJnIHtQcml2YXRlS2V5fSBwcml2YXRlX2tleSAtIHJlcXVpcmVkIGFuZCB1c2VkIGZvciBkZWNyeXB0aW9uXG4gICAgICAgICAgICBAYXJnIHtQdWJsaWNLZXl9IHB1YmxpY19rZXkgLSByZXF1aXJlZCBhbmQgdXNlZCB0byBjYWxjdWFsdGUgdGhlIHNoYXJlZCBzZWNyZXRcbiAgICAgICAgICAgIEBhcmcge3N0cmluZ30gW25vbmNlID0gXCJcIl0gb3B0aW9uYWwgYnV0IHNob3VsZCBhbHdheXMgYmUgcHJvdmlkZWQgYW5kIGJlIHVuaXF1ZSB3aGVuIHJlLXVzaW5nIHRoZSBzYW1lIHByaXZhdGUvcHVibGljIGtleXMgbW9yZSB0aGFuIG9uY2UuICBUaGlzIG5vbmNlIGlzIG5vdCBhIHNlY3JldC5cbiAgICAgICAgICAgIEBhcmcge3N0cmluZ3xCdWZmZXJ9IG1lc3NhZ2UgLSBFbmNyeXB0ZWQgbWVzc2FnZSBjb250YWluaW5nIGEgY2hlY2tzdW1cbiAgICAgICAgICAgIEByZXR1cm4ge0J1ZmZlcn1cbiAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiBcImRlY3J5cHRfd2l0aF9jaGVja3N1bVwiLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZGVjcnlwdF93aXRoX2NoZWNrc3VtKHByaXZhdGVfa2V5LCBwdWJsaWNfa2V5LCBub25jZSwgbWVzc2FnZSkge1xuICAgICAgICAgICAgdmFyIGxlZ2FjeSA9IGFyZ3VtZW50cy5sZW5ndGggPiA0ICYmIGFyZ3VtZW50c1s0XSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzRdIDogZmFsc2U7XG5cblxuICAgICAgICAgICAgLy8gV2FybmluZzogRG8gbm90IHB1dCBgbm9uY2UgPSBcIlwiYCBpbiB0aGUgYXJndW1lbnRzLCBpbiBlczYgdGhpcyB3aWxsIG5vdCBjb252ZXJ0IFwibnVsbFwiIGludG8gYW4gZW10cHkgc3RyaW5nXG4gICAgICAgICAgICBpZiAobm9uY2UgPT0gbnVsbCkgLy8gbnVsbCBvciB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICBub25jZSA9IFwiXCI7XG5cbiAgICAgICAgICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKG1lc3NhZ2UpKSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBCdWZmZXIobWVzc2FnZSwgJ2hleCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgUyA9IHByaXZhdGVfa2V5LmdldF9zaGFyZWRfc2VjcmV0KHB1YmxpY19rZXksIGxlZ2FjeSk7XG4gICAgICAgICAgICAvLyBEIEUgQiBVIEdcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdkZWNyeXB0X3dpdGhfY2hlY2tzdW0nLCB7XG4gICAgICAgICAgICAvLyAgICAgcHJpdl90b19wdWI6IHByaXZhdGVfa2V5LnRvUHVibGljS2V5KCkudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIC8vICAgICBwdWI6IHB1YmxpY19rZXkudG9QdWJsaWNLZXlTdHJpbmcoKSxcbiAgICAgICAgICAgIC8vICAgICBub25jZTogbm9uY2UsXG4gICAgICAgICAgICAvLyAgICAgbWVzc2FnZTogbWVzc2FnZS5sZW5ndGgsXG4gICAgICAgICAgICAvLyAgICAgUzogUy50b1N0cmluZygnaGV4JylcbiAgICAgICAgICAgIC8vIH0pXG5cbiAgICAgICAgICAgIHZhciBhZXMgPSBBZXMuZnJvbVNlZWQoQnVmZmVyLmNvbmNhdChbXG4gICAgICAgICAgICAvLyBBIG51bGwgb3IgZW1wdHkgc3RyaW5nIG5vbmNlIHdpbGwgbm90IGVmZmVjdCB0aGUgaGFzaFxuICAgICAgICAgICAgbmV3IEJ1ZmZlcihcIlwiICsgbm9uY2UpLCBuZXcgQnVmZmVyKFMudG9TdHJpbmcoJ2hleCcpKV0pKTtcblxuICAgICAgICAgICAgdmFyIHBsYW5lYnVmZmVyID0gYWVzLmRlY3J5cHQobWVzc2FnZSk7XG4gICAgICAgICAgICBpZiAoIShwbGFuZWJ1ZmZlci5sZW5ndGggPj0gNCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGtleSwgY291bGQgbm90IGRlY3J5cHQgbWVzc2FnZSgxKVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiBwbGFuZWJ1ZmZlcicscGxhbmVidWZmZXIpXG4gICAgICAgICAgICB2YXIgY2hlY2tzdW0gPSBwbGFuZWJ1ZmZlci5zbGljZSgwLCA0KTtcbiAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBwbGFuZWJ1ZmZlci5zbGljZSg0KTtcblxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJy4uLiBjaGVja3N1bScsY2hlY2tzdW0udG9TdHJpbmcoJ2hleCcpKVxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJy4uLiBwbGFpbnRleHQnLHBsYWludGV4dC50b1N0cmluZygpKVxuXG4gICAgICAgICAgICB2YXIgbmV3X2NoZWNrc3VtID0gaGFzaC5zaGEyNTYocGxhaW50ZXh0KTtcbiAgICAgICAgICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS5zbGljZSgwLCA0KTtcbiAgICAgICAgICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgICAgIGlmICghKGNoZWNrc3VtLnRvU3RyaW5nKCdoZXgnKSA9PT0gbmV3X2NoZWNrc3VtKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQga2V5LCBjb3VsZCBub3QgZGVjcnlwdCBtZXNzYWdlKDIpXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcGxhaW50ZXh0O1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6IFwiZW5jcnlwdF93aXRoX2NoZWNrc3VtXCIsXG5cblxuICAgICAgICAvKiogSWRlbnRpY2FsIHRvIHtAbGluayBkZWNyeXB0X3dpdGhfY2hlY2tzdW19IGJ1dCB1c2VkIHRvIGVuY3J5cHQuICBTaG91bGQgbm90IHRocm93IGFuIGVycm9yLlxuICAgICAgICAgICAgQHJldHVybiB7QnVmZmVyfSBtZXNzYWdlIC0gRW5jcnlwdGVkIG1lc3NhZ2Ugd2hpY2ggaW5jbHVkZXMgYSBjaGVja3N1bVxuICAgICAgICAqL1xuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZW5jcnlwdF93aXRoX2NoZWNrc3VtKHByaXZhdGVfa2V5LCBwdWJsaWNfa2V5LCBub25jZSwgbWVzc2FnZSkge1xuXG4gICAgICAgICAgICAvLyBXYXJuaW5nOiBEbyBub3QgcHV0IGBub25jZSA9IFwiXCJgIGluIHRoZSBhcmd1bWVudHMsIGluIGVzNiB0aGlzIHdpbGwgbm90IGNvbnZlcnQgXCJudWxsXCIgaW50byBhbiBlbXRweSBzdHJpbmdcblxuICAgICAgICAgICAgaWYgKG5vbmNlID09IG51bGwpIC8vIG51bGwgb3IgdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgbm9uY2UgPSBcIlwiO1xuXG4gICAgICAgICAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihtZXNzYWdlKSkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBuZXcgQnVmZmVyKG1lc3NhZ2UsICdiaW5hcnknKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIFMgPSBwcml2YXRlX2tleS5nZXRfc2hhcmVkX3NlY3JldChwdWJsaWNfa2V5KTtcblxuICAgICAgICAgICAgLy8gRCBFIEIgVSBHXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnZW5jcnlwdF93aXRoX2NoZWNrc3VtJywge1xuICAgICAgICAgICAgLy8gICAgIHByaXZfdG9fcHViOiBwcml2YXRlX2tleS50b1B1YmxpY0tleSgpLnRvU3RyaW5nKClcbiAgICAgICAgICAgIC8vICAgICBwdWI6IHB1YmxpY19rZXkudG9QdWJsaWNLZXlTdHJpbmcoKVxuICAgICAgICAgICAgLy8gICAgIG5vbmNlOiBub25jZVxuICAgICAgICAgICAgLy8gICAgIG1lc3NhZ2U6IG1lc3NhZ2UubGVuZ3RoXG4gICAgICAgICAgICAvLyAgICAgUzogUy50b1N0cmluZygnaGV4JylcbiAgICAgICAgICAgIC8vIH0pXG5cbiAgICAgICAgICAgIHZhciBhZXMgPSBBZXMuZnJvbVNlZWQoQnVmZmVyLmNvbmNhdChbXG4gICAgICAgICAgICAvLyBBIG51bGwgb3IgZW1wdHkgc3RyaW5nIG5vbmNlIHdpbGwgbm90IGVmZmVjdCB0aGUgaGFzaFxuICAgICAgICAgICAgbmV3IEJ1ZmZlcihcIlwiICsgbm9uY2UpLCBuZXcgQnVmZmVyKFMudG9TdHJpbmcoJ2hleCcpKV0pKTtcbiAgICAgICAgICAgIC8vIERFQlVHIGNvbnNvbGUubG9nKCcuLi4gUycsUy50b1N0cmluZygnaGV4JykpXG4gICAgICAgICAgICB2YXIgY2hlY2tzdW0gPSBoYXNoLnNoYTI1NihtZXNzYWdlKS5zbGljZSgwLCA0KTtcbiAgICAgICAgICAgIHZhciBwYXlsb2FkID0gQnVmZmVyLmNvbmNhdChbY2hlY2tzdW0sIG1lc3NhZ2VdKTtcbiAgICAgICAgICAgIC8vIERFQlVHIGNvbnNvbGUubG9nKCcuLi4gcGF5bG9hZCcscGF5bG9hZC50b1N0cmluZygpKVxuICAgICAgICAgICAgcmV0dXJuIGFlcy5lbmNyeXB0KHBheWxvYWQpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIEFlcztcbn0oKTtcblxubW9kdWxlLmV4cG9ydHMgPSBBZXM7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0Jyk7IC8vIGZyb20gZ2l0aHViLmNvbS9iaXRjb2luanMvYml0Y29pbmpzLWxpYiBmcm9tIGdpdGh1Yi5jb20vY3J5cHRvY29pbmpzL2VjZHNhXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi9oYXNoJyk7XG52YXIgZW5mb3JjZVR5cGUgPSByZXF1aXJlKCcuL2VuZm9yY2VfdHlwZXMnKTtcblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCdiaWdpJyk7XG52YXIgRUNTaWduYXR1cmUgPSByZXF1aXJlKCcuL2Vjc2lnbmF0dXJlJyk7XG5cbi8vIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM2OTc5I3NlY3Rpb24tMy4yXG5mdW5jdGlvbiBkZXRlcm1pbmlzdGljR2VuZXJhdGVLKGN1cnZlLCBoYXNoLCBkLCBjaGVja1NpZywgbm9uY2UpIHtcblxuICBlbmZvcmNlVHlwZSgnQnVmZmVyJywgaGFzaCk7XG4gIGVuZm9yY2VUeXBlKEJpZ0ludGVnZXIsIGQpO1xuXG4gIGlmIChub25jZSkge1xuICAgIGhhc2ggPSBjcnlwdG8uc2hhMjU2KEJ1ZmZlci5jb25jYXQoW2hhc2gsIG5ldyBCdWZmZXIobm9uY2UpXSkpO1xuICB9XG5cbiAgLy8gc2FuaXR5IGNoZWNrXG4gIGFzc2VydC5lcXVhbChoYXNoLmxlbmd0aCwgMzIsICdIYXNoIG11c3QgYmUgMjU2IGJpdCcpO1xuXG4gIHZhciB4ID0gZC50b0J1ZmZlcigzMik7XG4gIHZhciBrID0gbmV3IEJ1ZmZlcigzMik7XG4gIHZhciB2ID0gbmV3IEJ1ZmZlcigzMik7XG5cbiAgLy8gU3RlcCBCXG4gIHYuZmlsbCgxKTtcblxuICAvLyBTdGVwIENcbiAgay5maWxsKDApO1xuXG4gIC8vIFN0ZXAgRFxuICBrID0gY3J5cHRvLkhtYWNTSEEyNTYoQnVmZmVyLmNvbmNhdChbdiwgbmV3IEJ1ZmZlcihbMF0pLCB4LCBoYXNoXSksIGspO1xuXG4gIC8vIFN0ZXAgRVxuICB2ID0gY3J5cHRvLkhtYWNTSEEyNTYodiwgayk7XG5cbiAgLy8gU3RlcCBGXG4gIGsgPSBjcnlwdG8uSG1hY1NIQTI1NihCdWZmZXIuY29uY2F0KFt2LCBuZXcgQnVmZmVyKFsxXSksIHgsIGhhc2hdKSwgayk7XG5cbiAgLy8gU3RlcCBHXG4gIHYgPSBjcnlwdG8uSG1hY1NIQTI1Nih2LCBrKTtcblxuICAvLyBTdGVwIEgxL0gyYSwgaWdub3JlZCBhcyB0bGVuID09PSBxbGVuICgyNTYgYml0KVxuICAvLyBTdGVwIEgyYlxuICB2ID0gY3J5cHRvLkhtYWNTSEEyNTYodiwgayk7XG5cbiAgdmFyIFQgPSBCaWdJbnRlZ2VyLmZyb21CdWZmZXIodik7XG5cbiAgLy8gU3RlcCBIMywgcmVwZWF0IHVudGlsIFQgaXMgd2l0aGluIHRoZSBpbnRlcnZhbCBbMSwgbiAtIDFdXG4gIHdoaWxlIChULnNpZ251bSgpIDw9IDAgfHwgVC5jb21wYXJlVG8oY3VydmUubikgPj0gMCB8fCAhY2hlY2tTaWcoVCkpIHtcbiAgICBrID0gY3J5cHRvLkhtYWNTSEEyNTYoQnVmZmVyLmNvbmNhdChbdiwgbmV3IEJ1ZmZlcihbMF0pXSksIGspO1xuICAgIHYgPSBjcnlwdG8uSG1hY1NIQTI1Nih2LCBrKTtcblxuICAgIC8vIFN0ZXAgSDEvSDJhLCBhZ2FpbiwgaWdub3JlZCBhcyB0bGVuID09PSBxbGVuICgyNTYgYml0KVxuICAgIC8vIFN0ZXAgSDJiIGFnYWluXG4gICAgdiA9IGNyeXB0by5IbWFjU0hBMjU2KHYsIGspO1xuXG4gICAgVCA9IEJpZ0ludGVnZXIuZnJvbUJ1ZmZlcih2KTtcbiAgfVxuXG4gIHJldHVybiBUO1xufVxuXG5mdW5jdGlvbiBzaWduKGN1cnZlLCBoYXNoLCBkLCBub25jZSkge1xuXG4gIHZhciBlID0gQmlnSW50ZWdlci5mcm9tQnVmZmVyKGhhc2gpO1xuICB2YXIgbiA9IGN1cnZlLm47XG4gIHZhciBHID0gY3VydmUuRztcblxuICB2YXIgciwgcztcbiAgdmFyIGsgPSBkZXRlcm1pbmlzdGljR2VuZXJhdGVLKGN1cnZlLCBoYXNoLCBkLCBmdW5jdGlvbiAoaykge1xuICAgIC8vIGZpbmQgY2Fub25pY2FsbHkgdmFsaWQgc2lnbmF0dXJlXG4gICAgdmFyIFEgPSBHLm11bHRpcGx5KGspO1xuXG4gICAgaWYgKGN1cnZlLmlzSW5maW5pdHkoUSkpIHJldHVybiBmYWxzZTtcblxuICAgIHIgPSBRLmFmZmluZVgubW9kKG4pO1xuICAgIGlmIChyLnNpZ251bSgpID09PSAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICBzID0gay5tb2RJbnZlcnNlKG4pLm11bHRpcGx5KGUuYWRkKGQubXVsdGlwbHkocikpKS5tb2Qobik7XG4gICAgaWYgKHMuc2lnbnVtKCkgPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9LCBub25jZSk7XG5cbiAgdmFyIE5fT1ZFUl9UV08gPSBuLnNoaWZ0UmlnaHQoMSk7XG5cbiAgLy8gZW5mb3JjZSBsb3cgUyB2YWx1ZXMsIHNlZSBiaXA2MjogJ2xvdyBzIHZhbHVlcyBpbiBzaWduYXR1cmVzJ1xuICBpZiAocy5jb21wYXJlVG8oTl9PVkVSX1RXTykgPiAwKSB7XG4gICAgcyA9IG4uc3VidHJhY3Qocyk7XG4gIH1cblxuICByZXR1cm4gbmV3IEVDU2lnbmF0dXJlKHIsIHMpO1xufVxuXG5mdW5jdGlvbiB2ZXJpZnlSYXcoY3VydmUsIGUsIHNpZ25hdHVyZSwgUSkge1xuICB2YXIgbiA9IGN1cnZlLm47XG4gIHZhciBHID0gY3VydmUuRztcblxuICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICB2YXIgcyA9IHNpZ25hdHVyZS5zO1xuXG4gIC8vIDEuNC4xIEVuZm9yY2UgciBhbmQgcyBhcmUgYm90aCBpbnRlZ2VycyBpbiB0aGUgaW50ZXJ2YWwgWzEsIG4g4oiSIDFdXG4gIGlmIChyLnNpZ251bSgpIDw9IDAgfHwgci5jb21wYXJlVG8obikgPj0gMCkgcmV0dXJuIGZhbHNlO1xuICBpZiAocy5zaWdudW0oKSA8PSAwIHx8IHMuY29tcGFyZVRvKG4pID49IDApIHJldHVybiBmYWxzZTtcblxuICAvLyBjID0gc14tMSBtb2QgblxuICB2YXIgYyA9IHMubW9kSW52ZXJzZShuKTtcblxuICAvLyAxLjQuNCBDb21wdXRlIHUxID0gZXNe4oiSMSBtb2QgblxuICAvLyAgICAgICAgICAgICAgIHUyID0gcnNe4oiSMSBtb2QgblxuICB2YXIgdTEgPSBlLm11bHRpcGx5KGMpLm1vZChuKTtcbiAgdmFyIHUyID0gci5tdWx0aXBseShjKS5tb2Qobik7XG5cbiAgLy8gMS40LjUgQ29tcHV0ZSBSID0gKHhSLCB5UikgPSB1MUcgKyB1MlFcbiAgdmFyIFIgPSBHLm11bHRpcGx5VHdvKHUxLCBRLCB1Mik7XG5cbiAgLy8gMS40LjUgKGNvbnQuKSBFbmZvcmNlIFIgaXMgbm90IGF0IGluZmluaXR5XG4gIGlmIChjdXJ2ZS5pc0luZmluaXR5KFIpKSByZXR1cm4gZmFsc2U7XG5cbiAgLy8gMS40LjYgQ29udmVydCB0aGUgZmllbGQgZWxlbWVudCBSLnggdG8gYW4gaW50ZWdlclxuICB2YXIgeFIgPSBSLmFmZmluZVg7XG5cbiAgLy8gMS40LjcgU2V0IHYgPSB4UiBtb2QgblxuICB2YXIgdiA9IHhSLm1vZChuKTtcblxuICAvLyAxLjQuOCBJZiB2ID0gciwgb3V0cHV0IFwidmFsaWRcIiwgYW5kIGlmIHYgIT0gciwgb3V0cHV0IFwiaW52YWxpZFwiXG4gIHJldHVybiB2LmVxdWFscyhyKTtcbn1cblxuZnVuY3Rpb24gdmVyaWZ5KGN1cnZlLCBoYXNoLCBzaWduYXR1cmUsIFEpIHtcbiAgLy8gMS40LjIgSCA9IEhhc2goTSksIGFscmVhZHkgZG9uZSBieSB0aGUgdXNlclxuICAvLyAxLjQuMyBlID0gSFxuICB2YXIgZSA9IEJpZ0ludGVnZXIuZnJvbUJ1ZmZlcihoYXNoKTtcbiAgcmV0dXJuIHZlcmlmeVJhdyhjdXJ2ZSwgZSwgc2lnbmF0dXJlLCBRKTtcbn1cblxuLyoqXG4gICogUmVjb3ZlciBhIHB1YmxpYyBrZXkgZnJvbSBhIHNpZ25hdHVyZS5cbiAgKlxuICAqIFNlZSBTRUMgMTogRWxsaXB0aWMgQ3VydmUgQ3J5cHRvZ3JhcGh5LCBzZWN0aW9uIDQuMS42LCBcIlB1YmxpY1xuICAqIEtleSBSZWNvdmVyeSBPcGVyYXRpb25cIi5cbiAgKlxuICAqIGh0dHA6Ly93d3cuc2VjZy5vcmcvZG93bmxvYWQvYWlkLTc4MC9zZWMxLXYyLnBkZlxuICAqL1xuZnVuY3Rpb24gcmVjb3ZlclB1YktleShjdXJ2ZSwgZSwgc2lnbmF0dXJlLCBpKSB7XG4gIGFzc2VydC5zdHJpY3RFcXVhbChpICYgMywgaSwgJ1JlY292ZXJ5IHBhcmFtIGlzIG1vcmUgdGhhbiB0d28gYml0cycpO1xuXG4gIHZhciBuID0gY3VydmUubjtcbiAgdmFyIEcgPSBjdXJ2ZS5HO1xuXG4gIHZhciByID0gc2lnbmF0dXJlLnI7XG4gIHZhciBzID0gc2lnbmF0dXJlLnM7XG5cbiAgYXNzZXJ0KHIuc2lnbnVtKCkgPiAwICYmIHIuY29tcGFyZVRvKG4pIDwgMCwgJ0ludmFsaWQgciB2YWx1ZScpO1xuICBhc3NlcnQocy5zaWdudW0oKSA+IDAgJiYgcy5jb21wYXJlVG8obikgPCAwLCAnSW52YWxpZCBzIHZhbHVlJyk7XG5cbiAgLy8gQSBzZXQgTFNCIHNpZ25pZmllcyB0aGF0IHRoZSB5LWNvb3JkaW5hdGUgaXMgb2RkXG4gIHZhciBpc1lPZGQgPSBpICYgMTtcblxuICAvLyBUaGUgbW9yZSBzaWduaWZpY2FudCBiaXQgc3BlY2lmaWVzIHdoZXRoZXIgd2Ugc2hvdWxkIHVzZSB0aGVcbiAgLy8gZmlyc3Qgb3Igc2Vjb25kIGNhbmRpZGF0ZSBrZXkuXG4gIHZhciBpc1NlY29uZEtleSA9IGkgPj4gMTtcblxuICAvLyAxLjEgTGV0IHggPSByICsgam5cbiAgdmFyIHggPSBpc1NlY29uZEtleSA/IHIuYWRkKG4pIDogcjtcbiAgdmFyIFIgPSBjdXJ2ZS5wb2ludEZyb21YKGlzWU9kZCwgeCk7XG5cbiAgLy8gMS40IENoZWNrIHRoYXQgblIgaXMgYXQgaW5maW5pdHlcbiAgdmFyIG5SID0gUi5tdWx0aXBseShuKTtcbiAgYXNzZXJ0KGN1cnZlLmlzSW5maW5pdHkoblIpLCAnblIgaXMgbm90IGEgdmFsaWQgY3VydmUgcG9pbnQnKTtcblxuICAvLyBDb21wdXRlIC1lIGZyb20gZVxuICB2YXIgZU5lZyA9IGUubmVnYXRlKCkubW9kKG4pO1xuXG4gIC8vIDEuNi4xIENvbXB1dGUgUSA9IHJeLTEgKHNSIC0gIGVHKVxuICAvLyAgICAgICAgICAgICAgIFEgPSByXi0xIChzUiArIC1lRylcbiAgdmFyIHJJbnYgPSByLm1vZEludmVyc2Uobik7XG5cbiAgdmFyIFEgPSBSLm11bHRpcGx5VHdvKHMsIEcsIGVOZWcpLm11bHRpcGx5KHJJbnYpO1xuICBjdXJ2ZS52YWxpZGF0ZShRKTtcblxuICByZXR1cm4gUTtcbn1cblxuLyoqXG4gICogQ2FsY3VsYXRlIHB1YmtleSBleHRyYWN0aW9uIHBhcmFtZXRlci5cbiAgKlxuICAqIFdoZW4gZXh0cmFjdGluZyBhIHB1YmtleSBmcm9tIGEgc2lnbmF0dXJlLCB3ZSBoYXZlIHRvXG4gICogZGlzdGluZ3Vpc2ggZm91ciBkaWZmZXJlbnQgY2FzZXMuIFJhdGhlciB0aGFuIHB1dHRpbmcgdGhpc1xuICAqIGJ1cmRlbiBvbiB0aGUgdmVyaWZpZXIsIEJpdGNvaW4gaW5jbHVkZXMgYSAyLWJpdCB2YWx1ZSB3aXRoIHRoZVxuICAqIHNpZ25hdHVyZS5cbiAgKlxuICAqIFRoaXMgZnVuY3Rpb24gc2ltcGx5IHRyaWVzIGFsbCBmb3VyIGNhc2VzIGFuZCByZXR1cm5zIHRoZSB2YWx1ZVxuICAqIHRoYXQgcmVzdWx0ZWQgaW4gYSBzdWNjZXNzZnVsIHB1YmtleSByZWNvdmVyeS5cbiAgKi9cbmZ1bmN0aW9uIGNhbGNQdWJLZXlSZWNvdmVyeVBhcmFtKGN1cnZlLCBlLCBzaWduYXR1cmUsIFEpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICB2YXIgUXByaW1lID0gcmVjb3ZlclB1YktleShjdXJ2ZSwgZSwgc2lnbmF0dXJlLCBpKTtcblxuICAgIC8vIDEuNi4yIFZlcmlmeSBRXG4gICAgaWYgKFFwcmltZS5lcXVhbHMoUSkpIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGZpbmQgdmFsaWQgcmVjb3ZlcnkgZmFjdG9yJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjYWxjUHViS2V5UmVjb3ZlcnlQYXJhbTogY2FsY1B1YktleVJlY292ZXJ5UGFyYW0sXG4gIGRldGVybWluaXN0aWNHZW5lcmF0ZUs6IGRldGVybWluaXN0aWNHZW5lcmF0ZUssXG4gIHJlY292ZXJQdWJLZXk6IHJlY292ZXJQdWJLZXksXG4gIHNpZ246IHNpZ24sXG4gIHZlcmlmeTogdmVyaWZ5LFxuICB2ZXJpZnlSYXc6IHZlcmlmeVJhd1xufTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdhc3NlcnQnKTsgLy8gZnJvbSBodHRwczovL2dpdGh1Yi5jb20vYml0Y29pbmpzL2JpdGNvaW5qcy1saWJcbnZhciBlbmZvcmNlVHlwZSA9IHJlcXVpcmUoJy4vZW5mb3JjZV90eXBlcycpO1xuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJ2JpZ2knKTtcblxuZnVuY3Rpb24gRUNTaWduYXR1cmUociwgcykge1xuICBlbmZvcmNlVHlwZShCaWdJbnRlZ2VyLCByKTtcbiAgZW5mb3JjZVR5cGUoQmlnSW50ZWdlciwgcyk7XG5cbiAgdGhpcy5yID0gcjtcbiAgdGhpcy5zID0gcztcbn1cblxuLy8gSW1wb3J0IG9wZXJhdGlvbnNcbkVDU2lnbmF0dXJlLnBhcnNlQ29tcGFjdCA9IGZ1bmN0aW9uIChidWZmZXIpIHtcbiAgYXNzZXJ0LmVxdWFsKGJ1ZmZlci5sZW5ndGgsIDY1LCAnSW52YWxpZCBzaWduYXR1cmUgbGVuZ3RoJyk7XG4gIHZhciBpID0gYnVmZmVyLnJlYWRVSW50OCgwKSAtIDI3O1xuXG4gIC8vIEF0IG1vc3QgMyBiaXRzXG4gIGFzc2VydC5lcXVhbChpLCBpICYgNywgJ0ludmFsaWQgc2lnbmF0dXJlIHBhcmFtZXRlcicpO1xuICB2YXIgY29tcHJlc3NlZCA9ICEhKGkgJiA0KTtcblxuICAvLyBSZWNvdmVyeSBwYXJhbSBvbmx5XG4gIGkgPSBpICYgMztcblxuICB2YXIgciA9IEJpZ0ludGVnZXIuZnJvbUJ1ZmZlcihidWZmZXIuc2xpY2UoMSwgMzMpKTtcbiAgdmFyIHMgPSBCaWdJbnRlZ2VyLmZyb21CdWZmZXIoYnVmZmVyLnNsaWNlKDMzKSk7XG5cbiAgcmV0dXJuIHtcbiAgICBjb21wcmVzc2VkOiBjb21wcmVzc2VkLFxuICAgIGk6IGksXG4gICAgc2lnbmF0dXJlOiBuZXcgRUNTaWduYXR1cmUociwgcylcbiAgfTtcbn07XG5cbkVDU2lnbmF0dXJlLmZyb21ERVIgPSBmdW5jdGlvbiAoYnVmZmVyKSB7XG4gIGFzc2VydC5lcXVhbChidWZmZXIucmVhZFVJbnQ4KDApLCAweDMwLCAnTm90IGEgREVSIHNlcXVlbmNlJyk7XG4gIGFzc2VydC5lcXVhbChidWZmZXIucmVhZFVJbnQ4KDEpLCBidWZmZXIubGVuZ3RoIC0gMiwgJ0ludmFsaWQgc2VxdWVuY2UgbGVuZ3RoJyk7XG4gIGFzc2VydC5lcXVhbChidWZmZXIucmVhZFVJbnQ4KDIpLCAweDAyLCAnRXhwZWN0ZWQgYSBERVIgaW50ZWdlcicpO1xuXG4gIHZhciByTGVuID0gYnVmZmVyLnJlYWRVSW50OCgzKTtcbiAgYXNzZXJ0KHJMZW4gPiAwLCAnUiBsZW5ndGggaXMgemVybycpO1xuXG4gIHZhciBvZmZzZXQgPSA0ICsgckxlbjtcbiAgYXNzZXJ0LmVxdWFsKGJ1ZmZlci5yZWFkVUludDgob2Zmc2V0KSwgMHgwMiwgJ0V4cGVjdGVkIGEgREVSIGludGVnZXIgKDIpJyk7XG5cbiAgdmFyIHNMZW4gPSBidWZmZXIucmVhZFVJbnQ4KG9mZnNldCArIDEpO1xuICBhc3NlcnQoc0xlbiA+IDAsICdTIGxlbmd0aCBpcyB6ZXJvJyk7XG5cbiAgdmFyIHJCID0gYnVmZmVyLnNsaWNlKDQsIG9mZnNldCk7XG4gIHZhciBzQiA9IGJ1ZmZlci5zbGljZShvZmZzZXQgKyAyKTtcbiAgb2Zmc2V0ICs9IDIgKyBzTGVuO1xuXG4gIGlmIChyTGVuID4gMSAmJiByQi5yZWFkVUludDgoMCkgPT09IDB4MDApIHtcbiAgICBhc3NlcnQockIucmVhZFVJbnQ4KDEpICYgMHg4MCwgJ1IgdmFsdWUgZXhjZXNzaXZlbHkgcGFkZGVkJyk7XG4gIH1cblxuICBpZiAoc0xlbiA+IDEgJiYgc0IucmVhZFVJbnQ4KDApID09PSAweDAwKSB7XG4gICAgYXNzZXJ0KHNCLnJlYWRVSW50OCgxKSAmIDB4ODAsICdTIHZhbHVlIGV4Y2Vzc2l2ZWx5IHBhZGRlZCcpO1xuICB9XG5cbiAgYXNzZXJ0LmVxdWFsKG9mZnNldCwgYnVmZmVyLmxlbmd0aCwgJ0ludmFsaWQgREVSIGVuY29kaW5nJyk7XG4gIHZhciByID0gQmlnSW50ZWdlci5mcm9tREVSSW50ZWdlcihyQik7XG4gIHZhciBzID0gQmlnSW50ZWdlci5mcm9tREVSSW50ZWdlcihzQik7XG5cbiAgYXNzZXJ0KHIuc2lnbnVtKCkgPj0gMCwgJ1IgdmFsdWUgaXMgbmVnYXRpdmUnKTtcbiAgYXNzZXJ0KHMuc2lnbnVtKCkgPj0gMCwgJ1MgdmFsdWUgaXMgbmVnYXRpdmUnKTtcblxuICByZXR1cm4gbmV3IEVDU2lnbmF0dXJlKHIsIHMpO1xufTtcblxuLy8gRklYTUU6IDB4MDAsIDB4MDQsIDB4ODAgYXJlIFNJR0hBU0hfKiBib3VuZGFyeSBjb25zdGFudHMsIGltcG9ydGluZyBUcmFuc2FjdGlvbiBjYXVzZXMgYSBjaXJjdWxhciBkZXBlbmRlbmN5XG5FQ1NpZ25hdHVyZS5wYXJzZVNjcmlwdFNpZ25hdHVyZSA9IGZ1bmN0aW9uIChidWZmZXIpIHtcbiAgdmFyIGhhc2hUeXBlID0gYnVmZmVyLnJlYWRVSW50OChidWZmZXIubGVuZ3RoIC0gMSk7XG4gIHZhciBoYXNoVHlwZU1vZCA9IGhhc2hUeXBlICYgfjB4ODA7XG5cbiAgYXNzZXJ0KGhhc2hUeXBlTW9kID4gMHgwMCAmJiBoYXNoVHlwZU1vZCA8IDB4MDQsICdJbnZhbGlkIGhhc2hUeXBlJyk7XG5cbiAgcmV0dXJuIHtcbiAgICBzaWduYXR1cmU6IEVDU2lnbmF0dXJlLmZyb21ERVIoYnVmZmVyLnNsaWNlKDAsIC0xKSksXG4gICAgaGFzaFR5cGU6IGhhc2hUeXBlXG4gIH07XG59O1xuXG4vLyBFeHBvcnQgb3BlcmF0aW9uc1xuRUNTaWduYXR1cmUucHJvdG90eXBlLnRvQ29tcGFjdCA9IGZ1bmN0aW9uIChpLCBjb21wcmVzc2VkKSB7XG4gIGlmIChjb21wcmVzc2VkKSBpICs9IDQ7XG4gIGkgKz0gMjc7XG5cbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIoNjUpO1xuICBidWZmZXIud3JpdGVVSW50OChpLCAwKTtcblxuICB0aGlzLnIudG9CdWZmZXIoMzIpLmNvcHkoYnVmZmVyLCAxKTtcbiAgdGhpcy5zLnRvQnVmZmVyKDMyKS5jb3B5KGJ1ZmZlciwgMzMpO1xuXG4gIHJldHVybiBidWZmZXI7XG59O1xuXG5FQ1NpZ25hdHVyZS5wcm90b3R5cGUudG9ERVIgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciByQmEgPSB0aGlzLnIudG9ERVJJbnRlZ2VyKCk7XG4gIHZhciBzQmEgPSB0aGlzLnMudG9ERVJJbnRlZ2VyKCk7XG5cbiAgdmFyIHNlcXVlbmNlID0gW107XG5cbiAgLy8gSU5URUdFUlxuICBzZXF1ZW5jZS5wdXNoKDB4MDIsIHJCYS5sZW5ndGgpO1xuICBzZXF1ZW5jZSA9IHNlcXVlbmNlLmNvbmNhdChyQmEpO1xuXG4gIC8vIElOVEVHRVJcbiAgc2VxdWVuY2UucHVzaCgweDAyLCBzQmEubGVuZ3RoKTtcbiAgc2VxdWVuY2UgPSBzZXF1ZW5jZS5jb25jYXQoc0JhKTtcblxuICAvLyBTRVFVRU5DRVxuICBzZXF1ZW5jZS51bnNoaWZ0KDB4MzAsIHNlcXVlbmNlLmxlbmd0aCk7XG5cbiAgcmV0dXJuIG5ldyBCdWZmZXIoc2VxdWVuY2UpO1xufTtcblxuRUNTaWduYXR1cmUucHJvdG90eXBlLnRvU2NyaXB0U2lnbmF0dXJlID0gZnVuY3Rpb24gKGhhc2hUeXBlKSB7XG4gIHZhciBoYXNoVHlwZUJ1ZmZlciA9IG5ldyBCdWZmZXIoMSk7XG4gIGhhc2hUeXBlQnVmZmVyLndyaXRlVUludDgoaGFzaFR5cGUsIDApO1xuXG4gIHJldHVybiBCdWZmZXIuY29uY2F0KFt0aGlzLnRvREVSKCksIGhhc2hUeXBlQnVmZmVyXSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVDU2lnbmF0dXJlOyIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBlbmZvcmNlKHR5cGUsIHZhbHVlKSB7XG4gIC8vIENvcGllZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9iaXRjb2luanMvYml0Y29pbmpzLWxpYlxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdBcnJheSc6XG4gICAgICB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybjtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlICdCdWZmZXInOlxuICAgICAge1xuICAgICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSkgcmV0dXJuO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgJ051bWJlcic6XG4gICAgICB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSByZXR1cm47XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybjtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBkZWZhdWx0OlxuICAgICAge1xuICAgICAgICBpZiAoZ2V0TmFtZSh2YWx1ZS5jb25zdHJ1Y3RvcikgPT09IGdldE5hbWUodHlwZSkpIHJldHVybjtcbiAgICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ0V4cGVjdGVkICcgKyAoZ2V0TmFtZSh0eXBlKSB8fCB0eXBlKSArICcsIGdvdCAnICsgdmFsdWUpO1xufTtcblxuZnVuY3Rpb24gZ2V0TmFtZShmbikge1xuICAvLyBXaHkgbm90IGZuLm5hbWU6IGh0dHBzOi8va2FuZ2F4LmdpdGh1Yi5pby9jb21wYXQtdGFibGUvZXM2LyNmdW5jdGlvbl9uYW1lX3Byb3BlcnR5XG4gIHZhciBtYXRjaCA9IGZuLnRvU3RyaW5nKCkubWF0Y2goL2Z1bmN0aW9uICguKj8pXFwoLyk7XG4gIHJldHVybiBtYXRjaCA/IG1hdGNoWzFdIDogbnVsbDtcbn0iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIGNyZWF0ZUhhc2ggPSByZXF1aXJlKFwiY3JlYXRlLWhhc2hcIik7XG52YXIgY3JlYXRlSG1hYyA9IHJlcXVpcmUoXCJjcmVhdGUtaG1hY1wiKTtcblxuLyoqIEBhcmcge3N0cmluZ3xCdWZmZXJ9IGRhdGFcbiAgICBAYXJnIHtzdHJpbmd9IFtkaWdlc3QgPSBudWxsXSAtICdoZXgnLCAnYmluYXJ5JyBvciAnYmFzZTY0J1xuICAgIEByZXR1cm4ge3N0cmluZ3xCdWZmZXJ9IC0gQnVmZmVyIHdoZW4gZGlnZXN0IGlzIG51bGwsIG9yIHN0cmluZ1xuKi9cbmZ1bmN0aW9uIHNoYTEoZGF0YSwgZW5jb2RpbmcpIHtcbiAgICByZXR1cm4gY3JlYXRlSGFzaCgnc2hhMScpLnVwZGF0ZShkYXRhKS5kaWdlc3QoZW5jb2RpbmcpO1xufVxuXG4vKiogQGFyZyB7c3RyaW5nfEJ1ZmZlcn0gZGF0YVxuICAgIEBhcmcge3N0cmluZ30gW2RpZ2VzdCA9IG51bGxdIC0gJ2hleCcsICdiaW5hcnknIG9yICdiYXNlNjQnXG4gICAgQHJldHVybiB7c3RyaW5nfEJ1ZmZlcn0gLSBCdWZmZXIgd2hlbiBkaWdlc3QgaXMgbnVsbCwgb3Igc3RyaW5nXG4qL1xuZnVuY3Rpb24gc2hhMjU2KGRhdGEsIGVuY29kaW5nKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShkYXRhKS5kaWdlc3QoZW5jb2RpbmcpO1xufVxuXG4vKiogQGFyZyB7c3RyaW5nfEJ1ZmZlcn0gZGF0YVxuICAgIEBhcmcge3N0cmluZ30gW2RpZ2VzdCA9IG51bGxdIC0gJ2hleCcsICdiaW5hcnknIG9yICdiYXNlNjQnXG4gICAgQHJldHVybiB7c3RyaW5nfEJ1ZmZlcn0gLSBCdWZmZXIgd2hlbiBkaWdlc3QgaXMgbnVsbCwgb3Igc3RyaW5nXG4qL1xuZnVuY3Rpb24gc2hhNTEyKGRhdGEsIGVuY29kaW5nKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhhc2goJ3NoYTUxMicpLnVwZGF0ZShkYXRhKS5kaWdlc3QoZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiBIbWFjU0hBMjU2KGJ1ZmZlciwgc2VjcmV0KSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhtYWMoJ3NoYTI1NicsIHNlY3JldCkudXBkYXRlKGJ1ZmZlcikuZGlnZXN0KCk7XG59XG5cbmZ1bmN0aW9uIHJpcGVtZDE2MChkYXRhKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhhc2goJ3JtZDE2MCcpLnVwZGF0ZShkYXRhKS5kaWdlc3QoKTtcbn1cblxuLy8gZnVuY3Rpb24gaGFzaDE2MChidWZmZXIpIHtcbi8vICAgcmV0dXJuIHJpcGVtZDE2MChzaGEyNTYoYnVmZmVyKSlcbi8vIH1cbi8vXG4vLyBmdW5jdGlvbiBoYXNoMjU2KGJ1ZmZlcikge1xuLy8gICByZXR1cm4gc2hhMjU2KHNoYTI1NihidWZmZXIpKVxuLy8gfVxuXG4vL1xuLy8gZnVuY3Rpb24gSG1hY1NIQTUxMihidWZmZXIsIHNlY3JldCkge1xuLy8gICByZXR1cm4gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTUxMicsIHNlY3JldCkudXBkYXRlKGJ1ZmZlcikuZGlnZXN0KClcbi8vIH1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgc2hhMTogc2hhMSxcbiAgICBzaGEyNTY6IHNoYTI1NixcbiAgICBzaGE1MTI6IHNoYTUxMixcbiAgICBIbWFjU0hBMjU2OiBIbWFjU0hBMjU2LFxuICAgIHJpcGVtZDE2MDogcmlwZW1kMTYwXG4gICAgLy8gaGFzaDE2MDogaGFzaDE2MCxcbiAgICAvLyBoYXNoMjU2OiBoYXNoMjU2LFxuICAgIC8vIEhtYWNTSEE1MTI6IEhtYWNTSEE1MTJcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgZWNkc2EgPSByZXF1aXJlKCcuL2VjZHNhJyk7XG52YXIgaGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdlY3VydmUnKSxcbiAgICBnZXRDdXJ2ZUJ5TmFtZSA9IF9yZXF1aXJlLmdldEN1cnZlQnlOYW1lO1xuXG52YXIgc2VjcDI1NmsxID0gZ2V0Q3VydmVCeU5hbWUoJ3NlY3AyNTZrMScpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpO1xudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCdiaWdpJyk7XG52YXIgUHVibGljS2V5ID0gcmVxdWlyZSgnLi9QdWJsaWNLZXknKTtcblxudmFyIFNpZ25hdHVyZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTaWduYXR1cmUocjEsIHMxLCBpMSkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU2lnbmF0dXJlKTtcblxuICAgICAgICB0aGlzLnIgPSByMTtcbiAgICAgICAgdGhpcy5zID0gczE7XG4gICAgICAgIHRoaXMuaSA9IGkxO1xuICAgICAgICBhc3NlcnQuZXF1YWwodGhpcy5yICE9IG51bGwsIHRydWUsICdNaXNzaW5nIHBhcmFtZXRlcicpO1xuICAgICAgICBhc3NlcnQuZXF1YWwodGhpcy5zICE9IG51bGwsIHRydWUsICdNaXNzaW5nIHBhcmFtZXRlcicpO1xuICAgICAgICBhc3NlcnQuZXF1YWwodGhpcy5pICE9IG51bGwsIHRydWUsICdNaXNzaW5nIHBhcmFtZXRlcicpO1xuICAgIH1cblxuICAgIF9jcmVhdGVDbGFzcyhTaWduYXR1cmUsIFt7XG4gICAgICAgIGtleTogJ3RvQnVmZmVyJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvQnVmZmVyKCkge1xuICAgICAgICAgICAgdmFyIGJ1ZjtcbiAgICAgICAgICAgIGJ1ZiA9IG5ldyBCdWZmZXIoNjUpO1xuICAgICAgICAgICAgYnVmLndyaXRlVUludDgodGhpcy5pLCAwKTtcbiAgICAgICAgICAgIHRoaXMuci50b0J1ZmZlcigzMikuY29weShidWYsIDEpO1xuICAgICAgICAgICAgdGhpcy5zLnRvQnVmZmVyKDMyKS5jb3B5KGJ1ZiwgMzMpO1xuICAgICAgICAgICAgcmV0dXJuIGJ1ZjtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAncmVjb3ZlclB1YmxpY0tleUZyb21CdWZmZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVjb3ZlclB1YmxpY0tleUZyb21CdWZmZXIoYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZWNvdmVyUHVibGljS2V5KGhhc2guc2hhMjU2KGJ1ZmZlcikpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdyZWNvdmVyUHVibGljS2V5JyxcblxuXG4gICAgICAgIC8qKlxuICAgICAgICAgICAgQHJldHVybiB7UHVibGljS2V5fVxuICAgICAgICAqL1xuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVjb3ZlclB1YmxpY0tleShzaGEyNTZfYnVmZmVyKSB7XG4gICAgICAgICAgICB2YXIgUSA9IHZvaWQgMCxcbiAgICAgICAgICAgICAgICBlID0gdm9pZCAwLFxuICAgICAgICAgICAgICAgIGkgPSB2b2lkIDA7XG4gICAgICAgICAgICBlID0gQmlnSW50ZWdlci5mcm9tQnVmZmVyKHNoYTI1Nl9idWZmZXIpO1xuICAgICAgICAgICAgaSA9IHRoaXMuaTtcbiAgICAgICAgICAgIGkgLT0gMjc7XG4gICAgICAgICAgICBpID0gaSAmIDM7XG4gICAgICAgICAgICBRID0gZWNkc2EucmVjb3ZlclB1YktleShzZWNwMjU2azEsIGUsIHRoaXMsIGkpO1xuICAgICAgICAgICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tUG9pbnQoUSk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3ZlcmlmeUJ1ZmZlcicsXG5cblxuICAgICAgICAvKipcbiAgICAgICAgICAgIEBwYXJhbSB7QnVmZmVyfSB1bi1oYXNoZWRcbiAgICAgICAgICAgIEBwYXJhbSB7Li9QdWJsaWNLZXl9XG4gICAgICAgICAgICBAcmV0dXJuIHtib29sZWFufVxuICAgICAgICAqL1xuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdmVyaWZ5QnVmZmVyKGJ1ZiwgcHVibGljX2tleSkge1xuICAgICAgICAgICAgdmFyIF9oYXNoID0gaGFzaC5zaGEyNTYoYnVmKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZlcmlmeUhhc2goX2hhc2gsIHB1YmxpY19rZXkpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICd2ZXJpZnlIYXNoJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHZlcmlmeUhhc2goaGFzaCwgcHVibGljX2tleSkge1xuICAgICAgICAgICAgYXNzZXJ0LmVxdWFsKGhhc2gubGVuZ3RoLCAzMiwgXCJBIFNIQSAyNTYgc2hvdWxkIGJlIDMyIGJ5dGVzIGxvbmcsIGluc3RlYWQgZ290IFwiICsgaGFzaC5sZW5ndGgpO1xuICAgICAgICAgICAgcmV0dXJuIGVjZHNhLnZlcmlmeShzZWNwMjU2azEsIGhhc2gsIHtcbiAgICAgICAgICAgICAgICByOiB0aGlzLnIsXG4gICAgICAgICAgICAgICAgczogdGhpcy5zXG4gICAgICAgICAgICB9LCBwdWJsaWNfa2V5LlEpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICd0b0J5dGVCdWZmZXInLFxuXG5cbiAgICAgICAgLyogPEhFWD4gKi9cblxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdG9CeXRlQnVmZmVyKCkge1xuICAgICAgICAgICAgdmFyIGI7XG4gICAgICAgICAgICBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgICAgICAgICAgdGhpcy5hcHBlbmRCeXRlQnVmZmVyKGIpO1xuICAgICAgICAgICAgcmV0dXJuIGIuY29weSgwLCBiLm9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3RvSGV4JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvSGV4KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9CdWZmZXIoKS50b1N0cmluZyhcImhleFwiKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndmVyaWZ5SGV4JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHZlcmlmeUhleChoZXgsIHB1YmxpY19rZXkpIHtcbiAgICAgICAgICAgIHZhciBidWY7XG4gICAgICAgICAgICBidWYgPSBuZXcgQnVmZmVyKGhleCwgJ2hleCcpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmVyaWZ5QnVmZmVyKGJ1ZiwgcHVibGljX2tleSk7XG4gICAgICAgIH1cbiAgICB9XSwgW3tcbiAgICAgICAga2V5OiAnZnJvbUJ1ZmZlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tQnVmZmVyKGJ1Zikge1xuICAgICAgICAgICAgdmFyIGksIHIsIHM7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwoYnVmLmxlbmd0aCwgNjUsICdJbnZhbGlkIHNpZ25hdHVyZSBsZW5ndGgnKTtcbiAgICAgICAgICAgIGkgPSBidWYucmVhZFVJbnQ4KDApO1xuICAgICAgICAgICAgYXNzZXJ0LmVxdWFsKGkgLSAyNywgaSAtIDI3ICYgNywgJ0ludmFsaWQgc2lnbmF0dXJlIHBhcmFtZXRlcicpO1xuICAgICAgICAgICAgciA9IEJpZ0ludGVnZXIuZnJvbUJ1ZmZlcihidWYuc2xpY2UoMSwgMzMpKTtcbiAgICAgICAgICAgIHMgPSBCaWdJbnRlZ2VyLmZyb21CdWZmZXIoYnVmLnNsaWNlKDMzKSk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNpZ25hdHVyZShyLCBzLCBpKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnc2lnbkJ1ZmZlcicsXG5cblxuICAgICAgICAvKipcbiAgICAgICAgICAgIEBwYXJhbSB7QnVmZmVyfSBidWZcbiAgICAgICAgICAgIEBwYXJhbSB7UHJpdmF0ZUtleX0gcHJpdmF0ZV9rZXlcbiAgICAgICAgICAgIEByZXR1cm4ge1NpZ25hdHVyZX1cbiAgICAgICAgKi9cbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNpZ25CdWZmZXIoYnVmLCBwcml2YXRlX2tleSkge1xuICAgICAgICAgICAgdmFyIF9oYXNoID0gaGFzaC5zaGEyNTYoYnVmKTtcbiAgICAgICAgICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlclNoYTI1NihfaGFzaCwgcHJpdmF0ZV9rZXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqIFNpZ24gYSBidWZmZXIgb2YgZXhhY3RhbGx5IDMyIGJ5dGVzIGluIHNpemUgKHNoYTI1Nih0ZXh0KSlcbiAgICAgICAgICAgIEBwYXJhbSB7QnVmZmVyfSBidWYgLSAzMiBieXRlcyBiaW5hcnlcbiAgICAgICAgICAgIEBwYXJhbSB7UHJpdmF0ZUtleX0gcHJpdmF0ZV9rZXlcbiAgICAgICAgICAgIEByZXR1cm4ge1NpZ25hdHVyZX1cbiAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnc2lnbkJ1ZmZlclNoYTI1NicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaWduQnVmZmVyU2hhMjU2KGJ1Zl9zaGEyNTYsIHByaXZhdGVfa2V5KSB7XG4gICAgICAgICAgICBpZiAoYnVmX3NoYTI1Ni5sZW5ndGggIT09IDMyIHx8ICFCdWZmZXIuaXNCdWZmZXIoYnVmX3NoYTI1NikpIHRocm93IG5ldyBFcnJvcihcImJ1Zl9zaGEyNTY6IDMyIGJ5dGUgYnVmZmVyIHJlcXVyZWRcIik7XG4gICAgICAgICAgICB2YXIgZGVyLCBlLCBlY3NpZ25hdHVyZSwgaSwgbGVuUiwgbGVuUywgbm9uY2U7XG4gICAgICAgICAgICBpID0gbnVsbDtcbiAgICAgICAgICAgIG5vbmNlID0gMDtcbiAgICAgICAgICAgIGUgPSBCaWdJbnRlZ2VyLmZyb21CdWZmZXIoYnVmX3NoYTI1Nik7XG4gICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgIGVjc2lnbmF0dXJlID0gZWNkc2Euc2lnbihzZWNwMjU2azEsIGJ1Zl9zaGEyNTYsIHByaXZhdGVfa2V5LmQsIG5vbmNlKyspO1xuICAgICAgICAgICAgICAgIGRlciA9IGVjc2lnbmF0dXJlLnRvREVSKCk7XG4gICAgICAgICAgICAgICAgbGVuUiA9IGRlclszXTtcbiAgICAgICAgICAgICAgICBsZW5TID0gZGVyWzUgKyBsZW5SXTtcbiAgICAgICAgICAgICAgICBpZiAobGVuUiA9PT0gMzIgJiYgbGVuUyA9PT0gMzIpIHtcbiAgICAgICAgICAgICAgICAgICAgaSA9IGVjZHNhLmNhbGNQdWJLZXlSZWNvdmVyeVBhcmFtKHNlY3AyNTZrMSwgZSwgZWNzaWduYXR1cmUsIHByaXZhdGVfa2V5LnRvUHVibGljS2V5KCkuUSk7XG4gICAgICAgICAgICAgICAgICAgIGkgKz0gNDsgLy8gY29tcHJlc3NlZFxuICAgICAgICAgICAgICAgICAgICBpICs9IDI3OyAvLyBjb21wYWN0ICAvLyAgMjQgb3IgMjcgOiggZm9yY2luZyBvZGQteSAybmQga2V5IGNhbmRpZGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChub25jZSAlIDEwID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiV0FSTjogXCIgKyBub25jZSArIFwiIGF0dGVtcHRzIHRvIGZpbmQgY2Fub25pY2FsIHNpZ25hdHVyZVwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNpZ25hdHVyZShlY3NpZ25hdHVyZS5yLCBlY3NpZ25hdHVyZS5zLCBpKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnc2lnbicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaWduKHN0cmluZywgcHJpdmF0ZV9rZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlcihuZXcgQnVmZmVyKHN0cmluZyksIHByaXZhdGVfa2V5KTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZnJvbUhleCcsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tSGV4KGhleCkge1xuICAgICAgICAgICAgcmV0dXJuIFNpZ25hdHVyZS5mcm9tQnVmZmVyKG5ldyBCdWZmZXIoaGV4LCBcImhleFwiKSk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3NpZ25IZXgnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gc2lnbkhleChoZXgsIHByaXZhdGVfa2V5KSB7XG4gICAgICAgICAgICB2YXIgYnVmO1xuICAgICAgICAgICAgYnVmID0gbmV3IEJ1ZmZlcihoZXgsICdoZXgnKTtcbiAgICAgICAgICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlcihidWYsIHByaXZhdGVfa2V5KTtcbiAgICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBTaWduYXR1cmU7XG59KCk7XG5cbm1vZHVsZS5leHBvcnRzID0gU2lnbmF0dXJlOyIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgICAvLyBQcmltYXJ5IGNsYXNzIGZvciBjcmVhdGluZyBvcGVyYXRpb25zXG4gICAgU2VyaWFsaXplcjogcmVxdWlyZSgnLi9zcmMvc2VyaWFsaXplcicpLFxuXG4gICAgLy8gaGVscGVyIGZ1bmN0aW9ucyBmb3IgY3JlYXRpbmcgb3BlcmF0aW9uc1xuICAgIGZwOiByZXF1aXJlKCcuL3NyYy9GYXN0UGFyc2VyJyksXG5cbiAgICAvLyBMb3cgbGV2ZWwgdHlwZXNcbiAgICB0eXBlczogcmVxdWlyZSgnLi9zcmMvdHlwZXMnKSxcblxuICAgIC8vIEhpZ2hlciBsZXZlbCBvcGVyYXRpb25zIChtYWRlIG91dCBvZiBnZW5lcmljIHR5cGVzKVxuICAgIG9wczogcmVxdWlyZSgnLi9zcmMvb3BlcmF0aW9ucycpLFxuXG4gICAgLy8gVXRpbGl0eSB0aGF0IGdlbmVyYXRlcyBKU09OIGV4YW1wbGVzXG4gICAgdGVtcGxhdGU6IHJlcXVpcmUoJy4vc3JjL3RlbXBsYXRlJyksXG5cbiAgICAvLyBTZXJpYWxpemVyIHZhbGlkYXRpb25cbiAgICBTZXJpYWxpemVyVmFsaWRhdGlvbjogcmVxdWlyZSgnLi9zcmMvU2VyaWFsaXplclZhbGlkYXRpb24nKVxufTsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBQdWJsaWNLZXkgPSByZXF1aXJlKFwiLi4vLi4vZWNjL3NyYy9QdWJsaWNLZXlcIik7XG5cbnZhciBGYXN0UGFyc2VyID0gZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEZhc3RQYXJzZXIoKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBGYXN0UGFyc2VyKTtcbiAgICB9XG5cbiAgICBfY3JlYXRlQ2xhc3MoRmFzdFBhcnNlciwgbnVsbCwgW3tcbiAgICAgICAga2V5OiAnZml4ZWRfZGF0YScsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmaXhlZF9kYXRhKGIsIGxlbiwgYnVmZmVyKSB7XG4gICAgICAgICAgICBpZiAoIWIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBidWZmZXIuc2xpY2UoMCwgbGVuKS50b1N0cmluZygnYmluYXJ5Jyk7XG4gICAgICAgICAgICAgICAgYi5hcHBlbmQoZGF0YSwgJ2JpbmFyeScpO1xuICAgICAgICAgICAgICAgIHdoaWxlIChsZW4tLSA+IGRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGIud3JpdGVVaW50OCgwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgbGVuKTtcbiAgICAgICAgICAgICAgICBiLnNraXAobGVuKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihiX2NvcHkudG9CaW5hcnkoKSwgJ2JpbmFyeScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdwdWJsaWNfa2V5JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHB1YmxpY19rZXkoYiwgX3B1YmxpY19rZXkpIHtcbiAgICAgICAgICAgIGlmICghYikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChfcHVibGljX2tleSkge1xuICAgICAgICAgICAgICAgIHZhciBidWZmZXIgPSBfcHVibGljX2tleS50b0J1ZmZlcigpO1xuICAgICAgICAgICAgICAgIGIuYXBwZW5kKGJ1ZmZlci50b1N0cmluZygnYmluYXJ5JyksICdiaW5hcnknKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGJ1ZmZlciA9IEZhc3RQYXJzZXIuZml4ZWRfZGF0YShiLCAzMyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tQnVmZmVyKGJ1ZmZlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3JpcGVtZDE2MCcsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiByaXBlbWQxNjAoYiwgX3JpcGVtZCkge1xuICAgICAgICAgICAgaWYgKCFiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKF9yaXBlbWQpIHtcbiAgICAgICAgICAgICAgICBGYXN0UGFyc2VyLmZpeGVkX2RhdGEoYiwgMjAsIF9yaXBlbWQpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEZhc3RQYXJzZXIuZml4ZWRfZGF0YShiLCAyMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3NoYTI1NicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzaGEyNTYoYiwgX3NoYSkge1xuICAgICAgICAgICAgaWYgKCFiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKF9zaGEpIHtcbiAgICAgICAgICAgICAgICBGYXN0UGFyc2VyLmZpeGVkX2RhdGEoYiwgMzIsIF9zaGEpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEZhc3RQYXJzZXIuZml4ZWRfZGF0YShiLCAzMik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3RpbWVfcG9pbnRfc2VjJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRpbWVfcG9pbnRfc2VjKGIsIGVwb2NoKSB7XG4gICAgICAgICAgICBpZiAoZXBvY2gpIHtcbiAgICAgICAgICAgICAgICBlcG9jaCA9IE1hdGguY2VpbChlcG9jaCAvIDEwMDApO1xuICAgICAgICAgICAgICAgIGIud3JpdGVJbnQzMihlcG9jaCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBlcG9jaCA9IGIucmVhZEludDMyKCk7IC8vIGZjOjp0aW1lX3BvaW50X3NlY1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZShlcG9jaCAqIDEwMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIEZhc3RQYXJzZXI7XG59KCk7XG5cbm1vZHVsZS5leHBvcnRzID0gRmFzdFBhcnNlcjsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnYnl0ZWJ1ZmZlcicpLFxuICAgIExvbmcgPSBfcmVxdWlyZS5Mb25nO1xuXG52YXIgQ2hhaW5UeXBlcyA9IHJlcXVpcmUoJy4uLy4uL2NoYWluL3NyYy9DaGFpblR5cGVzJyk7XG5cbnZhciBNQVhfU0FGRV9JTlQgPSA5MDA3MTk5MjU0NzQwOTkxO1xudmFyIE1JTl9TQUZFX0lOVCA9IC05MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAgICBNb3N0IHZhbGlkYXRpb25zIGFyZSBza2lwcGVkIGFuZCB0aGUgdmFsdWUgcmV0dXJuZWQgdW5jaGFuZ2VkIHdoZW4gYW4gZW1wdHkgc3RyaW5nLCBudWxsLCBvciB1bmRlZmluZWQgaXMgZW5jb3VudGVyZWQgKGV4Y2VwdCBcInJlcXVpcmVkXCIpLlxuXG4gICAgVmFsaWRhdGlvbnMgc3VwcG9ydCBhIHN0cmluZyBmb3JtYXQgZm9yIGRlYWxpbmcgd2l0aCBsYXJnZSBudW1iZXJzLlxuKi9cbnZhciBfbXkgPSB7XG5cbiAgICBpc19lbXB0eTogZnVuY3Rpb24gaXNfZW1wdHkodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQ7XG4gICAgfSxcblxuICAgIHJlcXVpcmVkOiBmdW5jdGlvbiByZXF1aXJlZCh2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcblxuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndmFsdWUgcmVxdWlyZWQgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gICAgcmVxdWlyZV9sb25nOiBmdW5jdGlvbiByZXF1aXJlX2xvbmcodmFsdWUpIHtcbiAgICAgICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFwiXCI7XG5cbiAgICAgICAgaWYgKCFMb25nLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTG9uZyB2YWx1ZSByZXF1aXJlZCAnICsgZmllbGRfbmFtZSArICcgJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcbiAgICBzdHJpbmc6IGZ1bmN0aW9uIHN0cmluZyh2YWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmluZyByZXF1aXJlZDogJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcbiAgICBudW1iZXI6IGZ1bmN0aW9uIG51bWJlcih2YWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ251bWJlciByZXF1aXJlZDogJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcbiAgICB3aG9sZV9udW1iZXI6IGZ1bmN0aW9uIHdob2xlX251bWJlcih2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcblxuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcLi8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignd2hvbGUgbnVtYmVyIHJlcXVpcmVkICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuICAgIHVuc2lnbmVkOiBmdW5jdGlvbiB1bnNpZ25lZCh2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcblxuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoLy0vLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc2lnbmVkIHJlcXVpcmVkICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuXG5cbiAgICBpc19kaWdpdHM6IGZ1bmN0aW9uIGlzX2RpZ2l0cyh2YWx1ZSkge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWVyaWNcIikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICgvXlswLTldKyQvLnRlc3QodmFsdWUpXG4gICAgICAgICk7XG4gICAgfSxcblxuICAgIHRvX251bWJlcjogZnVuY3Rpb24gdG9fbnVtYmVyKHZhbHVlKSB7XG4gICAgICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBcIlwiO1xuXG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm9fb3ZlcmZsb3c1Myh2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgICAgIHZhciBpbnRfdmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KCk7XG4gICAgICAgIHJldHVybiBpbnRfdmFsdWU7XG4gICAgfSxcblxuICAgIHRvX2xvbmc6IGZ1bmN0aW9uIHRvX2xvbmcodmFsdWUpIHtcbiAgICAgICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFwiXCI7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKExvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5ub19vdmVyZmxvdzY0KHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgdmFsdWUgPSBcIlwiICsgdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgfSxcbiAgICB0b191bG9uZzogZnVuY3Rpb24gdG9fdWxvbmcodmFsdWUpIHtcbiAgICAgICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFwiXCI7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKExvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5ub19vdmVyZmxvdzY0KHZhbHVlLCBmaWVsZF9uYW1lLCB0cnVlKTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgdmFsdWUgPSBcIlwiICsgdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIExvbmcuZnJvbVN0cmluZyh2YWx1ZSwgdHJ1ZSk7XG4gICAgfSxcbiAgICB0b19zdHJpbmc6IGZ1bmN0aW9uIHRvX3N0cmluZyh2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcblxuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgdGhpcy5ub19vdmVyZmxvdzUzKHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICAgICAgICAgIHJldHVybiBcIlwiICsgdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKExvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgJ3Vuc3VwcG9ydGVkIHR5cGUgJyArIGZpZWxkX25hbWUgKyAnOiAoJyArICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHZhbHVlKSkgKyAnKSAnICsgdmFsdWU7XG4gICAgfSxcbiAgICByZXF1aXJlX3Rlc3Q6IGZ1bmN0aW9uIHJlcXVpcmVfdGVzdChyZWdleCwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IFwiXCI7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyZWdleC50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bm1hdGNoZWQgJyArIHJlZ2V4ICsgJyAnICsgZmllbGRfbmFtZSArICcgJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcblxuXG4gICAgcmVxdWlyZV9tYXRjaDogZnVuY3Rpb24gcmVxdWlyZV9tYXRjaChyZWdleCwgdmFsdWUpIHtcbiAgICAgICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IFwiXCI7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG1hdGNoID0gdmFsdWUubWF0Y2gocmVnZXgpO1xuICAgICAgICBpZiAobWF0Y2ggPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndW5tYXRjaGVkICcgKyByZWdleCArICcgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0sXG5cbiAgICByZXF1aXJlX29iamVjdF9pZDogZnVuY3Rpb24gcmVxdWlyZV9vYmplY3RfaWQodmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICAgICAgcmV0dXJuIHJlcXVpcmVfbWF0Y2goL14oWzAtOV0rKVxcLihbMC05XSspXFwuKFswLTldKykkLywgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgIH0sXG5cbiAgICAvLyBEb2VzIG5vdCBzdXBwb3J0IG92ZXIgNTMgYml0c1xuICAgIHJlcXVpcmVfcmFuZ2U6IGZ1bmN0aW9uIHJlcXVpcmVfcmFuZ2UobWluLCBtYXgsIHZhbHVlKSB7XG4gICAgICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiBcIlwiO1xuXG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBudW1iZXIgPSB0aGlzLnRvX251bWJlcih2YWx1ZSk7XG4gICAgICAgIGlmICh2YWx1ZSA8IG1pbiB8fCB2YWx1ZSA+IG1heCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdvdXQgb2YgcmFuZ2UgJyArIHZhbHVlICsgJyAnICsgZmllbGRfbmFtZSArICcgJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcblxuXG4gICAgcmVxdWlyZV9vYmplY3RfdHlwZTogZnVuY3Rpb24gcmVxdWlyZV9vYmplY3RfdHlwZSgpIHtcbiAgICAgICAgdmFyIHJlc2VydmVkX3NwYWNlcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogMTtcbiAgICAgICAgdmFyIHR5cGUgPSBhcmd1bWVudHNbMV07XG4gICAgICAgIHZhciB2YWx1ZSA9IGFyZ3VtZW50c1syXTtcbiAgICAgICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMyAmJiBhcmd1bWVudHNbM10gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1szXSA6IFwiXCI7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG9iamVjdF90eXBlID0gQ2hhaW5UeXBlcy5vYmplY3RfdHlwZVt0eXBlXTtcbiAgICAgICAgaWYgKCFvYmplY3RfdHlwZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG9iamVjdCB0eXBlICcgKyB0eXBlICsgJyAnICsgZmllbGRfbmFtZSArICcgJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKHJlc2VydmVkX3NwYWNlcyArICcuJyArIG9iamVjdF90eXBlICsgJy5bMC05XSskJyk7XG4gICAgICAgIGlmICghcmUudGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0aW5nICcgKyB0eXBlICsgJyBpbiBmb3JtYXQgJyArIChyZXNlcnZlZF9zcGFjZXMgKyAnLicgKyBvYmplY3RfdHlwZSArICcuWzAtOV0rICcpICsgKCdpbnN0ZWFkIG9mICcgKyB2YWx1ZSArICcgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuXG4gICAgZ2V0X2luc3RhbmNlOiBmdW5jdGlvbiBnZXRfaW5zdGFuY2UocmVzZXJ2ZV9zcGFjZXMsIHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVxdWlyZV9vYmplY3RfdHlwZShyZXNlcnZlX3NwYWNlcywgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy50b19udW1iZXIodmFsdWUuc3BsaXQoJy4nKVsyXSk7XG4gICAgfSxcblxuICAgIHJlcXVpcmVfcmVsYXRpdmVfdHlwZTogZnVuY3Rpb24gcmVxdWlyZV9yZWxhdGl2ZV90eXBlKHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgICAgIHRoaXMucmVxdWlyZV9vYmplY3RfdHlwZSgwLCB0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuXG4gICAgZ2V0X3JlbGF0aXZlX2luc3RhbmNlOiBmdW5jdGlvbiBnZXRfcmVsYXRpdmVfaW5zdGFuY2UodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXF1aXJlX29iamVjdF90eXBlKDAsIHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9fbnVtYmVyKHZhbHVlLnNwbGl0KCcuJylbMl0pO1xuICAgIH0sXG5cbiAgICByZXF1aXJlX3Byb3RvY29sX3R5cGU6IGZ1bmN0aW9uIHJlcXVpcmVfcHJvdG9jb2xfdHlwZSh0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSkge1xuICAgICAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMSwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcblxuICAgIGdldF9wcm90b2NvbF9pbnN0YW5jZTogZnVuY3Rpb24gZ2V0X3Byb3RvY29sX2luc3RhbmNlKHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVxdWlyZV9vYmplY3RfdHlwZSgxLCB0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdCgnLicpWzJdKTtcbiAgICB9LFxuXG4gICAgZ2V0X3Byb3RvY29sX3R5cGU6IGZ1bmN0aW9uIGdldF9wcm90b2NvbF90eXBlKHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVxdWlyZV9vYmplY3RfaWQodmFsdWUsIGZpZWxkX25hbWUpO1xuICAgICAgICB2YXIgdmFsdWVzID0gdmFsdWUuc3BsaXQoJy4nKTtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9fbnVtYmVyKHZhbHVlc1sxXSk7XG4gICAgfSxcblxuICAgIGdldF9wcm90b2NvbF90eXBlX25hbWU6IGZ1bmN0aW9uIGdldF9wcm90b2NvbF90eXBlX25hbWUodmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHR5cGVfaWQgPSB0aGlzLmdldF9wcm90b2NvbF90eXBlKHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKENoYWluVHlwZXMub2JqZWN0X3R5cGUpW3R5cGVfaWRdO1xuICAgIH0sXG5cblxuICAgIHJlcXVpcmVfaW1wbGVtZW50YXRpb25fdHlwZTogZnVuY3Rpb24gcmVxdWlyZV9pbXBsZW1lbnRhdGlvbl90eXBlKHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgICAgIHRoaXMucmVxdWlyZV9vYmplY3RfdHlwZSgyLCB0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuXG4gICAgZ2V0X2ltcGxlbWVudGF0aW9uX2luc3RhbmNlOiBmdW5jdGlvbiBnZXRfaW1wbGVtZW50YXRpb25faW5zdGFuY2UodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXF1aXJlX29iamVjdF90eXBlKDIsIHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9fbnVtYmVyKHZhbHVlLnNwbGl0KCcuJylbMl0pO1xuICAgIH0sXG5cbiAgICAvLyBzaWduZWQgLyB1bnNpZ25lZCBkZWNpbWFsXG4gICAgbm9fb3ZlcmZsb3c1MzogZnVuY3Rpb24gbm9fb3ZlcmZsb3c1Myh2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcblxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPiBNQVhfU0FGRV9JTlQgfHwgdmFsdWUgPCBNSU5fU0FGRV9JTlQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ292ZXJmbG93ICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHZhciBpbnQgPSBwYXJzZUludCh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAodmFsdWUgPiBNQVhfU0FGRV9JTlQgfHwgdmFsdWUgPCBNSU5fU0FGRV9JTlQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ292ZXJmbG93ICcgKyBmaWVsZF9uYW1lICsgJyAnICsgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChMb25nLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIC8vIHR5cGVvZiB2YWx1ZS50b0ludCgpIGlzICdudW1iZXInXG4gICAgICAgICAgICB0aGlzLm5vX292ZXJmbG93NTModmFsdWUudG9JbnQoKSwgZmllbGRfbmFtZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgJ3Vuc3VwcG9ydGVkIHR5cGUgJyArIGZpZWxkX25hbWUgKyAnOiAoJyArICh0eXBlb2YgdmFsdWUgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHZhbHVlKSkgKyAnKSAnICsgdmFsdWU7XG4gICAgfSxcblxuXG4gICAgLy8gc2lnbmVkIC8gdW5zaWduZWQgd2hvbGUgbnVtYmVycyBvbmx5XG4gICAgbm9fb3ZlcmZsb3c2NDogZnVuY3Rpb24gbm9fb3ZlcmZsb3c2NCh2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcbiAgICAgICAgdmFyIHVuc2lnbmVkID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBmYWxzZTtcblxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZGNvZGVJTy9Mb25nLmpzL2lzc3Vlcy8yMFxuICAgICAgICBpZiAoTG9uZy5pc0xvbmcodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCaWdJbnRlZ2VyI2lzQmlnSW50ZWdlciBodHRwczovL2dpdGh1Yi5jb20vY3J5cHRvY29pbmpzL2JpZ2kvaXNzdWVzLzIwXG4gICAgICAgIGlmICh2YWx1ZS50ICE9PSB1bmRlZmluZWQgJiYgdmFsdWUucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLm5vX292ZXJmbG93NjQodmFsdWUudG9TdHJpbmcoKSwgZmllbGRfbmFtZSwgdW5zaWduZWQpO1xuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgbGVhZGluZyB6ZXJvcywgd2lsbCBjYXVzZSBhIGZhbHNlIHBvc2l0aXZlXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoL14wKy8sICcnKTtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0cmFpbGluZyB6ZXJvc1xuICAgICAgICAgICAgd2hpbGUgKC8wJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZygwLCB2YWx1ZS5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICgvXFwuJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgZG90XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHJpbmcoMCwgdmFsdWUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IFwiMFwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgbG9uZ19zdHJpbmcgPSBMb25nLmZyb21TdHJpbmcodmFsdWUsIHVuc2lnbmVkKS50b1N0cmluZygpO1xuXG4gICAgICAgICAgICBpZiAobG9uZ19zdHJpbmcgIT09IHZhbHVlLnRyaW0oKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignb3ZlcmZsb3cgJyArIGZpZWxkX25hbWUgKyAnICcgKyB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgaWYgKHZhbHVlID4gTUFYX1NBRkVfSU5UIHx8IHZhbHVlIDwgTUlOX1NBRkVfSU5UKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdvdmVyZmxvdyAnICsgZmllbGRfbmFtZSArICcgJyArIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93ICd1bnN1cHBvcnRlZCB0eXBlICcgKyBmaWVsZF9uYW1lICsgJzogKCcgKyAodHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZih2YWx1ZSkpICsgJykgJyArIHZhbHVlO1xuICAgIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gX215OyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSgpO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG4vKiogRXhjZXB0aW9uIG5lc3RpbmcuICAqL1xudmFyIEVycm9yV2l0aENhdXNlID0gZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEVycm9yV2l0aENhdXNlKG1lc3NhZ2UsIGNhdXNlKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFcnJvcldpdGhDYXVzZSk7XG5cbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYXVzZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjYXVzZSAhPT0gbnVsbCA/IGNhdXNlLm1lc3NhZ2UgOiB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IFwiY2F1c2VcXHRcIiArIGNhdXNlLm1lc3NhZ2UgKyBcIlxcdFwiICsgdGhpcy5tZXNzYWdlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0YWNrID0gXCJcIjsgLy8obmV3IEVycm9yKS5zdGFja1xuICAgICAgICBpZiAodHlwZW9mIGNhdXNlICE9PSBcInVuZGVmaW5lZFwiICYmIGNhdXNlICE9PSBudWxsID8gY2F1c2Uuc3RhY2sgOiB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHN0YWNrID0gXCJjYXVzZWQgYnlcXG5cXHRcIiArIGNhdXNlLnN0YWNrICsgXCJcXHRcIiArIHN0YWNrO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdGFjayA9IHRoaXMubWVzc2FnZSArIFwiXFxuXCIgKyBzdGFjaztcbiAgICB9XG5cbiAgICBfY3JlYXRlQ2xhc3MoRXJyb3JXaXRoQ2F1c2UsIG51bGwsIFt7XG4gICAgICAgIGtleTogXCJ0aHJvd1wiLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gX3Rocm93KG1lc3NhZ2UsIGNhdXNlKSB7XG4gICAgICAgICAgICB2YXIgbXNnID0gbWVzc2FnZTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY2F1c2UgIT09IFwidW5kZWZpbmVkXCIgJiYgY2F1c2UgIT09IG51bGwgPyBjYXVzZS5tZXNzYWdlIDogdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbXNnICs9IFwiXFx0IGNhdXNlOiBcIiArIGNhdXNlLm1lc3NhZ2UgKyBcIiBcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgY2F1c2UgIT09IFwidW5kZWZpbmVkXCIgJiYgY2F1c2UgIT09IG51bGwgPyBjYXVzZS5zdGFjayA6IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG1zZyArPSBcIlxcbiBzdGFjazogXCIgKyBjYXVzZS5zdGFjayArIFwiIFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gRXJyb3JXaXRoQ2F1c2U7XG59KCk7XG5cbm1vZHVsZS5leHBvcnRzID0gRXJyb3JXaXRoQ2F1c2U7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciB0eXBlcyA9IHJlcXVpcmUoXCIuL3R5cGVzXCIpO1xudmFyIFNlcmlhbGl6ZXJJbXBsID0gcmVxdWlyZShcIi4vc2VyaWFsaXplclwiKTtcblxudmFyIHVpbnQ4ID0gdHlwZXMudWludDgsXG4gICAgdWludDE2ID0gdHlwZXMudWludDE2LFxuICAgIHVpbnQzMiA9IHR5cGVzLnVpbnQzMixcbiAgICBpbnQ2NCA9IHR5cGVzLmludDY0LFxuICAgIHVpbnQ2NCA9IHR5cGVzLnVpbnQ2NCxcbiAgICBzdHJpbmcgPSB0eXBlcy5zdHJpbmcsXG4gICAgYnl0ZXMgPSB0eXBlcy5ieXRlcyxcbiAgICBib29sID0gdHlwZXMuYm9vbCxcbiAgICBhcnJheSA9IHR5cGVzLmFycmF5LFxuICAgIGZpeGVkX2FycmF5ID0gdHlwZXMuZml4ZWRfYXJyYXksXG4gICAgcHJvdG9jb2xfaWRfdHlwZSA9IHR5cGVzLnByb3RvY29sX2lkX3R5cGUsXG4gICAgb2JqZWN0X2lkX3R5cGUgPSB0eXBlcy5vYmplY3RfaWRfdHlwZSxcbiAgICB2b3RlX2lkID0gdHlwZXMudm90ZV9pZCxcbiAgICBmdXR1cmVfZXh0ZW5zaW9ucyA9IHR5cGVzLmZ1dHVyZV9leHRlbnNpb25zLFxuICAgIHN0YXRpY192YXJpYW50ID0gdHlwZXMuc3RhdGljX3ZhcmlhbnQsXG4gICAgbWFwID0gdHlwZXMubWFwLFxuICAgIHNldCA9IHR5cGVzLnNldCxcbiAgICBwdWJsaWNfa2V5ID0gdHlwZXMucHVibGljX2tleSxcbiAgICBhZGRyZXNzID0gdHlwZXMuYWRkcmVzcyxcbiAgICB0aW1lX3BvaW50X3NlYyA9IHR5cGVzLnRpbWVfcG9pbnRfc2VjLFxuICAgIG9wdGlvbmFsID0gdHlwZXMub3B0aW9uYWwsXG4gICAgdmFyaWFudCA9IHR5cGVzLnZhcmlhbnQsXG4gICAgdmFyaWFudF9vYmplY3QgPSB0eXBlcy52YXJpYW50X29iamVjdCxcbiAgICBlbnVtZXJhdGlvbiA9IHR5cGVzLmVudW1lcmF0aW9uLFxuICAgIHNoYTI1NiA9IHR5cGVzLnNoYTI1NjtcblxuXG5mdXR1cmVfZXh0ZW5zaW9ucyA9IHR5cGVzLnZvaWQ7XG5cbi8qXG5XaGVuIHVwZGF0aW5nIGdlbmVyYXRlZCBjb2RlXG5SZXBsYWNlOiAgb3BlcmF0aW9uID0gc3RhdGljX3ZhcmlhbnQgW1xud2l0aDogICAgIG9wZXJhdGlvbi5zdF9vcGVyYXRpb25zID0gW1xuXG5EZWxldGU6XG5wdWJsaWNfa2V5ID0gbmV3IFNlcmlhbGl6ZXIoIFxuICAgIFwicHVibGljX2tleVwiXG4gICAga2V5X2RhdGE6IGJ5dGVzIDMzXG4pXG5cbiovXG4vLyBQbGFjZS1ob2xkZXIsIHRoZWlyIGFyZSBkZXBlbmRlbmNpZXMgb24gXCJvcGVyYXRpb25cIiAuLiBUaGUgZmluYWwgbGlzdCBvZlxuLy8gb3BlcmF0aW9ucyBpcyBub3QgYXZpYWxibGUgdW50aWwgdGhlIHZlcnkgZW5kIG9mIHRoZSBnZW5lcmF0ZWQgY29kZS5cbi8vIFNlZTogb3BlcmF0aW9uLnN0X29wZXJhdGlvbnMgPSAuLi5cbnZhciBvcGVyYXRpb24gPSBzdGF0aWNfdmFyaWFudCgpO1xubW9kdWxlLmV4cG9ydHNbXCJvcGVyYXRpb25cIl0gPSBvcGVyYXRpb247XG5cbi8vIEZvciBtb2R1bGUuZXhwb3J0c1xudmFyIFNlcmlhbGl6ZXIgPSBmdW5jdGlvbiBTZXJpYWxpemVyKG9wZXJhdGlvbl9uYW1lLCBzZXJpbGl6YXRpb25fdHlwZXNfb2JqZWN0KSB7XG4gICAgdmFyIHMgPSBuZXcgU2VyaWFsaXplckltcGwob3BlcmF0aW9uX25hbWUsIHNlcmlsaXphdGlvbl90eXBlc19vYmplY3QpO1xuICAgIHJldHVybiBtb2R1bGUuZXhwb3J0c1tvcGVyYXRpb25fbmFtZV0gPSBzO1xufTtcblxuLy8gQ3VzdG9tLXR5cGVzIGZvbGxvdyBHZW5lcmF0ZWQgY29kZTpcblxuLy8gIyMgIEdlbmVyYXRlZCBjb2RlIGZvbGxvd3Ncbi8vICMgcHJvZ3JhbXMvanNfb3BlcmF0aW9uX3NlcmlhbGl6ZXIgPiBucG0gaSAtZyBkZWNhZmZlaW5hdGVcbi8vICMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbnZhciB0cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcInRyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyIH0pO1xuXG52YXIgbGltaXRfb3JkZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwibGltaXRfb3JkZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgbGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwibGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgY2FsbF9vcmRlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJjYWxsX29yZGVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGZpbGxfb3JkZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJmaWxsX29yZGVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiKTtcblxudmFyIGFjY291bnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYWNjb3VudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgYmFzaWNfZmVlOiB1aW50NjQsXG4gICAgcHJlbWl1bV9mZWU6IHVpbnQ2NCxcbiAgICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMiB9KTtcblxudmFyIGFjY291bnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYWNjb3VudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiBpbnQ2NCxcbiAgICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMiB9KTtcblxudmFyIGFjY291bnRfd2hpdGVsaXN0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiBpbnQ2NCB9KTtcblxudmFyIGFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBtZW1iZXJzaGlwX2FubnVhbF9mZWU6IHVpbnQ2NCxcbiAgICBtZW1iZXJzaGlwX2xpZmV0aW1lX2ZlZTogdWludDY0IH0pO1xuXG52YXIgYWNjb3VudF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFjY291bnRfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQgfSk7XG5cbnZhciBhc3NldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgc3ltYm9sMzogdWludDY0LFxuICAgIHN5bWJvbDQ6IHVpbnQ2NCxcbiAgICBsb25nX3N5bWJvbDogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyIH0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyIH0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9pc3N1ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCxcbiAgICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMiB9KTtcblxudmFyIGFzc2V0X3Jlc2VydmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9yZXNlcnZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgYXNzZXRfZnVuZF9mZWVfcG9vbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQgfSk7XG5cbnZhciBhc3NldF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQgfSk7XG5cbnZhciBhc3NldF9nbG9iYWxfc2V0dGxlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfZ2xvYmFsX3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGFzc2V0X3B1Ymxpc2hfZmVlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X3B1Ymxpc2hfZmVlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIHdpdG5lc3NfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwid2l0bmVzc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQgfSk7XG5cbnZhciB3aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcIndpdG5lc3NfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogaW50NjQgfSk7XG5cbnZhciBwcm9wb3NhbF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJwcm9wb3NhbF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQsXG4gICAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzIgfSk7XG5cbnZhciBwcm9wb3NhbF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJwcm9wb3NhbF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQsXG4gICAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzIgfSk7XG5cbnZhciBwcm9wb3NhbF9kZWxldGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJwcm9wb3NhbF9kZWxldGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQgfSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcIndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ3aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIHdpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyIH0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl9kZWxldGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiY29tbWl0dGVlX21lbWJlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQgfSk7XG5cbnZhciBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIHZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwidmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgd29ya2VyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcIndvcmtlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQgfSk7XG5cbnZhciBjdXN0b21fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJjdXN0b21fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQsXG4gICAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzIgfSk7XG5cbnZhciBhc3NlcnRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NlcnRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQgfSk7XG5cbnZhciBiYWxhbmNlX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYmFsYW5jZV9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIik7XG5cbnZhciBvdmVycmlkZV90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcIm92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyIH0pO1xuXG52YXIgdHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ0cmFuc2Zlcl90b19ibGluZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCxcbiAgICBwcmljZV9wZXJfb3V0cHV0OiB1aW50MzIgfSk7XG5cbnZhciBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImJsaW5kX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9vdXRwdXQ6IHVpbnQzMiB9KTtcblxudmFyIHRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ0cmFuc2Zlcl9mcm9tX2JsaW5kX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgYXNzZXRfc2V0dGxlX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X3NldHRsZV9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIpO1xuXG52YXIgYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X2NsYWltX2ZlZXNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiB1aW50NjQgfSk7XG5cbnZhciBmYmFfZGlzdHJpYnV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7fSk7XG5cbnZhciB0b3VybmFtZW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcInRvdXJuYW1lbnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyIH0pO1xuXG52YXIgdG91cm5hbWVudF9qb2luX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwidG91cm5hbWVudF9qb2luX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgZmVlX3BhcmFtZXRlcnMgPSBzdGF0aWNfdmFyaWFudChbdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBsaW1pdF9vcmRlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBsaW1pdF9vcmRlcl9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBjYWxsX29yZGVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGZpbGxfb3JkZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFjY291bnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X3VwZ3JhZGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9yZXNlcnZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfZnVuZF9mZWVfcG9vbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9wdWJsaXNoX2ZlZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRuZXNzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHdpdG5lc3NfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHdpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXdfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3b3JrZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYmFsYW5jZV9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIG92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgdHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgdG91cm5hbWVudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB0b3VybmFtZW50X2pvaW5fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXSk7XG5cbnZhciBmZWVfc2NoZWR1bGUgPSBuZXcgU2VyaWFsaXplcihcImZlZV9zY2hlZHVsZVwiLCB7IHBhcmFtZXRlcnM6IHNldChmZWVfcGFyYW1ldGVycyksXG4gICAgc2NhbGU6IHVpbnQzMiB9KTtcblxudmFyIHZvaWRfcmVzdWx0ID0gbmV3IFNlcmlhbGl6ZXIoXCJ2b2lkX3Jlc3VsdFwiKTtcblxudmFyIGFzc2V0ID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldFwiLCB7IGFtb3VudDogaW50NjQsXG4gICAgYXNzZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoXCJhc3NldFwiKSB9KTtcblxudmFyIG9wZXJhdGlvbl9yZXN1bHQgPSBzdGF0aWNfdmFyaWFudChbdm9pZF9yZXN1bHQsIG9iamVjdF9pZF90eXBlLCBhc3NldF0pO1xuXG52YXIgcHJvY2Vzc2VkX3RyYW5zYWN0aW9uID0gbmV3IFNlcmlhbGl6ZXIoXCJwcm9jZXNzZWRfdHJhbnNhY3Rpb25cIiwgeyByZWZfYmxvY2tfbnVtOiB1aW50MTYsXG4gICAgcmVmX2Jsb2NrX3ByZWZpeDogdWludDMyLFxuICAgIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICAgIG9wZXJhdGlvbnM6IGFycmF5KG9wZXJhdGlvbiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSxcbiAgICBzaWduYXR1cmVzOiBhcnJheShieXRlcyg2NSkpLFxuICAgIG9wZXJhdGlvbl9yZXN1bHRzOiBhcnJheShvcGVyYXRpb25fcmVzdWx0KSB9KTtcblxudmFyIHNpZ25lZF9ibG9jayA9IG5ldyBTZXJpYWxpemVyKFwic2lnbmVkX2Jsb2NrXCIsIHsgcHJldmlvdXM6IGJ5dGVzKDIwKSxcbiAgICB0aW1lc3RhbXA6IHRpbWVfcG9pbnRfc2VjLFxuICAgIHdpdG5lc3M6IHByb3RvY29sX2lkX3R5cGUoXCJ3aXRuZXNzXCIpLFxuICAgIHRyYW5zYWN0aW9uX21lcmtsZV9yb290OiBieXRlcygyMCksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSxcbiAgICB3aXRuZXNzX3NpZ25hdHVyZTogYnl0ZXMoNjUpLFxuICAgIHRyYW5zYWN0aW9uczogYXJyYXkocHJvY2Vzc2VkX3RyYW5zYWN0aW9uKSB9KTtcblxudmFyIGJsb2NrX2hlYWRlciA9IG5ldyBTZXJpYWxpemVyKFwiYmxvY2tfaGVhZGVyXCIsIHsgcHJldmlvdXM6IGJ5dGVzKDIwKSxcbiAgICB0aW1lc3RhbXA6IHRpbWVfcG9pbnRfc2VjLFxuICAgIHdpdG5lc3M6IHByb3RvY29sX2lkX3R5cGUoXCJ3aXRuZXNzXCIpLFxuICAgIHRyYW5zYWN0aW9uX21lcmtsZV9yb290OiBieXRlcygyMCksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIHNpZ25lZF9ibG9ja19oZWFkZXIgPSBuZXcgU2VyaWFsaXplcihcInNpZ25lZF9ibG9ja19oZWFkZXJcIiwgeyBwcmV2aW91czogYnl0ZXMoMjApLFxuICAgIHRpbWVzdGFtcDogdGltZV9wb2ludF9zZWMsXG4gICAgd2l0bmVzczogcHJvdG9jb2xfaWRfdHlwZShcIndpdG5lc3NcIiksXG4gICAgdHJhbnNhY3Rpb25fbWVya2xlX3Jvb3Q6IGJ5dGVzKDIwKSxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICAgIHdpdG5lc3Nfc2lnbmF0dXJlOiBieXRlcyg2NSkgfSk7XG5cbnZhciBtZW1vX2RhdGEgPSBuZXcgU2VyaWFsaXplcihcIm1lbW9fZGF0YVwiLCB7IGZyb206IHB1YmxpY19rZXksXG4gICAgdG86IHB1YmxpY19rZXksXG4gICAgbm9uY2U6IHVpbnQ2NCxcbiAgICBtZXNzYWdlOiBieXRlcygpIH0pO1xuXG52YXIgdHJhbnNmZXIgPSBuZXcgU2VyaWFsaXplcihcInRyYW5zZmVyXCIsIHsgZmVlOiBhc3NldCxcbiAgICBmcm9tOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICB0bzogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYW1vdW50OiBhc3NldCxcbiAgICBtZW1vOiBvcHRpb25hbChtZW1vX2RhdGEpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBsaW1pdF9vcmRlcl9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcihcImxpbWl0X29yZGVyX2NyZWF0ZVwiLCB7IGZlZTogYXNzZXQsXG4gICAgc2VsbGVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhbW91bnRfdG9fc2VsbDogYXNzZXQsXG4gICAgbWluX3RvX3JlY2VpdmU6IGFzc2V0LFxuICAgIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICAgIGZpbGxfb3Jfa2lsbDogYm9vbCxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG52YXIgbGltaXRfb3JkZXJfY2FuY2VsID0gbmV3IFNlcmlhbGl6ZXIoXCJsaW1pdF9vcmRlcl9jYW5jZWxcIiwgeyBmZWU6IGFzc2V0LFxuICAgIGZlZV9wYXlpbmdfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgb3JkZXI6IHByb3RvY29sX2lkX3R5cGUoXCJsaW1pdF9vcmRlclwiKSxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG52YXIgY2FsbF9vcmRlcl91cGRhdGUgPSBuZXcgU2VyaWFsaXplcihcImNhbGxfb3JkZXJfdXBkYXRlXCIsIHsgZmVlOiBhc3NldCxcbiAgICBmdW5kaW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGRlbHRhX2NvbGxhdGVyYWw6IGFzc2V0LFxuICAgIGRlbHRhX2RlYnQ6IGFzc2V0LFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBmaWxsX29yZGVyID0gbmV3IFNlcmlhbGl6ZXIoXCJmaWxsX29yZGVyXCIsIHsgZmVlOiBhc3NldCxcbiAgICBvcmRlcl9pZDogb2JqZWN0X2lkX3R5cGUsXG4gICAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgcGF5czogYXNzZXQsXG4gICAgcmVjZWl2ZXM6IGFzc2V0IH0pO1xuXG52YXIgYXV0aG9yaXR5ID0gbmV3IFNlcmlhbGl6ZXIoXCJhdXRob3JpdHlcIiwgeyB3ZWlnaHRfdGhyZXNob2xkOiB1aW50MzIsXG4gICAgYWNjb3VudF9hdXRoczogbWFwKHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLCB1aW50MTYpLFxuICAgIGtleV9hdXRoczogbWFwKHB1YmxpY19rZXksIHVpbnQxNiksXG4gICAgYWRkcmVzc19hdXRoczogbWFwKGFkZHJlc3MsIHVpbnQxNikgfSk7XG5cbnZhciBhY2NvdW50X29wdGlvbnMgPSBuZXcgU2VyaWFsaXplcihcImFjY291bnRfb3B0aW9uc1wiLCB7IG1lbW9fa2V5OiBwdWJsaWNfa2V5LFxuICAgIHZvdGluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBudW1fd2l0bmVzczogdWludDE2LFxuICAgIG51bV9jb21taXR0ZWU6IHVpbnQxNixcbiAgICB2b3Rlczogc2V0KHZvdGVfaWQpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBhY2NvdW50X2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKFwiYWNjb3VudF9jcmVhdGVcIiwgeyBmZWU6IGFzc2V0LFxuICAgIHJlZ2lzdHJhcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgcmVmZXJyZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHJlZmVycmVyX3BlcmNlbnQ6IHVpbnQxNixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgb3duZXI6IGF1dGhvcml0eSxcbiAgICBhY3RpdmU6IGF1dGhvcml0eSxcbiAgICBvcHRpb25zOiBhY2NvdW50X29wdGlvbnMsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIGFjY291bnRfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJhY2NvdW50X3VwZGF0ZVwiLCB7IGZlZTogYXNzZXQsXG4gICAgYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgb3duZXI6IG9wdGlvbmFsKGF1dGhvcml0eSksXG4gICAgYWN0aXZlOiBvcHRpb25hbChhdXRob3JpdHkpLFxuICAgIG5ld19vcHRpb25zOiBvcHRpb25hbChhY2NvdW50X29wdGlvbnMpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBhY2NvdW50X3doaXRlbGlzdCA9IG5ldyBTZXJpYWxpemVyKFwiYWNjb3VudF93aGl0ZWxpc3RcIiwgeyBmZWU6IGFzc2V0LFxuICAgIGF1dGhvcml6aW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFjY291bnRfdG9fbGlzdDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgbmV3X2xpc3Rpbmc6IHVpbnQ4LFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBhY2NvdW50X3VwZ3JhZGUgPSBuZXcgU2VyaWFsaXplcihcImFjY291bnRfdXBncmFkZVwiLCB7IGZlZTogYXNzZXQsXG4gICAgYWNjb3VudF90b191cGdyYWRlOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICB1cGdyYWRlX3RvX2xpZmV0aW1lX21lbWJlcjogYm9vbCxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG52YXIgYWNjb3VudF90cmFuc2ZlciA9IG5ldyBTZXJpYWxpemVyKFwiYWNjb3VudF90cmFuc2ZlclwiLCB7IGZlZTogYXNzZXQsXG4gICAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgbmV3X293bmVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG52YXIgcHJpY2UgPSBuZXcgU2VyaWFsaXplcihcInByaWNlXCIsIHsgYmFzZTogYXNzZXQsXG4gICAgcXVvdGU6IGFzc2V0IH0pO1xuXG52YXIgYXNzZXRfb3B0aW9ucyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfb3B0aW9uc1wiLCB7IG1heF9zdXBwbHk6IGludDY0LFxuICAgIG1hcmtldF9mZWVfcGVyY2VudDogdWludDE2LFxuICAgIG1heF9tYXJrZXRfZmVlOiBpbnQ2NCxcbiAgICBpc3N1ZXJfcGVybWlzc2lvbnM6IHVpbnQxNixcbiAgICBmbGFnczogdWludDE2LFxuICAgIGNvcmVfZXhjaGFuZ2VfcmF0ZTogcHJpY2UsXG4gICAgd2hpdGVsaXN0X2F1dGhvcml0aWVzOiBzZXQocHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIikpLFxuICAgIGJsYWNrbGlzdF9hdXRob3JpdGllczogc2V0KHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpKSxcbiAgICB3aGl0ZWxpc3RfbWFya2V0czogc2V0KHByb3RvY29sX2lkX3R5cGUoXCJhc3NldFwiKSksXG4gICAgYmxhY2tsaXN0X21hcmtldHM6IHNldChwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIikpLFxuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmcsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIGJpdGFzc2V0X29wdGlvbnMgPSBuZXcgU2VyaWFsaXplcihcImJpdGFzc2V0X29wdGlvbnNcIiwgeyBmZWVkX2xpZmV0aW1lX3NlYzogdWludDMyLFxuICAgIG1pbmltdW1fZmVlZHM6IHVpbnQ4LFxuICAgIGZvcmNlX3NldHRsZW1lbnRfZGVsYXlfc2VjOiB1aW50MzIsXG4gICAgZm9yY2Vfc2V0dGxlbWVudF9vZmZzZXRfcGVyY2VudDogdWludDE2LFxuICAgIG1heGltdW1fZm9yY2Vfc2V0dGxlbWVudF92b2x1bWU6IHVpbnQxNixcbiAgICBzaG9ydF9iYWNraW5nX2Fzc2V0OiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIGFzc2V0X2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfY3JlYXRlXCIsIHsgZmVlOiBhc3NldCxcbiAgICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHN5bWJvbDogc3RyaW5nLFxuICAgIHByZWNpc2lvbjogdWludDgsXG4gICAgY29tbW9uX29wdGlvbnM6IGFzc2V0X29wdGlvbnMsXG4gICAgYml0YXNzZXRfb3B0czogb3B0aW9uYWwoYml0YXNzZXRfb3B0aW9ucyksXG4gICAgaXNfcHJlZGljdGlvbl9tYXJrZXQ6IGJvb2wsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIGFzc2V0X3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfdXBkYXRlXCIsIHsgZmVlOiBhc3NldCxcbiAgICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZShcImFzc2V0XCIpLFxuICAgIG5ld19pc3N1ZXI6IG9wdGlvbmFsKHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpKSxcbiAgICBuZXdfb3B0aW9uczogYXNzZXRfb3B0aW9ucyxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2JpdGFzc2V0ID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF91cGRhdGVfYml0YXNzZXRcIiwgeyBmZWU6IGFzc2V0LFxuICAgIGlzc3VlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXNzZXRfdG9fdXBkYXRlOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgbmV3X29wdGlvbnM6IGJpdGFzc2V0X29wdGlvbnMsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIGFzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2VycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzXCIsIHsgZmVlOiBhc3NldCxcbiAgICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZShcImFzc2V0XCIpLFxuICAgIG5ld19mZWVkX3Byb2R1Y2Vyczogc2V0KHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpKSxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG52YXIgYXNzZXRfaXNzdWUgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X2lzc3VlXCIsIHsgZmVlOiBhc3NldCxcbiAgICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFzc2V0X3RvX2lzc3VlOiBhc3NldCxcbiAgICBpc3N1ZV90b19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBtZW1vOiBvcHRpb25hbChtZW1vX2RhdGEpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBhc3NldF9yZXNlcnZlID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9yZXNlcnZlXCIsIHsgZmVlOiBhc3NldCxcbiAgICBwYXllcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYW1vdW50X3RvX3Jlc2VydmU6IGFzc2V0LFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBhc3NldF9mdW5kX2ZlZV9wb29sID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9mdW5kX2ZlZV9wb29sXCIsIHsgZmVlOiBhc3NldCxcbiAgICBmcm9tX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgYW1vdW50OiBpbnQ2NCxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG52YXIgYXNzZXRfc2V0dGxlID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9zZXR0bGVcIiwgeyBmZWU6IGFzc2V0LFxuICAgIGFjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFtb3VudDogYXNzZXQsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIGFzc2V0X2dsb2JhbF9zZXR0bGUgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X2dsb2JhbF9zZXR0bGVcIiwgeyBmZWU6IGFzc2V0LFxuICAgIGlzc3VlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXNzZXRfdG9fc2V0dGxlOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgc2V0dGxlX3ByaWNlOiBwcmljZSxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG52YXIgcHJpY2VfZmVlZCA9IG5ldyBTZXJpYWxpemVyKFwicHJpY2VfZmVlZFwiLCB7IHNldHRsZW1lbnRfcHJpY2U6IHByaWNlLFxuICAgIG1haW50ZW5hbmNlX2NvbGxhdGVyYWxfcmF0aW86IHVpbnQxNixcbiAgICBtYXhpbXVtX3Nob3J0X3NxdWVlemVfcmF0aW86IHVpbnQxNixcbiAgICBjb3JlX2V4Y2hhbmdlX3JhdGU6IHByaWNlIH0pO1xuXG52YXIgYXNzZXRfcHVibGlzaF9mZWVkID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9wdWJsaXNoX2ZlZWRcIiwgeyBmZWU6IGFzc2V0LFxuICAgIHB1Ymxpc2hlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXNzZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoXCJhc3NldFwiKSxcbiAgICBmZWVkOiBwcmljZV9mZWVkLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciB3aXRuZXNzX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKFwid2l0bmVzc19jcmVhdGVcIiwgeyBmZWU6IGFzc2V0LFxuICAgIHdpdG5lc3NfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgYmxvY2tfc2lnbmluZ19rZXk6IHB1YmxpY19rZXkgfSk7XG5cbnZhciB3aXRuZXNzX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKFwid2l0bmVzc191cGRhdGVcIiwgeyBmZWU6IGFzc2V0LFxuICAgIHdpdG5lc3M6IHByb3RvY29sX2lkX3R5cGUoXCJ3aXRuZXNzXCIpLFxuICAgIHdpdG5lc3NfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgbmV3X3VybDogb3B0aW9uYWwoc3RyaW5nKSxcbiAgICBuZXdfc2lnbmluZ19rZXk6IG9wdGlvbmFsKHB1YmxpY19rZXkpIH0pO1xuXG52YXIgb3Bfd3JhcHBlciA9IG5ldyBTZXJpYWxpemVyKFwib3Bfd3JhcHBlclwiLCB7IG9wOiBvcGVyYXRpb24gfSk7XG5cbnZhciBwcm9wb3NhbF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcihcInByb3Bvc2FsX2NyZWF0ZVwiLCB7IGZlZTogYXNzZXQsXG4gICAgZmVlX3BheWluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBleHBpcmF0aW9uX3RpbWU6IHRpbWVfcG9pbnRfc2VjLFxuICAgIHByb3Bvc2VkX29wczogYXJyYXkob3Bfd3JhcHBlciksXG4gICAgcmV2aWV3X3BlcmlvZF9zZWNvbmRzOiBvcHRpb25hbCh1aW50MzIpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBwcm9wb3NhbF91cGRhdGUgPSBuZXcgU2VyaWFsaXplcihcInByb3Bvc2FsX3VwZGF0ZVwiLCB7IGZlZTogYXNzZXQsXG4gICAgZmVlX3BheWluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBwcm9wb3NhbDogcHJvdG9jb2xfaWRfdHlwZShcInByb3Bvc2FsXCIpLFxuICAgIGFjdGl2ZV9hcHByb3ZhbHNfdG9fYWRkOiBzZXQocHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIikpLFxuICAgIGFjdGl2ZV9hcHByb3ZhbHNfdG9fcmVtb3ZlOiBzZXQocHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIikpLFxuICAgIG93bmVyX2FwcHJvdmFsc190b19hZGQ6IHNldChwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSksXG4gICAgb3duZXJfYXBwcm92YWxzX3RvX3JlbW92ZTogc2V0KHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpKSxcbiAgICBrZXlfYXBwcm92YWxzX3RvX2FkZDogc2V0KHB1YmxpY19rZXkpLFxuICAgIGtleV9hcHByb3ZhbHNfdG9fcmVtb3ZlOiBzZXQocHVibGljX2tleSksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIHByb3Bvc2FsX2RlbGV0ZSA9IG5ldyBTZXJpYWxpemVyKFwicHJvcG9zYWxfZGVsZXRlXCIsIHsgZmVlOiBhc3NldCxcbiAgICBmZWVfcGF5aW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHVzaW5nX293bmVyX2F1dGhvcml0eTogYm9vbCxcbiAgICBwcm9wb3NhbDogcHJvdG9jb2xfaWRfdHlwZShcInByb3Bvc2FsXCIpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKFwid2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVcIiwgeyBmZWU6IGFzc2V0LFxuICAgIHdpdGhkcmF3X2Zyb21fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXV0aG9yaXplZF9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICB3aXRoZHJhd2FsX2xpbWl0OiBhc3NldCxcbiAgICB3aXRoZHJhd2FsX3BlcmlvZF9zZWM6IHVpbnQzMixcbiAgICBwZXJpb2RzX3VudGlsX2V4cGlyYXRpb246IHVpbnQzMixcbiAgICBwZXJpb2Rfc3RhcnRfdGltZTogdGltZV9wb2ludF9zZWMgfSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKFwid2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVcIiwgeyBmZWU6IGFzc2V0LFxuICAgIHdpdGhkcmF3X2Zyb21fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXV0aG9yaXplZF9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBwZXJtaXNzaW9uX3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZShcIndpdGhkcmF3X3Blcm1pc3Npb25cIiksXG4gICAgd2l0aGRyYXdhbF9saW1pdDogYXNzZXQsXG4gICAgd2l0aGRyYXdhbF9wZXJpb2Rfc2VjOiB1aW50MzIsXG4gICAgcGVyaW9kX3N0YXJ0X3RpbWU6IHRpbWVfcG9pbnRfc2VjLFxuICAgIHBlcmlvZHNfdW50aWxfZXhwaXJhdGlvbjogdWludDMyIH0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbSA9IG5ldyBTZXJpYWxpemVyKFwid2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbVwiLCB7IGZlZTogYXNzZXQsXG4gICAgd2l0aGRyYXdfcGVybWlzc2lvbjogcHJvdG9jb2xfaWRfdHlwZShcIndpdGhkcmF3X3Blcm1pc3Npb25cIiksXG4gICAgd2l0aGRyYXdfZnJvbV9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICB3aXRoZHJhd190b19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhbW91bnRfdG9fd2l0aGRyYXc6IGFzc2V0LFxuICAgIG1lbW86IG9wdGlvbmFsKG1lbW9fZGF0YSkgfSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSA9IG5ldyBTZXJpYWxpemVyKFwid2l0aGRyYXdfcGVybWlzc2lvbl9kZWxldGVcIiwgeyBmZWU6IGFzc2V0LFxuICAgIHdpdGhkcmF3X2Zyb21fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXV0aG9yaXplZF9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICB3aXRoZHJhd2FsX3Blcm1pc3Npb246IHByb3RvY29sX2lkX3R5cGUoXCJ3aXRoZHJhd19wZXJtaXNzaW9uXCIpIH0pO1xuXG52YXIgY29tbWl0dGVlX21lbWJlcl9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcihcImNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlXCIsIHsgZmVlOiBhc3NldCxcbiAgICBjb21taXR0ZWVfbWVtYmVyX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHVybDogc3RyaW5nIH0pO1xuXG52YXIgY29tbWl0dGVlX21lbWJlcl91cGRhdGUgPSBuZXcgU2VyaWFsaXplcihcImNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlXCIsIHsgZmVlOiBhc3NldCxcbiAgICBjb21taXR0ZWVfbWVtYmVyOiBwcm90b2NvbF9pZF90eXBlKFwiY29tbWl0dGVlX21lbWJlclwiKSxcbiAgICBjb21taXR0ZWVfbWVtYmVyX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIG5ld191cmw6IG9wdGlvbmFsKHN0cmluZykgfSk7XG5cbnZhciBjaGFpbl9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJjaGFpbl9wYXJhbWV0ZXJzXCIsIHsgY3VycmVudF9mZWVzOiBmZWVfc2NoZWR1bGUsXG4gICAgYmxvY2tfaW50ZXJ2YWw6IHVpbnQ4LFxuICAgIG1haW50ZW5hbmNlX2ludGVydmFsOiB1aW50MzIsXG4gICAgbWFpbnRlbmFuY2Vfc2tpcF9zbG90czogdWludDgsXG4gICAgY29tbWl0dGVlX3Byb3Bvc2FsX3Jldmlld19wZXJpb2Q6IHVpbnQzMixcbiAgICBtYXhpbXVtX3RyYW5zYWN0aW9uX3NpemU6IHVpbnQzMixcbiAgICBtYXhpbXVtX2Jsb2NrX3NpemU6IHVpbnQzMixcbiAgICBtYXhpbXVtX3RpbWVfdW50aWxfZXhwaXJhdGlvbjogdWludDMyLFxuICAgIG1heGltdW1fcHJvcG9zYWxfbGlmZXRpbWU6IHVpbnQzMixcbiAgICBtYXhpbXVtX2Fzc2V0X3doaXRlbGlzdF9hdXRob3JpdGllczogdWludDgsXG4gICAgbWF4aW11bV9hc3NldF9mZWVkX3B1Ymxpc2hlcnM6IHVpbnQ4LFxuICAgIG1heGltdW1fd2l0bmVzc19jb3VudDogdWludDE2LFxuICAgIG1heGltdW1fY29tbWl0dGVlX2NvdW50OiB1aW50MTYsXG4gICAgbWF4aW11bV9hdXRob3JpdHlfbWVtYmVyc2hpcDogdWludDE2LFxuICAgIHJlc2VydmVfcGVyY2VudF9vZl9mZWU6IHVpbnQxNixcbiAgICBuZXR3b3JrX3BlcmNlbnRfb2ZfZmVlOiB1aW50MTYsXG4gICAgbGlmZXRpbWVfcmVmZXJyZXJfcGVyY2VudF9vZl9mZWU6IHVpbnQxNixcbiAgICBjYXNoYmFja192ZXN0aW5nX3BlcmlvZF9zZWNvbmRzOiB1aW50MzIsXG4gICAgY2FzaGJhY2tfdmVzdGluZ190aHJlc2hvbGQ6IGludDY0LFxuICAgIGNvdW50X25vbl9tZW1iZXJfdm90ZXM6IGJvb2wsXG4gICAgYWxsb3dfbm9uX21lbWJlcl93aGl0ZWxpc3RzOiBib29sLFxuICAgIHdpdG5lc3NfcGF5X3Blcl9ibG9jazogaW50NjQsXG4gICAgd29ya2VyX2J1ZGdldF9wZXJfZGF5OiBpbnQ2NCxcbiAgICBtYXhfcHJlZGljYXRlX29wY29kZTogdWludDE2LFxuICAgIGZlZV9saXF1aWRhdGlvbl90aHJlc2hvbGQ6IGludDY0LFxuICAgIGFjY291bnRzX3Blcl9mZWVfc2NhbGU6IHVpbnQxNixcbiAgICBhY2NvdW50X2ZlZV9zY2FsZV9iaXRzaGlmdHM6IHVpbnQ4LFxuICAgIG1heF9hdXRob3JpdHlfZGVwdGg6IHVpbnQ4LFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnNcIiwgeyBmZWU6IGFzc2V0LFxuICAgIG5ld19wYXJhbWV0ZXJzOiBjaGFpbl9wYXJhbWV0ZXJzIH0pO1xuXG52YXIgbGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXIoXCJsaW5lYXJfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXJcIiwgeyBiZWdpbl90aW1lc3RhbXA6IHRpbWVfcG9pbnRfc2VjLFxuICAgIHZlc3RpbmdfY2xpZmZfc2Vjb25kczogdWludDMyLFxuICAgIHZlc3RpbmdfZHVyYXRpb25fc2Vjb25kczogdWludDMyIH0pO1xuXG52YXIgY2RkX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXIoXCJjZGRfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXJcIiwgeyBzdGFydF9jbGFpbTogdGltZV9wb2ludF9zZWMsXG4gICAgdmVzdGluZ19zZWNvbmRzOiB1aW50MzIgfSk7XG5cbnZhciB2ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplciA9IHN0YXRpY192YXJpYW50KFtsaW5lYXJfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXIsIGNkZF92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplcl0pO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKFwidmVzdGluZ19iYWxhbmNlX2NyZWF0ZVwiLCB7IGZlZTogYXNzZXQsXG4gICAgY3JlYXRvcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgb3duZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFtb3VudDogYXNzZXQsXG4gICAgcG9saWN5OiB2ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplciB9KTtcblxudmFyIHZlc3RpbmdfYmFsYW5jZV93aXRoZHJhdyA9IG5ldyBTZXJpYWxpemVyKFwidmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3XCIsIHsgZmVlOiBhc3NldCxcbiAgICB2ZXN0aW5nX2JhbGFuY2U6IHByb3RvY29sX2lkX3R5cGUoXCJ2ZXN0aW5nX2JhbGFuY2VcIiksXG4gICAgb3duZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFtb3VudDogYXNzZXQgfSk7XG5cbnZhciByZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXIoXCJyZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyXCIpO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX3dvcmtlcl9pbml0aWFsaXplciA9IG5ldyBTZXJpYWxpemVyKFwidmVzdGluZ19iYWxhbmNlX3dvcmtlcl9pbml0aWFsaXplclwiLCB7IHBheV92ZXN0aW5nX3BlcmlvZF9kYXlzOiB1aW50MTYgfSk7XG5cbnZhciBidXJuX3dvcmtlcl9pbml0aWFsaXplciA9IG5ldyBTZXJpYWxpemVyKFwiYnVybl93b3JrZXJfaW5pdGlhbGl6ZXJcIik7XG5cbnZhciB3b3JrZXJfaW5pdGlhbGl6ZXIgPSBzdGF0aWNfdmFyaWFudChbcmVmdW5kX3dvcmtlcl9pbml0aWFsaXplciwgdmVzdGluZ19iYWxhbmNlX3dvcmtlcl9pbml0aWFsaXplciwgYnVybl93b3JrZXJfaW5pdGlhbGl6ZXJdKTtcblxudmFyIHdvcmtlcl9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcihcIndvcmtlcl9jcmVhdGVcIiwgeyBmZWU6IGFzc2V0LFxuICAgIG93bmVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICB3b3JrX2JlZ2luX2RhdGU6IHRpbWVfcG9pbnRfc2VjLFxuICAgIHdvcmtfZW5kX2RhdGU6IHRpbWVfcG9pbnRfc2VjLFxuICAgIGRhaWx5X3BheTogaW50NjQsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHVybDogc3RyaW5nLFxuICAgIGluaXRpYWxpemVyOiB3b3JrZXJfaW5pdGlhbGl6ZXIgfSk7XG5cbnZhciBjdXN0b20gPSBuZXcgU2VyaWFsaXplcihcImN1c3RvbVwiLCB7IGZlZTogYXNzZXQsXG4gICAgcGF5ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHJlcXVpcmVkX2F1dGhzOiBzZXQocHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIikpLFxuICAgIGlkOiB1aW50MTYsXG4gICAgZGF0YTogYnl0ZXMoKSB9KTtcblxudmFyIGFjY291bnRfbmFtZV9lcV9saXRfcHJlZGljYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJhY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZVwiLCB7IGFjY291bnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIG5hbWU6IHN0cmluZyB9KTtcblxudmFyIGFzc2V0X3N5bWJvbF9lcV9saXRfcHJlZGljYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9zeW1ib2xfZXFfbGl0X3ByZWRpY2F0ZVwiLCB7IGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgc3ltYm9sOiBzdHJpbmcgfSk7XG5cbnZhciBibG9ja19pZF9wcmVkaWNhdGUgPSBuZXcgU2VyaWFsaXplcihcImJsb2NrX2lkX3ByZWRpY2F0ZVwiLCB7IGlkOiBieXRlcygyMCkgfSk7XG5cbnZhciBwcmVkaWNhdGUgPSBzdGF0aWNfdmFyaWFudChbYWNjb3VudF9uYW1lX2VxX2xpdF9wcmVkaWNhdGUsIGFzc2V0X3N5bWJvbF9lcV9saXRfcHJlZGljYXRlLCBibG9ja19pZF9wcmVkaWNhdGVdKTtcblxudmFyIGFzc2VydCA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXJ0XCIsIHsgZmVlOiBhc3NldCxcbiAgICBmZWVfcGF5aW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHByZWRpY2F0ZXM6IGFycmF5KHByZWRpY2F0ZSksXG4gICAgcmVxdWlyZWRfYXV0aHM6IHNldChwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIGJhbGFuY2VfY2xhaW0gPSBuZXcgU2VyaWFsaXplcihcImJhbGFuY2VfY2xhaW1cIiwgeyBmZWU6IGFzc2V0LFxuICAgIGRlcG9zaXRfdG9fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYmFsYW5jZV90b19jbGFpbTogcHJvdG9jb2xfaWRfdHlwZShcImJhbGFuY2VcIiksXG4gICAgYmFsYW5jZV9vd25lcl9rZXk6IHB1YmxpY19rZXksXG4gICAgdG90YWxfY2xhaW1lZDogYXNzZXQgfSk7XG5cbnZhciBvdmVycmlkZV90cmFuc2ZlciA9IG5ldyBTZXJpYWxpemVyKFwib3ZlcnJpZGVfdHJhbnNmZXJcIiwgeyBmZWU6IGFzc2V0LFxuICAgIGlzc3VlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgZnJvbTogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgdG86IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFtb3VudDogYXNzZXQsXG4gICAgbWVtbzogb3B0aW9uYWwobWVtb19kYXRhKSxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG52YXIgc3RlYWx0aF9jb25maXJtYXRpb24gPSBuZXcgU2VyaWFsaXplcihcInN0ZWFsdGhfY29uZmlybWF0aW9uXCIsIHsgb25lX3RpbWVfa2V5OiBwdWJsaWNfa2V5LFxuICAgIHRvOiBvcHRpb25hbChwdWJsaWNfa2V5KSxcbiAgICBlbmNyeXB0ZWRfbWVtbzogYnl0ZXMoKSB9KTtcblxudmFyIGJsaW5kX291dHB1dCA9IG5ldyBTZXJpYWxpemVyKFwiYmxpbmRfb3V0cHV0XCIsIHsgY29tbWl0bWVudDogYnl0ZXMoMzMpLFxuICAgIHJhbmdlX3Byb29mOiBieXRlcygpLFxuICAgIG93bmVyOiBhdXRob3JpdHksXG4gICAgc3RlYWx0aF9tZW1vOiBvcHRpb25hbChzdGVhbHRoX2NvbmZpcm1hdGlvbikgfSk7XG5cbnZhciB0cmFuc2Zlcl90b19ibGluZCA9IG5ldyBTZXJpYWxpemVyKFwidHJhbnNmZXJfdG9fYmxpbmRcIiwgeyBmZWU6IGFzc2V0LFxuICAgIGFtb3VudDogYXNzZXQsXG4gICAgZnJvbTogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYmxpbmRpbmdfZmFjdG9yOiBieXRlcygzMiksXG4gICAgb3V0cHV0czogYXJyYXkoYmxpbmRfb3V0cHV0KSB9KTtcblxudmFyIGJsaW5kX2lucHV0ID0gbmV3IFNlcmlhbGl6ZXIoXCJibGluZF9pbnB1dFwiLCB7IGNvbW1pdG1lbnQ6IGJ5dGVzKDMzKSxcbiAgICBvd25lcjogYXV0aG9yaXR5IH0pO1xuXG52YXIgYmxpbmRfdHJhbnNmZXIgPSBuZXcgU2VyaWFsaXplcihcImJsaW5kX3RyYW5zZmVyXCIsIHsgZmVlOiBhc3NldCxcbiAgICBpbnB1dHM6IGFycmF5KGJsaW5kX2lucHV0KSxcbiAgICBvdXRwdXRzOiBhcnJheShibGluZF9vdXRwdXQpIH0pO1xuXG52YXIgdHJhbnNmZXJfZnJvbV9ibGluZCA9IG5ldyBTZXJpYWxpemVyKFwidHJhbnNmZXJfZnJvbV9ibGluZFwiLCB7IGZlZTogYXNzZXQsXG4gICAgYW1vdW50OiBhc3NldCxcbiAgICB0bzogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYmxpbmRpbmdfZmFjdG9yOiBieXRlcygzMiksXG4gICAgaW5wdXRzOiBhcnJheShibGluZF9pbnB1dCkgfSk7XG5cbnZhciBhc3NldF9zZXR0bGVfY2FuY2VsID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9zZXR0bGVfY2FuY2VsXCIsIHsgZmVlOiBhc3NldCxcbiAgICBzZXR0bGVtZW50OiBwcm90b2NvbF9pZF90eXBlKFwiZm9yY2Vfc2V0dGxlbWVudFwiKSxcbiAgICBhY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhbW91bnQ6IGFzc2V0LFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciBhc3NldF9jbGFpbV9mZWVzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9jbGFpbV9mZWVzXCIsIHsgZmVlOiBhc3NldCxcbiAgICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFtb3VudF90b19jbGFpbTogYXNzZXQsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIGZiYV9kaXN0cmlidXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJmYmFfZGlzdHJpYnV0ZVwiLCB7IGZlZTogYXNzZXQsXG4gICAgYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgZmJhX2lkOiBwcm90b2NvbF9pZF90eXBlKFwiZmJhX2FjY3VtdWxhdG9yXCIpLFxuICAgIGFtb3VudDogaW50NjQgfSk7XG5cbnZhciBkaXZpZGVuZF9hc3NldF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoXCJkaXZpZGVuZF9hc3NldF9vcHRpb25zXCIsIHsgbmV4dF9wYXlvdXRfdGltZTogb3B0aW9uYWwodGltZV9wb2ludF9zZWMpLFxuICAgIHBheW91dF9pbnRlcnZhbDogb3B0aW9uYWwodWludDMyKSxcbiAgICBtaW5pbXVtX2ZlZV9wZXJjZW50YWdlOiB1aW50NjQsXG4gICAgbWluaW11bV9kaXN0cmlidXRpb25faW50ZXJ2YWw6IG9wdGlvbmFsKHVpbnQzMiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIGFzc2V0X3VwZGF0ZV9kaXZpZGVuZCA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfdXBkYXRlX2RpdmlkZW5kXCIsIHsgZmVlOiBhc3NldCxcbiAgICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFzc2V0X3RvX3VwZGF0ZTogcHJvdG9jb2xfaWRfdHlwZShcImFzc2V0XCIpLFxuICAgIG5ld19vcHRpb25zOiBkaXZpZGVuZF9hc3NldF9vcHRpb25zLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciByb2NrX3BhcGVyX3NjaXNzb3JzX2dhbWVfb3B0aW9ucyA9IG5ldyBTZXJpYWxpemVyKFwicm9ja19wYXBlcl9zY2lzc29yc19nYW1lX29wdGlvbnNcIiwgeyBpbnN1cmFuY2VfZW5hYmxlZDogYm9vbCxcbiAgICB0aW1lX3Blcl9jb21taXRfbW92ZTogdWludDMyLFxuICAgIHRpbWVfcGVyX3JldmVhbF9tb3ZlOiB1aW50MzIsXG4gICAgbnVtYmVyX29mX2dlc3R1cmVzOiB1aW50OCB9KTtcblxudmFyIGdhbWVfc3BlY2lmaWNfZGV0YWlscyA9IHN0YXRpY192YXJpYW50KFtyb2NrX3BhcGVyX3NjaXNzb3JzX2dhbWVfb3B0aW9uc10pO1xuXG52YXIgdG91cm5hbWVudF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoXCJ0b3VybmFtZW50X29wdGlvbnNcIiwge1xuICAgIHR5cGVfb2ZfZ2FtZTogdWludDE2LFxuICAgIHJlZ2lzdHJhdGlvbl9kZWFkbGluZTogdGltZV9wb2ludF9zZWMsXG4gICAgbnVtYmVyX29mX3BsYXllcnM6IHVpbnQzMixcbiAgICBidXlfaW46IGFzc2V0LFxuICAgIHdoaXRlbGlzdDogc2V0KHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpKSxcbiAgICBzdGFydF90aW1lOiBvcHRpb25hbCh0aW1lX3BvaW50X3NlYyksXG4gICAgc3RhcnRfZGVsYXk6IG9wdGlvbmFsKHVpbnQzMiksXG4gICAgcm91bmRfZGVsYXk6IHVpbnQzMixcbiAgICBudW1iZXJfb2Zfd2luczogdWludDMyLFxuICAgIG1ldGE6IHZhcmlhbnRfb2JqZWN0LFxuICAgIGdhbWVfb3B0aW9uczogZ2FtZV9zcGVjaWZpY19kZXRhaWxzXG59KTtcblxudmFyIHRvdXJuYW1lbnRfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJ0b3VybmFtZW50X2NyZWF0ZVwiLCB7IGZlZTogYXNzZXQsXG4gICAgY3JlYXRvcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgb3B0aW9uczogdG91cm5hbWVudF9vcHRpb25zLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucykgfSk7XG5cbnZhciB0b3VybmFtZW50X2pvaW4gPSBuZXcgU2VyaWFsaXplcihcInRvdXJuYW1lbnRfam9pblwiLCB7IGZlZTogYXNzZXQsXG4gICAgcGF5ZXJfYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgcGxheWVyX2FjY291bnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHRvdXJuYW1lbnRfaWQ6IHByb3RvY29sX2lkX3R5cGUoXCJ0b3VybmFtZW50XCIpLFxuICAgIGJ1eV9pbjogYXNzZXQsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIHJvY2tfcGFwZXJfc2Npc3NvcnNfZ2VzdHVyZSA9IGVudW1lcmF0aW9uKFtcInJvY2tcIiwgXCJwYXBlclwiLCBcInNjaXNzb3JzXCIsIFwic3BvY2tcIiwgXCJsaXphcmRcIl0pO1xuXG52YXIgcm9ja19wYXBlcl9zY2lzc29yc190aHJvd19jb21taXQgPSBuZXcgU2VyaWFsaXplcihcInJvY2tfcGFwZXJfc2Npc3NvcnNfdGhyb3dfY29tbWl0XCIsIHsgbm9uY2UxOiB1aW50NjQsXG4gICAgdGhyb3dfaGFzaDogc2hhMjU2IH0pO1xuXG52YXIgcm9ja19wYXBlcl9zY2lzc29yc190aHJvd19yZXZlYWwgPSBuZXcgU2VyaWFsaXplcihcInJvY2tfcGFwZXJfc2Npc3NvcnNfdGhyb3dfcmV2ZWFsXCIsIHsgbm9uY2UyOiB1aW50NjQsXG4gICAgZ2VzdHVyZTogcm9ja19wYXBlcl9zY2lzc29yc19nZXN0dXJlIH0pO1xuXG52YXIgZ2FtZV9zcGVjaWZpY19tb3ZlcyA9IHN0YXRpY192YXJpYW50KFtyb2NrX3BhcGVyX3NjaXNzb3JzX3Rocm93X2NvbW1pdCwgcm9ja19wYXBlcl9zY2lzc29yc190aHJvd19yZXZlYWxdKTtcblxudmFyIGdhbWVfbW92ZSA9IG5ldyBTZXJpYWxpemVyKFwiZ2FtZV9tb3ZlXCIsIHsgZmVlOiBhc3NldCxcbiAgICBnYW1lX2lkOiBwcm90b2NvbF9pZF90eXBlKFwiZ2FtZVwiKSxcbiAgICBwbGF5ZXJfYWNjb3VudF9pZDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgbW92ZTogZ2FtZV9zcGVjaWZpY19tb3ZlcyxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpIH0pO1xuXG5vcGVyYXRpb24uc3Rfb3BlcmF0aW9ucyA9IFt0cmFuc2ZlciwgbGltaXRfb3JkZXJfY3JlYXRlLCBsaW1pdF9vcmRlcl9jYW5jZWwsIGNhbGxfb3JkZXJfdXBkYXRlLCBmaWxsX29yZGVyLCBhY2NvdW50X2NyZWF0ZSwgYWNjb3VudF91cGRhdGUsIGFjY291bnRfd2hpdGVsaXN0LCBhY2NvdW50X3VwZ3JhZGUsIGFjY291bnRfdHJhbnNmZXIsIGFzc2V0X2NyZWF0ZSwgYXNzZXRfdXBkYXRlLCBhc3NldF91cGRhdGVfYml0YXNzZXQsIGFzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2VycywgYXNzZXRfaXNzdWUsIGFzc2V0X3Jlc2VydmUsIGFzc2V0X2Z1bmRfZmVlX3Bvb2wsIGFzc2V0X3NldHRsZSwgYXNzZXRfZ2xvYmFsX3NldHRsZSwgYXNzZXRfcHVibGlzaF9mZWVkLCB3aXRuZXNzX2NyZWF0ZSwgd2l0bmVzc191cGRhdGUsIHByb3Bvc2FsX2NyZWF0ZSwgcHJvcG9zYWxfdXBkYXRlLCBwcm9wb3NhbF9kZWxldGUsIHdpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlLCB3aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZSwgd2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbSwgd2l0aGRyYXdfcGVybWlzc2lvbl9kZWxldGUsIGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlLCBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZSwgY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnMsIHZlc3RpbmdfYmFsYW5jZV9jcmVhdGUsIHZlc3RpbmdfYmFsYW5jZV93aXRoZHJhdywgd29ya2VyX2NyZWF0ZSwgY3VzdG9tLCBhc3NlcnQsIGJhbGFuY2VfY2xhaW0sIG92ZXJyaWRlX3RyYW5zZmVyLCB0cmFuc2Zlcl90b19ibGluZCwgYmxpbmRfdHJhbnNmZXIsIHRyYW5zZmVyX2Zyb21fYmxpbmQsIGFzc2V0X3NldHRsZV9jYW5jZWwsIGFzc2V0X2NsYWltX2ZlZXMsIGZiYV9kaXN0cmlidXRlLCB0b3VybmFtZW50X2NyZWF0ZSwgdG91cm5hbWVudF9qb2luLCBnYW1lX21vdmUsIGFzc2V0X3VwZGF0ZV9kaXZpZGVuZF07XG5cbnZhciB0cmFuc2FjdGlvbiA9IG5ldyBTZXJpYWxpemVyKFwidHJhbnNhY3Rpb25cIiwgeyByZWZfYmxvY2tfbnVtOiB1aW50MTYsXG4gICAgcmVmX2Jsb2NrX3ByZWZpeDogdWludDMyLFxuICAgIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICAgIG9wZXJhdGlvbnM6IGFycmF5KG9wZXJhdGlvbiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSB9KTtcblxudmFyIHNpZ25lZF90cmFuc2FjdGlvbiA9IG5ldyBTZXJpYWxpemVyKFwic2lnbmVkX3RyYW5zYWN0aW9uXCIsIHsgcmVmX2Jsb2NrX251bTogdWludDE2LFxuICAgIHJlZl9ibG9ja19wcmVmaXg6IHVpbnQzMixcbiAgICBleHBpcmF0aW9uOiB0aW1lX3BvaW50X3NlYyxcbiAgICBvcGVyYXRpb25zOiBhcnJheShvcGVyYXRpb24pLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucyksXG4gICAgc2lnbmF0dXJlczogYXJyYXkoYnl0ZXMoNjUpKSB9KTtcbi8vIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyMgIEdlbmVyYXRlZCBjb2RlIGVuZFxuLy8jIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gQ3VzdG9tIFR5cGVzXG5cbnZhciBzdGVhbHRoX21lbW9fZGF0YSA9IG5ldyBTZXJpYWxpemVyKFwic3RlYWx0aF9tZW1vX2RhdGFcIiwge1xuICAgIGZyb206IG9wdGlvbmFsKHB1YmxpY19rZXkpLFxuICAgIGFtb3VudDogYXNzZXQsXG4gICAgYmxpbmRpbmdfZmFjdG9yOiBieXRlcygzMiksXG4gICAgY29tbWl0bWVudDogYnl0ZXMoMzMpLFxuICAgIGNoZWNrOiB1aW50MzJcbn0pO1xuLy8gdmFyIHN0ZWFsdGhfY29uZmlybWF0aW9uID0gbmV3IFNlcmlhbGl6ZXIoXG4vLyAgICAgXCJzdGVhbHRoX2NvbmZpcm1hdGlvblwiLCB7XG4vLyAgICAgb25lX3RpbWVfa2V5OiBwdWJsaWNfa2V5LFxuLy8gICAgIHRvOiBvcHRpb25hbCggcHVibGljX2tleSApLFxuLy8gICAgIGVuY3J5cHRlZF9tZW1vOiBzdGVhbHRoX21lbW9fZGF0YVxuLy8gfSkiLCIndXNlIHN0cmljdCc7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBCeXRlQnVmZmVyID0gcmVxdWlyZSgnYnl0ZWJ1ZmZlcicpO1xudmFyIEVDID0gcmVxdWlyZSgnLi9lcnJvcl93aXRoX2NhdXNlJyk7XG5cbnZhciBIRVhfRFVNUCA9IHByb2Nlc3MuZW52Lm5wbV9jb25maWdfX2dyYXBoZW5lX3NlcmlhbGl6ZXJfaGV4X2R1bXA7XG5cbnZhciBTZXJpYWxpemVyID0gZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFNlcmlhbGl6ZXIob3BlcmF0aW9uX25hbWUsIHR5cGVzKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTZXJpYWxpemVyKTtcblxuICAgICAgICB0aGlzLm9wZXJhdGlvbl9uYW1lID0gb3BlcmF0aW9uX25hbWU7XG4gICAgICAgIHRoaXMudHlwZXMgPSB0eXBlcztcbiAgICAgICAgaWYgKHRoaXMudHlwZXMpIHRoaXMua2V5cyA9IE9iamVjdC5rZXlzKHRoaXMudHlwZXMpO1xuXG4gICAgICAgIFNlcmlhbGl6ZXIucHJpbnREZWJ1ZyA9IHRydWU7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNsYXNzKFNlcmlhbGl6ZXIsIFt7XG4gICAgICAgIGtleTogJ2Zyb21CeXRlQnVmZmVyJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgIHZhciBmaWVsZCA9IG51bGw7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBpdGVyYWJsZSA9IHRoaXMua2V5cztcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgZmllbGQ7IGkgPCBpdGVyYWJsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBmaWVsZCA9IGl0ZXJhYmxlW2ldO1xuICAgICAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IHRoaXMudHlwZXNbZmllbGRdO1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEhFWF9EVU1QKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUub3BlcmF0aW9uX25hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcih0eXBlLm9wZXJhdGlvbl9uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbzEgPSBiLm9mZnNldDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG8yID0gYi5vZmZzZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIub2Zmc2V0ID0gbzE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYi5yZXNldCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBfYiA9IGIuY29weShvMSwgbzIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHRoaXMub3BlcmF0aW9uX25hbWUgKyAnLicgKyBmaWVsZCArICdcXHQnLCBfYi50b0hleCgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3RbZmllbGRdID0gdHlwZS5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFNlcmlhbGl6ZXIucHJpbnREZWJ1Zykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlYWRpbmcgJyArIHRoaXMub3BlcmF0aW9uX25hbWUgKyAnLicgKyBmaWVsZCArICcgaW4gZGF0YTonKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiLnByaW50RGVidWcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIEVDLnRocm93KHRoaXMub3BlcmF0aW9uX25hbWUgKyAnLicgKyBmaWVsZCwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdhcHBlbmRCeXRlQnVmZmVyJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgZmllbGQgPSBudWxsO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgaXRlcmFibGUgPSB0aGlzLmtleXM7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGZpZWxkOyBpIDwgaXRlcmFibGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgZmllbGQgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHR5cGUgPSB0aGlzLnR5cGVzW2ZpZWxkXTtcbiAgICAgICAgICAgICAgICAgICAgdHlwZS5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdFtmaWVsZF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgRUMudGhyb3codGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgXCIgPSBcIiArIEpTT04uc3RyaW5naWZ5KG9iamVjdFtmaWVsZF0pLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBjaXJjdWxhciByZWZcbiAgICAgICAgICAgICAgICAgICAgRUMudGhyb3codGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkICsgXCIgPSBcIiArIG9iamVjdFtmaWVsZF0sIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2Zyb21PYmplY3QnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZnJvbU9iamVjdChzZXJpYWxpemVkX29iamVjdCkge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgICAgICAgdmFyIGZpZWxkID0gbnVsbDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy5rZXlzO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBmaWVsZDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkID0gaXRlcmFibGVbaV07XG4gICAgICAgICAgICAgICAgICAgIHZhciB0eXBlID0gdGhpcy50eXBlc1tmaWVsZF07XG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHNlcmlhbGl6ZWRfb2JqZWN0W2ZpZWxkXTtcbiAgICAgICAgICAgICAgICAgICAgLy9ERUJVRyB2YWx1ZSA9IHZhbHVlLnJlc29sdmUgaWYgdmFsdWUucmVzb2x2ZVxuICAgICAgICAgICAgICAgICAgICAvL0RFQlVHIGNvbnNvbGUubG9nKCcuLi4gdmFsdWUnLGZpZWxkLHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICB2YXIgb2JqZWN0ID0gdHlwZS5mcm9tT2JqZWN0KHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ZpZWxkXSA9IG9iamVjdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIEVDLnRocm93KHRoaXMub3BlcmF0aW9uX25hbWUgKyAnLicgKyBmaWVsZCwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAgICBAYXJnIHtib29sZWFufSBbZGVidWcudXNlX2RlZmF1bHQgPSBmYWxzZV0gLSBtb3JlIHRlbXBsYXRlIGZyaWVuZGx5XG4gICAgICAgICAgICBAYXJnIHtib29sZWFufSBbZGVidWcuYW5ub3RhdGUgPSBmYWxzZV0gLSBhZGQgdXNlci1mcmllbmRseSBpbmZvcm1hdGlvblxuICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICd0b09iamVjdCcsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiB0b09iamVjdCgpIHtcbiAgICAgICAgICAgIHZhciBzZXJpYWxpemVkX29iamVjdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDoge307XG4gICAgICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHsgdXNlX2RlZmF1bHQ6IGZhbHNlLCBhbm5vdGF0ZTogZmFsc2UgfTtcblxuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgICAgICAgdmFyIGZpZWxkID0gbnVsbDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnR5cGVzKSByZXR1cm4gcmVzdWx0O1xuXG4gICAgICAgICAgICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy5rZXlzO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBmaWVsZDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkID0gaXRlcmFibGVbaV07XG4gICAgICAgICAgICAgICAgICAgIHZhciB0eXBlID0gdGhpcy50eXBlc1tmaWVsZF07XG4gICAgICAgICAgICAgICAgICAgIHZhciBvYmplY3QgPSB0eXBlLnRvT2JqZWN0KHR5cGVvZiBzZXJpYWxpemVkX29iamVjdCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzZXJpYWxpemVkX29iamVjdCAhPT0gbnVsbCA/IHNlcmlhbGl6ZWRfb2JqZWN0W2ZpZWxkXSA6IHVuZGVmaW5lZCwgZGVidWcpO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRbZmllbGRdID0gb2JqZWN0O1xuICAgICAgICAgICAgICAgICAgICBpZiAoSEVYX0RVTVApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS5hcHBlbmRCeXRlQnVmZmVyKGIsIHR5cGVvZiBzZXJpYWxpemVkX29iamVjdCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzZXJpYWxpemVkX29iamVjdCAhPT0gbnVsbCA/IHNlcmlhbGl6ZWRfb2JqZWN0W2ZpZWxkXSA6IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBiID0gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IodGhpcy5vcGVyYXRpb25fbmFtZSArICcuJyArIGZpZWxkLCBiLnRvSGV4KCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBFQy50aHJvdyh0aGlzLm9wZXJhdGlvbl9uYW1lICsgJy4nICsgZmllbGQsIGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKiBTb3J0IGJ5IHRoZSBmaXJzdCBlbGVtZW50IGluIGEgb3BlcmF0aW9uICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2NvbXBhcmUnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG5cbiAgICAgICAgICAgIHZhciBmaXJzdF9rZXkgPSB0aGlzLmtleXNbMF07XG4gICAgICAgICAgICB2YXIgZmlyc3RfdHlwZSA9IHRoaXMudHlwZXNbZmlyc3Rfa2V5XTtcblxuICAgICAgICAgICAgdmFyIHZhbEEgPSBhW2ZpcnN0X2tleV07XG4gICAgICAgICAgICB2YXIgdmFsQiA9IGJbZmlyc3Rfa2V5XTtcblxuICAgICAgICAgICAgaWYgKGZpcnN0X3R5cGUuY29tcGFyZSkgcmV0dXJuIGZpcnN0X3R5cGUuY29tcGFyZSh2YWxBLCB2YWxCKTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWxBID09PSBcIm51bWJlclwiICYmIHR5cGVvZiB2YWxCID09PSBcIm51bWJlclwiKSByZXR1cm4gdmFsQSAtIHZhbEI7XG5cbiAgICAgICAgICAgIHZhciBlbmNvZGluZyA9IHZvaWQgMDtcbiAgICAgICAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsQSkgJiYgQnVmZmVyLmlzQnVmZmVyKHZhbEIpKSB7XG4gICAgICAgICAgICAgICAgLy8gQSBiaW5hcnkgc3RyaW5nIGNvbXBhcmUgZG9lcyBub3Qgd29yay4gIElmIGxvY2FsZUNvbXBhcmUgaXMgd2VsbCBzdXBwb3J0ZWQgdGhhdCBjb3VsZCByZXBsYWNlIEhFWC4gIFBlcmZvcm1hbmFuY2UgaXMgdmVyeSBnb29kIHNvIGNvbXBhcmluZyBIRVggd29ya3MuXG4gICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBcImhleFwiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc3RyQSA9IHZhbEEudG9TdHJpbmcoZW5jb2RpbmcpO1xuICAgICAgICAgICAgdmFyIHN0ckIgPSB2YWxCLnRvU3RyaW5nKGVuY29kaW5nKTtcbiAgICAgICAgICAgIHJldHVybiBzdHJBID4gc3RyQiA/IDEgOiBzdHJBIDwgc3RyQiA/IC0xIDogMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIDxoZWxwZXJfZnVuY3Rpb25zPlxuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICdmcm9tSGV4JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZyb21IZXgoaGV4KSB7XG4gICAgICAgICAgICB2YXIgYiA9IEJ5dGVCdWZmZXIuZnJvbUhleChoZXgsIEJ5dGVCdWZmZXIuTElUVExFX0VORElBTik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZnJvbUJ1ZmZlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBmcm9tQnVmZmVyKGJ1ZmZlcikge1xuICAgICAgICAgICAgdmFyIGIgPSBCeXRlQnVmZmVyLmZyb21CaW5hcnkoYnVmZmVyLnRvU3RyaW5nKFwiYmluYXJ5XCIpLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3RvSGV4JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvSGV4KG9iamVjdCkge1xuICAgICAgICAgICAgLy8gcmV0dXJuIHRoaXMudG9CdWZmZXIob2JqZWN0KS50b1N0cmluZyhcImhleFwiKVxuICAgICAgICAgICAgdmFyIGIgPSB0aGlzLnRvQnl0ZUJ1ZmZlcihvYmplY3QpO1xuICAgICAgICAgICAgcmV0dXJuIGIudG9IZXgoKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndG9CeXRlQnVmZmVyJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHRvQnl0ZUJ1ZmZlcihvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBiID0gbmV3IEJ5dGVCdWZmZXIoQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZLCBCeXRlQnVmZmVyLkxJVFRMRV9FTkRJQU4pO1xuICAgICAgICAgICAgdGhpcy5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCk7XG4gICAgICAgICAgICByZXR1cm4gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndG9CdWZmZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdG9CdWZmZXIob2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcih0aGlzLnRvQnl0ZUJ1ZmZlcihvYmplY3QpLnRvQmluYXJ5KCksICdiaW5hcnknKTtcbiAgICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBTZXJpYWxpemVyO1xufSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNlcmlhbGl6ZXI7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qKiBDb25zb2xlIHByaW50IGFueSB0cmFuc2FjdGlvbiBvYmplY3Qgd2l0aCB6ZXJvIGRlZmF1bHQgdmFsdWVzLiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB0ZW1wbGF0ZShvcCkge1xuXG4gICAgdmFyIG9iamVjdCA9IG9wLnRvT2JqZWN0KHZvaWQgMCwgeyB1c2VfZGVmYXVsdDogdHJ1ZSwgYW5ub3RhdGU6IHRydWUgfSk7XG5cbiAgICAvLyB2aXN1YWwgKHdpdGggZGVzY3JpcHRpb25zKVxuICAgIGNvbnNvbGUuZXJyb3IoSlNPTi5zdHJpbmdpZnkob2JqZWN0LCBudWxsLCA0KSk7XG5cbiAgICAvLyB1c2FibGUgaW4gYSBjb3B5LXBhc3RlXG5cbiAgICBvYmplY3QgPSBvcC50b09iamVjdCh2b2lkIDAsIHsgdXNlX2RlZmF1bHQ6IHRydWUsIGFubm90YXRlOiBmYWxzZSB9KTtcblxuICAgIC8vIGNvcHktcGFzdGUgb25lLWxpbmVlclxuICAgIGNvbnNvbGUuZXJyb3IoSlNPTi5zdHJpbmdpZnkob2JqZWN0KSk7XG59OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIF9zbGljZWRUb0FycmF5ID0gZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBzbGljZUl0ZXJhdG9yKGFyciwgaSkgeyB2YXIgX2FyciA9IFtdOyB2YXIgX24gPSB0cnVlOyB2YXIgX2QgPSBmYWxzZTsgdmFyIF9lID0gdW5kZWZpbmVkOyB0cnkgeyBmb3IgKHZhciBfaSA9IGFycltTeW1ib2wuaXRlcmF0b3JdKCksIF9zOyAhKF9uID0gKF9zID0gX2kubmV4dCgpKS5kb25lKTsgX24gPSB0cnVlKSB7IF9hcnIucHVzaChfcy52YWx1ZSk7IGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhazsgfSB9IGNhdGNoIChlcnIpIHsgX2QgPSB0cnVlOyBfZSA9IGVycjsgfSBmaW5hbGx5IHsgdHJ5IHsgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSkgX2lbXCJyZXR1cm5cIl0oKTsgfSBmaW5hbGx5IHsgaWYgKF9kKSB0aHJvdyBfZTsgfSB9IHJldHVybiBfYXJyOyB9IHJldHVybiBmdW5jdGlvbiAoYXJyLCBpKSB7IGlmIChBcnJheS5pc0FycmF5KGFycikpIHsgcmV0dXJuIGFycjsgfSBlbHNlIGlmIChTeW1ib2wuaXRlcmF0b3IgaW4gT2JqZWN0KGFycikpIHsgcmV0dXJuIHNsaWNlSXRlcmF0b3IoYXJyLCBpKTsgfSBlbHNlIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2VcIik7IH0gfTsgfSgpO1xuXG52YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07XG5cbi8vIExvdy1sZXZlbCB0eXBlcyB0aGF0IG1ha2UgdXAgb3BlcmF0aW9uc1xuXG52YXIgdiA9IHJlcXVpcmUoJy4vU2VyaWFsaXplclZhbGlkYXRpb24nKTtcbnZhciBmcCA9IHJlcXVpcmUoJy4vRmFzdFBhcnNlcicpO1xuXG52YXIgQ2hhaW5UeXBlcyA9IHJlcXVpcmUoXCIuLi8uLi9jaGFpbi9zcmMvQ2hhaW5UeXBlc1wiKTtcbnZhciBPYmplY3RJZCA9IHJlcXVpcmUoXCIuLi8uLi9jaGFpbi9zcmMvT2JqZWN0SWRcIik7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoXCIuLi8uLi9lY2NcIiksXG4gICAgUHVibGljS2V5ID0gX3JlcXVpcmUuUHVibGljS2V5LFxuICAgIEFkZHJlc3MgPSBfcmVxdWlyZS5BZGRyZXNzO1xuXG52YXIgX3JlcXVpcmUyID0gcmVxdWlyZShcInBlZXJwbGF5c2pzLXdzXCIpLFxuICAgIENoYWluQ29uZmlnID0gX3JlcXVpcmUyLkNoYWluQ29uZmlnO1xuXG52YXIgVHlwZXMgPSB7fTtcbm1vZHVsZS5leHBvcnRzID0gVHlwZXM7XG5cbnZhciBIRVhfRFVNUCA9IHByb2Nlc3MuZW52Lm5wbV9jb25maWdfX2dyYXBoZW5lX3NlcmlhbGl6ZXJfaGV4X2R1bXA7XG5cblR5cGVzLnVpbnQ4ID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHJldHVybiBiLnJlYWRVaW50OCgpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgdi5yZXF1aXJlX3JhbmdlKDAsIDB4RkYsIG9iamVjdCwgJ3VpbnQ4ICcgKyBvYmplY3QpO1xuICAgICAgICBiLndyaXRlVWludDgob2JqZWN0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgdi5yZXF1aXJlX3JhbmdlKDAsIDB4RkYsIG9iamVjdCwgJ3VpbnQ4ICcgKyBvYmplY3QpO1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgdi5yZXF1aXJlX3JhbmdlKDAsIDB4RkYsIG9iamVjdCwgJ3VpbnQ4ICcgKyBvYmplY3QpO1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqZWN0KTtcbiAgICB9XG59O1xuXG5UeXBlcy51aW50MTYgPSB7XG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgcmV0dXJuIGIucmVhZFVpbnQxNigpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgdi5yZXF1aXJlX3JhbmdlKDAsIDB4RkZGRiwgb2JqZWN0LCAndWludDE2ICcgKyBvYmplY3QpO1xuICAgICAgICBiLndyaXRlVWludDE2KG9iamVjdCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZV9yYW5nZSgwLCAweEZGRkYsIG9iamVjdCwgJ3VpbnQxNiAnICsgb2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHYucmVxdWlyZV9yYW5nZSgwLCAweEZGRkYsIG9iamVjdCwgJ3VpbnQxNiAnICsgb2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KG9iamVjdCk7XG4gICAgfVxufTtcblxuVHlwZXMudWludDMyID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHJldHVybiBiLnJlYWRVaW50MzIoKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZV9yYW5nZSgwLCAweEZGRkZGRkZGLCBvYmplY3QsICd1aW50MzIgJyArIG9iamVjdCk7XG4gICAgICAgIGIud3JpdGVVaW50MzIob2JqZWN0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgdi5yZXF1aXJlX3JhbmdlKDAsIDB4RkZGRkZGRkYsIG9iamVjdCwgJ3VpbnQzMiAnICsgb2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHYucmVxdWlyZV9yYW5nZSgwLCAweEZGRkZGRkZGLCBvYmplY3QsICd1aW50MzIgJyArIG9iamVjdCk7XG4gICAgICAgIHJldHVybiBwYXJzZUludChvYmplY3QpO1xuICAgIH1cbn07XG5cbnZhciBNSU5fU0lHTkVEXzMyID0gLTEgKiBNYXRoLnBvdygyLCAzMSk7XG52YXIgTUFYX1NJR05FRF8zMiA9IE1hdGgucG93KDIsIDMxKSAtIDE7XG5cblR5cGVzLnZhcmludDMyID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHJldHVybiBiLnJlYWRWYXJpbnQzMigpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgdi5yZXF1aXJlX3JhbmdlKE1JTl9TSUdORURfMzIsIE1BWF9TSUdORURfMzIsIG9iamVjdCwgJ3VpbnQzMiAnICsgb2JqZWN0KTtcbiAgICAgICAgYi53cml0ZVZhcmludDMyKG9iamVjdCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZV9yYW5nZShNSU5fU0lHTkVEXzMyLCBNQVhfU0lHTkVEXzMyLCBvYmplY3QsICd1aW50MzIgJyArIG9iamVjdCk7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICB2LnJlcXVpcmVfcmFuZ2UoTUlOX1NJR05FRF8zMiwgTUFYX1NJR05FRF8zMiwgb2JqZWN0LCAndWludDMyICcgKyBvYmplY3QpO1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqZWN0KTtcbiAgICB9XG59O1xuXG5UeXBlcy5pbnQ2NCA9IHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICByZXR1cm4gYi5yZWFkSW50NjQoKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgYi53cml0ZUludDY0KHYudG9fbG9uZyhvYmplY3QpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgdi5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICByZXR1cm4gdi50b19sb25nKG9iamVjdCk7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gXCIwXCI7XG4gICAgICAgIH1cbiAgICAgICAgdi5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICByZXR1cm4gdi50b19sb25nKG9iamVjdCkudG9TdHJpbmcoKTtcbiAgICB9XG59O1xuXG5UeXBlcy51aW50NjQgPSB7XG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgcmV0dXJuIGIucmVhZFVpbnQ2NCgpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgYi53cml0ZVVpbnQ2NCh2LnRvX3Vsb25nKHYudW5zaWduZWQob2JqZWN0KSkpO1xuICAgICAgICByZXR1cm47XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICByZXR1cm4gdi50b191bG9uZyh2LnVuc2lnbmVkKG9iamVjdCkpO1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiMFwiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2LnRvX3Vsb25nKG9iamVjdCkudG9TdHJpbmcoKTtcbiAgICB9XG59O1xuXG5UeXBlcy5zdHJpbmcgPSB7XG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgdmFyIGJfY29weTtcbiAgICAgICAgdmFyIGxlbiA9IGIucmVhZFZhcmludDMyKCk7XG4gICAgICAgIGJfY29weSA9IGIuY29weShiLm9mZnNldCwgYi5vZmZzZXQgKyBsZW4pLCBiLnNraXAobGVuKTtcbiAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIoYl9jb3B5LnRvQmluYXJ5KCksICdiaW5hcnknKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgYi53cml0ZVZhcmludDMyKG9iamVjdC5sZW5ndGgpO1xuICAgICAgICBiLmFwcGVuZChvYmplY3QudG9TdHJpbmcoJ2JpbmFyeScpLCAnYmluYXJ5Jyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIob2JqZWN0KTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3QudG9TdHJpbmcoKTtcbiAgICB9XG59O1xuXG5UeXBlcy5ieXRlcyA9IGZ1bmN0aW9uIChzaXplKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgICAgIGlmIChzaXplID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgYl9jb3B5O1xuICAgICAgICAgICAgICAgIHZhciBsZW4gPSBiLnJlYWRWYXJpbnQzMigpO1xuICAgICAgICAgICAgICAgIGJfY29weSA9IGIuY29weShiLm9mZnNldCwgYi5vZmZzZXQgKyBsZW4pLCBiLnNraXAobGVuKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihiX2NvcHkudG9CaW5hcnkoKSwgJ2JpbmFyeScpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgc2l6ZSksIGIuc2tpcChzaXplKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihiX2NvcHkudG9CaW5hcnkoKSwgJ2JpbmFyeScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICAgICAgdi5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QgPT09IFwic3RyaW5nXCIpIG9iamVjdCA9IG5ldyBCdWZmZXIob2JqZWN0LCBcImhleFwiKTtcblxuICAgICAgICAgICAgaWYgKHNpemUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QubGVuZ3RoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGIuYXBwZW5kKG9iamVjdC50b1N0cmluZygnYmluYXJ5JyksICdiaW5hcnknKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSxcbiAgICAgICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqZWN0KSkgcmV0dXJuIG9iamVjdDtcblxuICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIob2JqZWN0LCAnaGV4Jyk7XG4gICAgICAgIH0sXG4gICAgICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHZhciB6ZXJvcyA9IGZ1bmN0aW9uIHplcm9zKG51bSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5KG51bSkuam9pbihcIjAwXCIpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIHplcm9zKHNpemUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdi5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdC50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuVHlwZXMuYm9vbCA9IHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICByZXR1cm4gYi5yZWFkVWludDgoKSA9PT0gMTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIC8vIHN1cHBvcnRzIGJvb2xlYW4gb3IgaW50ZWdlclxuICAgICAgICBiLndyaXRlVWludDgoSlNPTi5wYXJzZShvYmplY3QpID8gMSA6IDApO1xuICAgICAgICByZXR1cm47XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShvYmplY3QpID8gdHJ1ZSA6IGZhbHNlO1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKG9iamVjdCkgPyB0cnVlIDogZmFsc2U7XG4gICAgfVxufTtcblxuVHlwZXMudm9pZCA9IHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCIodm9pZCkgdW5kZWZpbmVkIHR5cGVcIik7XG4gICAgfSxcbiAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCIodm9pZCkgdW5kZWZpbmVkIHR5cGVcIik7XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCIodm9pZCkgdW5kZWZpbmVkIHR5cGVcIik7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIih2b2lkKSB1bmRlZmluZWQgdHlwZVwiKTtcbiAgICB9XG59O1xuXG5UeXBlcy5hcnJheSA9IGZ1bmN0aW9uIChzdF9vcGVyYXRpb24pIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgdmFyIHNpemUgPSBiLnJlYWRWYXJpbnQzMigpO1xuICAgICAgICAgICAgaWYgKEhFWF9EVU1QKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJ2YXJpbnQzMiBzaXplID0gXCIgKyBzaXplLnRvU3RyaW5nKDE2KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgMCA8IHNpemUgPyBpIDwgc2l6ZSA6IGkgPiBzaXplOyAwIDwgc2l6ZSA/IGkrKyA6IGkrKykge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc29ydE9wZXJhdGlvbihyZXN1bHQsIHN0X29wZXJhdGlvbik7XG4gICAgICAgIH0sXG4gICAgICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgICAgICB2LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgICAgICBvYmplY3QgPSBzb3J0T3BlcmF0aW9uKG9iamVjdCwgc3Rfb3BlcmF0aW9uKTtcbiAgICAgICAgICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QubGVuZ3RoKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgb2JqZWN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbyA9IG9iamVjdFtpXTtcbiAgICAgICAgICAgICAgICBzdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIG87IGkgPCBvYmplY3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvID0gb2JqZWN0W2ldO1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG8pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG4gICAgICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KG9iamVjdCwgZGVidWcpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbzsgaSA8IG9iamVjdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIG8gPSBvYmplY3RbaV07XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KG8sIGRlYnVnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfTtcbn07XG5cblR5cGVzLnRpbWVfcG9pbnRfc2VjID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHJldHVybiBiLnJlYWRVaW50MzIoKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSBcIm51bWJlclwiKSBvYmplY3QgPSBUeXBlcy50aW1lX3BvaW50X3NlYy5mcm9tT2JqZWN0KG9iamVjdCk7XG5cbiAgICAgICAgYi53cml0ZVVpbnQzMihvYmplY3QpO1xuICAgICAgICByZXR1cm47XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2LnJlcXVpcmVkKG9iamVjdCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QgPT09IFwibnVtYmVyXCIpIHJldHVybiBvYmplY3Q7XG5cbiAgICAgICAgaWYgKG9iamVjdC5nZXRUaW1lKSByZXR1cm4gTWF0aC5mbG9vcihvYmplY3QuZ2V0VGltZSgpIC8gMTAwMCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QgIT09IFwic3RyaW5nXCIpIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gZGF0ZSB0eXBlOiBcIiArIG9iamVjdCk7XG5cbiAgICAgICAgLy8gaWYodHlwZW9mIG9iamVjdCA9PT0gXCJzdHJpbmdcIiAmJiAhL1okLy50ZXN0KG9iamVjdCkpXG4gICAgICAgIC8vICAgICBvYmplY3QgPSBvYmplY3QgKyBcIlpcIlxuXG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKG5ldyBEYXRlKG9iamVjdCkuZ2V0VGltZSgpIC8gMTAwMCk7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gbmV3IERhdGUoMCkudG9JU09TdHJpbmcoKS5zcGxpdCgnLicpWzBdO1xuXG4gICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcblxuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIG9iamVjdDtcblxuICAgICAgICBpZiAob2JqZWN0LmdldFRpbWUpIHJldHVybiBvYmplY3QudG9JU09TdHJpbmcoKS5zcGxpdCgnLicpWzBdO1xuXG4gICAgICAgIHZhciBpbnQgPSBwYXJzZUludChvYmplY3QpO1xuICAgICAgICB2LnJlcXVpcmVfcmFuZ2UoMCwgMHhGRkZGRkZGRiwgaW50LCAndWludDMyICcgKyBvYmplY3QpO1xuICAgICAgICByZXR1cm4gbmV3IERhdGUoaW50ICogMTAwMCkudG9JU09TdHJpbmcoKS5zcGxpdCgnLicpWzBdO1xuICAgIH1cbn07XG5cblR5cGVzLnNldCA9IGZ1bmN0aW9uIChzdF9vcGVyYXRpb24pIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZGF0ZTogZnVuY3Rpb24gdmFsaWRhdGUoYXJyYXkpIHtcbiAgICAgICAgICAgIHZhciBkdXBfbWFwID0ge307XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbzsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbyA9IGFycmF5W2ldO1xuICAgICAgICAgICAgICAgIHZhciByZWY7XG4gICAgICAgICAgICAgICAgaWYgKHJlZiA9IHR5cGVvZiBvID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihvKSwgWydzdHJpbmcnLCAnbnVtYmVyJ10uaW5kZXhPZihyZWYpID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGR1cF9tYXBbb10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZHVwbGljYXRlIChzZXQpXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGR1cF9tYXBbb10gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzb3J0T3BlcmF0aW9uKGFycmF5LCBzdF9vcGVyYXRpb24pO1xuICAgICAgICB9LFxuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgdmFyIHNpemUgPSBiLnJlYWRWYXJpbnQzMigpO1xuICAgICAgICAgICAgaWYgKEhFWF9EVU1QKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJ2YXJpbnQzMiBzaXplID0gXCIgKyBzaXplLnRvU3RyaW5nKDE2KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyAwIDwgc2l6ZSA/IGkgPCBzaXplIDogaSA+IHNpemU7IDAgPCBzaXplID8gaSsrIDogaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9KCkpO1xuICAgICAgICB9LFxuICAgICAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKCFvYmplY3QpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBpdGVyYWJsZSA9IHRoaXMudmFsaWRhdGUob2JqZWN0KTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgaXRlcmFibGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvID0gaXRlcmFibGVbaV07XG4gICAgICAgICAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0sXG4gICAgICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICAgICAgICAgIG9iamVjdCA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbzsgaSA8IG9iamVjdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBvID0gb2JqZWN0W2ldO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9KCkpO1xuICAgICAgICB9LFxuICAgICAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW3N0X29wZXJhdGlvbi50b09iamVjdChvYmplY3QsIGRlYnVnKV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICAgICAgICAgIG9iamVjdCA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbzsgaSA8IG9iamVjdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBvID0gb2JqZWN0W2ldO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChzdF9vcGVyYXRpb24udG9PYmplY3QobywgZGVidWcpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0oKSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuLy8gZ2xvYmFsX3BhcmFtZXRlcnNfdXBkYXRlX29wZXJhdGlvbiBjdXJyZW50X2ZlZXNcblR5cGVzLmZpeGVkX2FycmF5ID0gZnVuY3Rpb24gKGNvdW50LCBzdF9vcGVyYXRpb24pIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgdmFyIGksIGosIHJlZiwgcmVzdWx0cztcbiAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBjb3VudDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChzdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNvcnRPcGVyYXRpb24ocmVzdWx0cywgc3Rfb3BlcmF0aW9uKTtcbiAgICAgICAgfSxcbiAgICAgICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBpLCBqLCByZWY7XG4gICAgICAgICAgICBpZiAoY291bnQgIT09IDApIHtcbiAgICAgICAgICAgICAgICB2LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgICAgICAgICAgb2JqZWN0ID0gc29ydE9wZXJhdGlvbihvYmplY3QsIHN0X29wZXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gY291bnQ7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICBzdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3RbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgdmFyIGksIGosIHJlZiwgcmVzdWx0cztcbiAgICAgICAgICAgIGlmIChjb3VudCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBjb3VudDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvYmplY3RbaV0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICB9LFxuICAgICAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0LCBkZWJ1Zykge1xuICAgICAgICAgICAgdmFyIGksIGosIGssIHJlZiwgcmVmMSwgcmVzdWx0cywgcmVzdWx0czE7XG4gICAgICAgICAgICBpZiAoZGVidWcgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlYnVnID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGNvdW50OyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChzdF9vcGVyYXRpb24udG9PYmplY3Qodm9pZCAwLCBkZWJ1ZykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjb3VudCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdHMxID0gW107XG4gICAgICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IGNvdW50OyBrIDwgcmVmMTsgaSA9IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdHMxLnB1c2goc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KG9iamVjdFtpXSwgZGVidWcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzMTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKiBTdXBwb3J0cyBpbnN0YW5jZSBudW1iZXJzICgxMSkgb3Igb2JqZWN0IHR5cGVzICgxLjIuMTEpLiAgT2JqZWN0IHR5cGVcblZhbGlkYXRpb24gaXMgZW5mb3JjZWQgd2hlbiBhbiBvYmplY3QgdHlwZSBpcyB1c2VkLiAqL1xudmFyIGlkX3R5cGUgPSBmdW5jdGlvbiBpZF90eXBlKHJlc2VydmVkX3NwYWNlcywgb2JqZWN0X3R5cGUpIHtcbiAgICB2LnJlcXVpcmVkKHJlc2VydmVkX3NwYWNlcywgXCJyZXNlcnZlZF9zcGFjZXNcIik7XG4gICAgdi5yZXF1aXJlZChvYmplY3RfdHlwZSwgXCJvYmplY3RfdHlwZVwiKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgcmV0dXJuIGIucmVhZFZhcmludDMyKCk7XG4gICAgICAgIH0sXG4gICAgICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgICAgICB2LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnJlc29sdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gY29udmVydCAxLjIubiBpbnRvIGp1c3QgblxuICAgICAgICAgICAgaWYgKC9eWzAtOV0rXFwuWzAtOV0rXFwuWzAtOV0rJC8udGVzdChvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0ID0gdi5nZXRfaW5zdGFuY2UocmVzZXJ2ZWRfc3BhY2VzLCBvYmplY3RfdHlwZSwgb2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGIud3JpdGVWYXJpbnQzMih2LnRvX251bWJlcihvYmplY3QpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSxcbiAgICAgICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0ID0gb2JqZWN0LnJlc29sdmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodi5pc19kaWdpdHMob2JqZWN0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2LnRvX251bWJlcihvYmplY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHYuZ2V0X2luc3RhbmNlKHJlc2VydmVkX3NwYWNlcywgb2JqZWN0X3R5cGUsIG9iamVjdCk7XG4gICAgICAgIH0sXG4gICAgICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgICAgIHZhciBvYmplY3RfdHlwZV9pZCA9IENoYWluVHlwZXMub2JqZWN0X3R5cGVbb2JqZWN0X3R5cGVdO1xuICAgICAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc2VydmVkX3NwYWNlcyArICcuJyArIG9iamVjdF90eXBlX2lkICsgJy4wJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0ID0gb2JqZWN0LnJlc29sdmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoL15bMC05XStcXC5bMC05XStcXC5bMC05XSskLy50ZXN0KG9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QgPSB2LmdldF9pbnN0YW5jZShyZXNlcnZlZF9zcGFjZXMsIG9iamVjdF90eXBlLCBvYmplY3QpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzZXJ2ZWRfc3BhY2VzICsgJy4nICsgb2JqZWN0X3R5cGVfaWQgKyAnLicgKyBvYmplY3Q7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuVHlwZXMucHJvdG9jb2xfaWRfdHlwZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdi5yZXF1aXJlZChuYW1lLCBcIm5hbWVcIik7XG4gICAgcmV0dXJuIGlkX3R5cGUoQ2hhaW5UeXBlcy5yZXNlcnZlZF9zcGFjZXMucHJvdG9jb2xfaWRzLCBuYW1lKTtcbn07XG5cblR5cGVzLm9iamVjdF9pZF90eXBlID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHJldHVybiBPYmplY3RJZC5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgaWYgKG9iamVjdC5yZXNvbHZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgICAgICB9XG4gICAgICAgIG9iamVjdCA9IE9iamVjdElkLmZyb21TdHJpbmcob2JqZWN0KTtcbiAgICAgICAgb2JqZWN0LmFwcGVuZEJ5dGVCdWZmZXIoYik7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgaWYgKG9iamVjdC5yZXNvbHZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBPYmplY3RJZC5mcm9tU3RyaW5nKG9iamVjdCk7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gXCIwLjAuMFwiO1xuICAgICAgICB9XG4gICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgaWYgKG9iamVjdC5yZXNvbHZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgICAgICB9XG4gICAgICAgIG9iamVjdCA9IE9iamVjdElkLmZyb21TdHJpbmcob2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIG9iamVjdC50b1N0cmluZygpO1xuICAgIH1cbn07XG5cblR5cGVzLnZvdGVfaWQgPSB7IFRZUEU6IDB4MDAwMDAwRkYsXG4gICAgSUQ6IDB4RkZGRkZGMDAsXG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYi5yZWFkVWludDMyKCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiB2YWx1ZSAmIHRoaXMuVFlQRSxcbiAgICAgICAgICAgIGlkOiB2YWx1ZSAmIHRoaXMuSURcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgaWYgKG9iamVjdCA9PT0gXCJzdHJpbmdcIikgb2JqZWN0ID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KG9iamVjdCk7XG5cbiAgICAgICAgdmFyIHZhbHVlID0gb2JqZWN0LmlkIDw8IDggfCBvYmplY3QudHlwZTtcbiAgICAgICAgYi53cml0ZVVpbnQzMih2YWx1ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHYucmVxdWlyZWQob2JqZWN0LCBcIih0eXBlIHZvdGVfaWQpXCIpO1xuICAgICAgICBpZiAoKHR5cGVvZiBvYmplY3QgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKG9iamVjdCkpID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICB2LnJlcXVpcmVkKG9iamVjdC50eXBlLCBcInR5cGVcIik7XG4gICAgICAgICAgICB2LnJlcXVpcmVkKG9iamVjdC5pZCwgXCJpZFwiKTtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH1cbiAgICAgICAgdi5yZXF1aXJlX3Rlc3QoL15bMC05XSs6WzAtOV0rJC8sIG9iamVjdCwgJ3ZvdGVfaWQgZm9ybWF0ICcgKyBvYmplY3QpO1xuXG4gICAgICAgIHZhciBfb2JqZWN0JHNwbGl0ID0gb2JqZWN0LnNwbGl0KCc6JyksXG4gICAgICAgICAgICBfb2JqZWN0JHNwbGl0MiA9IF9zbGljZWRUb0FycmF5KF9vYmplY3Qkc3BsaXQsIDIpLFxuICAgICAgICAgICAgdHlwZSA9IF9vYmplY3Qkc3BsaXQyWzBdLFxuICAgICAgICAgICAgaWQgPSBfb2JqZWN0JHNwbGl0MlsxXTtcblxuICAgICAgICB2LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZiwgdHlwZSwgJ3ZvdGUgdHlwZSAnICsgb2JqZWN0KTtcbiAgICAgICAgdi5yZXF1aXJlX3JhbmdlKDAsIDB4ZmZmZmZmLCBpZCwgJ3ZvdGUgaWQgJyArIG9iamVjdCk7XG4gICAgICAgIHJldHVybiB7IHR5cGU6IHR5cGUsIGlkOiBpZCB9O1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiMDowXCI7XG4gICAgICAgIH1cbiAgICAgICAgdi5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCA9PT0gXCJzdHJpbmdcIikgb2JqZWN0ID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KG9iamVjdCk7XG5cbiAgICAgICAgcmV0dXJuIG9iamVjdC50eXBlICsgXCI6XCIgKyBvYmplY3QuaWQ7XG4gICAgfSxcbiAgICBjb21wYXJlOiBmdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgICAgICAgaWYgKCh0eXBlb2YgYSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YoYSkpICE9PSBcIm9iamVjdFwiKSBhID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KGEpO1xuICAgICAgICBpZiAoKHR5cGVvZiBiID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogX3R5cGVvZihiKSkgIT09IFwib2JqZWN0XCIpIGIgPSBUeXBlcy52b3RlX2lkLmZyb21PYmplY3QoYik7XG4gICAgICAgIHJldHVybiBwYXJzZUludChhLmlkKSAtIHBhcnNlSW50KGIuaWQpO1xuICAgIH1cbn07XG5cblR5cGVzLm9wdGlvbmFsID0gZnVuY3Rpb24gKHN0X29wZXJhdGlvbikge1xuICAgIHYucmVxdWlyZWQoc3Rfb3BlcmF0aW9uLCBcInN0X29wZXJhdGlvblwiKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgaWYgKCEoYi5yZWFkVWludDgoKSA9PT0gMSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgICAgICAgfSxcbiAgICAgICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgIT09IG51bGwgJiYgb2JqZWN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBiLndyaXRlVWludDgoMSk7XG4gICAgICAgICAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYi53cml0ZVVpbnQ4KDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9LFxuICAgICAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvYmplY3QpO1xuICAgICAgICB9LFxuICAgICAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgICAgICAvLyB0b09iamVjdCBpcyBvbmx5IG51bGwgc2F2ZSBpZiB1c2VfZGVmYXVsdCBpcyB0cnVlXG4gICAgICAgICAgICB2YXIgcmVzdWx0X29iamVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0X29wZXJhdGlvbi50b09iamVjdChvYmplY3QsIGRlYnVnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KCk7XG5cbiAgICAgICAgICAgIGlmIChkZWJ1Zy5hbm5vdGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmICgodHlwZW9mIHJlc3VsdF9vYmplY3QgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHJlc3VsdF9vYmplY3QpKSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRfb2JqZWN0Ll9fb3B0aW9uYWwgPSBcInBhcmVudCBpcyBvcHRpb25hbFwiO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdF9vYmplY3QgPSB7IF9fb3B0aW9uYWw6IHJlc3VsdF9vYmplY3QgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0X29iamVjdDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG5UeXBlcy5zdGF0aWNfdmFyaWFudCA9IGZ1bmN0aW9uIChfc3Rfb3BlcmF0aW9ucykge1xuICAgIHJldHVybiB7XG4gICAgICAgIG5vc29ydDogdHJ1ZSxcbiAgICAgICAgc3Rfb3BlcmF0aW9uczogX3N0X29wZXJhdGlvbnMsXG4gICAgICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgICAgICB2YXIgdHlwZV9pZCA9IGIucmVhZFZhcmludDMyKCk7XG4gICAgICAgICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuICAgICAgICAgICAgaWYgKEhFWF9EVU1QKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignc3RhdGljX3ZhcmlhbnQgaWQgMHgnICsgdHlwZV9pZC50b1N0cmluZygxNikgKyAnICgnICsgdHlwZV9pZCArICcpJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2LnJlcXVpcmVkKHN0X29wZXJhdGlvbiwgJ29wZXJhdGlvbiAnICsgdHlwZV9pZCk7XG4gICAgICAgICAgICByZXR1cm4gW3R5cGVfaWQsIHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKV07XG4gICAgICAgIH0sXG4gICAgICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgICAgICB2LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgICAgICB2YXIgdHlwZV9pZCA9IG9iamVjdFswXTtcbiAgICAgICAgICAgIHZhciBzdF9vcGVyYXRpb24gPSB0aGlzLnN0X29wZXJhdGlvbnNbdHlwZV9pZF07XG4gICAgICAgICAgICB2LnJlcXVpcmVkKHN0X29wZXJhdGlvbiwgJ29wZXJhdGlvbiAnICsgdHlwZV9pZCk7XG4gICAgICAgICAgICBiLndyaXRlVmFyaW50MzIodHlwZV9pZCk7XG4gICAgICAgICAgICBzdF9vcGVyYXRpb24uYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3RbMV0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9LFxuICAgICAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgdi5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgdmFyIHR5cGVfaWQgPSBvYmplY3RbMF07XG4gICAgICAgICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuICAgICAgICAgICAgdi5yZXF1aXJlZChzdF9vcGVyYXRpb24sICdvcGVyYXRpb24gJyArIHR5cGVfaWQpO1xuICAgICAgICAgICAgcmV0dXJuIFt0eXBlX2lkLCBzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvYmplY3RbMV0pXTtcbiAgICAgICAgfSxcbiAgICAgICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFswLCB0aGlzLnN0X29wZXJhdGlvbnNbMF0udG9PYmplY3QodW5kZWZpbmVkLCBkZWJ1ZyldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdi5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgdmFyIHR5cGVfaWQgPSBvYmplY3RbMF07XG4gICAgICAgICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuICAgICAgICAgICAgdi5yZXF1aXJlZChzdF9vcGVyYXRpb24sICdvcGVyYXRpb24gJyArIHR5cGVfaWQpO1xuICAgICAgICAgICAgcmV0dXJuIFt0eXBlX2lkLCBzdF9vcGVyYXRpb24udG9PYmplY3Qob2JqZWN0WzFdLCBkZWJ1ZyldO1xuICAgICAgICB9XG4gICAgfTtcbn07XG5cblR5cGVzLm1hcCA9IGZ1bmN0aW9uIChrZXlfc3Rfb3BlcmF0aW9uLCB2YWx1ZV9zdF9vcGVyYXRpb24pIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZGF0ZTogZnVuY3Rpb24gdmFsaWRhdGUoYXJyYXkpIHtcbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcnJheSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJleHBlY3RpbmcgYXJyYXlcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZHVwX21hcCA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIG87IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIG8gPSBhcnJheVtpXTtcbiAgICAgICAgICAgICAgICB2YXIgcmVmO1xuICAgICAgICAgICAgICAgIGlmICghKG8ubGVuZ3RoID09PSAyKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJleHBlY3RpbmcgdHdvIGVsZW1lbnRzXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVmID0gX3R5cGVvZihvWzBdKSwgWydudW1iZXInLCAnc3RyaW5nJ10uaW5kZXhPZihyZWYpID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGR1cF9tYXBbb1swXV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZHVwbGljYXRlIChtYXApXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGR1cF9tYXBbb1swXV0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzb3J0T3BlcmF0aW9uKGFycmF5LCBrZXlfc3Rfb3BlcmF0aW9uKTtcbiAgICAgICAgfSxcbiAgICAgICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgIHZhciBlbmQgPSBiLnJlYWRWYXJpbnQzMigpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IDAgPCBlbmQgPyBpIDwgZW5kIDogaSA+IGVuZDsgMCA8IGVuZCA/IGkrKyA6IGkrKykge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFtrZXlfc3Rfb3BlcmF0aW9uLmZyb21CeXRlQnVmZmVyKGIpLCB2YWx1ZV9zdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYildKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlKHJlc3VsdCk7XG4gICAgICAgIH0sXG4gICAgICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnZhbGlkYXRlKG9iamVjdCk7XG4gICAgICAgICAgICBiLndyaXRlVmFyaW50MzIob2JqZWN0Lmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbzsgaSA8IG9iamVjdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIG8gPSBvYmplY3RbaV07XG4gICAgICAgICAgICAgICAga2V5X3N0X29wZXJhdGlvbi5hcHBlbmRCeXRlQnVmZmVyKGIsIG9bMF0pO1xuICAgICAgICAgICAgICAgIHZhbHVlX3N0X29wZXJhdGlvbi5hcHBlbmRCeXRlQnVmZmVyKGIsIG9bMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9LFxuICAgICAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgdi5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIG87IGkgPCBvYmplY3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvID0gb2JqZWN0W2ldO1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFtrZXlfc3Rfb3BlcmF0aW9uLmZyb21PYmplY3Qob1swXSksIHZhbHVlX3N0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG9bMV0pXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZShyZXN1bHQpO1xuICAgICAgICB9LFxuICAgICAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW1trZXlfc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KHVuZGVmaW5lZCwgZGVidWcpLCB2YWx1ZV9zdF9vcGVyYXRpb24udG9PYmplY3QodW5kZWZpbmVkLCBkZWJ1ZyldXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHYucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIG9iamVjdCA9IHRoaXMudmFsaWRhdGUob2JqZWN0KTtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgb2JqZWN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbyA9IG9iamVjdFtpXTtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChba2V5X3N0X29wZXJhdGlvbi50b09iamVjdChvWzBdLCBkZWJ1ZyksIHZhbHVlX3N0X29wZXJhdGlvbi50b09iamVjdChvWzFdLCBkZWJ1ZyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuVHlwZXMucHVibGljX2tleSA9IHtcbiAgICB0b1B1YmxpYzogZnVuY3Rpb24gdG9QdWJsaWMob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvYmplY3QgPSBvYmplY3QucmVzb2x2ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBQdWJsaWNLZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBvYmplY3QuUSA/IG9iamVjdCA6IFB1YmxpY0tleS5mcm9tU3RyaW5nT3JUaHJvdyhvYmplY3QpO1xuICAgIH0sXG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgcmV0dXJuIGZwLnB1YmxpY19rZXkoYik7XG4gICAgfSxcbiAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICB2LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgIGZwLnB1YmxpY19rZXkoYiwgVHlwZXMucHVibGljX2tleS50b1B1YmxpYyhvYmplY3QpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgdi5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICBpZiAob2JqZWN0LlEpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFR5cGVzLnB1YmxpY19rZXkudG9QdWJsaWMob2JqZWN0KTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBDaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeCArIFwiODU5Z3hmblh5VXJpTWdVZVRoaDFmV3Yzb3FjcExGeUhhM1RmRllDNFBLMkhxaFRvVk1cIjtcbiAgICAgICAgfVxuICAgICAgICB2LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgIHJldHVybiBvYmplY3QudG9TdHJpbmcoKTtcbiAgICB9LFxuICAgIGNvbXBhcmU6IGZ1bmN0aW9uIGNvbXBhcmUoYSwgYikge1xuICAgICAgICByZXR1cm4gc3RyQ21wKGEudG9BZGRyZXNzU3RyaW5nKCksIGIudG9BZGRyZXNzU3RyaW5nKCkpO1xuICAgIH1cbn07XG5cblR5cGVzLmFkZHJlc3MgPSB7XG4gICAgX3RvX2FkZHJlc3M6IGZ1bmN0aW9uIF90b19hZGRyZXNzKG9iamVjdCkge1xuICAgICAgICB2LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgIGlmIChvYmplY3QuYWRkeSkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQWRkcmVzcy5mcm9tU3RyaW5nKG9iamVjdCk7XG4gICAgfSxcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICByZXR1cm4gbmV3IEFkZHJlc3MoZnAucmlwZW1kMTYwKGIpKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIGZwLnJpcGVtZDE2MChiLCBUeXBlcy5hZGRyZXNzLl90b19hZGRyZXNzKG9iamVjdCkudG9CdWZmZXIoKSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBUeXBlcy5hZGRyZXNzLl90b19hZGRyZXNzKG9iamVjdCk7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXggKyBcIjY2NEttSHhTdVF5RHNmd280V0VKdldwemcxUUtkZzY3U1wiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBUeXBlcy5hZGRyZXNzLl90b19hZGRyZXNzKG9iamVjdCkudG9TdHJpbmcoKTtcbiAgICB9LFxuICAgIGNvbXBhcmU6IGZ1bmN0aW9uIGNvbXBhcmUoYSwgYikge1xuICAgICAgICByZXR1cm4gc3RyQ21wKGEudG9TdHJpbmcoKSwgYi50b1N0cmluZygpKTtcbiAgICB9XG59O1xuXG5UeXBlcy52YXJpYW50ID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHZhciB0eXBlID0gYi5yZWFkVWludDgoKTtcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVzLmludDY0LmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIHJldHVybiBUeXBlcy51aW50NjQuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgcmV0dXJuIGIucmVhZERvdWJsZSgpO1xuICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIHJldHVybiBUeXBlcy5ib29sLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIHJldHVybiBUeXBlcy5zdHJpbmcuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgcmV0dXJuIFR5cGVzLmFycmF5KFR5cGVzLnZhcmlhbnQpLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gVHlwZXMudmFyaWFudF9vYmplY3QuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgIH07XG4gICAgfSxcbiAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCA9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgaWYgKE51bWJlci5pc0ludGVnZXIob2JqZWN0KSkge1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QgPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICBiLndyaXRlVWludDgoMik7XG4gICAgICAgICAgICAgICAgICAgIFR5cGVzLnVpbnQ2NC5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYi53cml0ZVVpbnQ4KDEpO1xuICAgICAgICAgICAgICAgICAgICBUeXBlcy5pbnQ2NC5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBiLndyaXRlVWludDgoMyk7XG4gICAgICAgICAgICAgICAgYi53cml0ZURvdWJsZShOdW1iZXIucGFyc2VGbG9hdChvYmplY3QpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0ID09ICdib29sZWFuJykge1xuICAgICAgICAgICAgYi53cml0ZVVpbnQ4KDQpO1xuICAgICAgICAgICAgVHlwZXMuYm9vbC5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG9iamVjdCA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgYi53cml0ZVVpbnQ4KDUpO1xuICAgICAgICAgICAgVHlwZXMuc3RyaW5nLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0ID09ICdhcnJheScpIHtcbiAgICAgICAgICAgIGIud3JpdGVVaW50OCg2KTtcbiAgICAgICAgICAgIFR5cGVzLmFycmF5KFR5cGVzLnZhcmlhbnQpLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGIud3JpdGVVaW50OCg3KTtcbiAgICAgICAgICAgIFR5cGVzLnZhcmlhbnRfb2JqZWN0LmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2Uob2JqZWN0KTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKG9iamVjdCk7XG4gICAgfVxufTtcblxuVHlwZXMudmFyaWFudF9vYmplY3QgPSB7XG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgdmFyIGNvdW50ID0gYi5yZWFkVmFyaW50MzIoKTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBUeXBlcy5zdHJpbmcuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgICAgICByZXN1bHRba2V5XSA9IFR5cGVzLnZhcmlhbnQuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIHZhciBjb3VudCA9IDA7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QuaGFzT3duUHJvcGVydHkoa2V5KSkgKytjb3VudDtcbiAgICAgICAgfWIud3JpdGVWYXJpbnQzMihjb3VudCk7IC8vIG51bWJlciBvZiBrZXkvdmFsdWUgcGFpcnNcbiAgICAgICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgVHlwZXMuc3RyaW5nLmFwcGVuZEJ5dGVCdWZmZXIoYiwga2V5KTtcbiAgICAgICAgICAgICAgICBUeXBlcy52YXJpYW50LmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0W2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9cmV0dXJuO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIG5ld09iamVjdCA9IHt9O1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0Lmhhc093blByb3BlcnR5KGtleSkpIG5ld09iamVjdFtrZXldID0gb2JqZWN0W2tleV07XG4gICAgICAgIH1yZXR1cm4gbmV3T2JqZWN0O1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgIHZhciBuZXdPYmplY3QgPSB7fTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdC5oYXNPd25Qcm9wZXJ0eShrZXkpKSBuZXdPYmplY3Rba2V5XSA9IG9iamVjdFtrZXldO1xuICAgICAgICB9cmV0dXJuIG5ld09iamVjdDtcbiAgICB9XG59O1xuXG5UeXBlcy5lbnVtZXJhdGlvbiA9IGZ1bmN0aW9uICh2YWx1ZXMpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlc1tiLnJlYWRWYXJpbnQzMlppZ1phZygpXTtcbiAgICAgICAgfSxcbiAgICAgICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgICAgIGIud3JpdGVWYXJpbnQzMlppZ1phZyh2YWx1ZXMuaW5kZXhPZihvYmplY3QpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSxcbiAgICAgICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH0sXG4gICAgICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHZhbHVlc1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuVHlwZXMuc2hhMjU2ID0gVHlwZXMuYnl0ZXMoMzIpO1xuXG52YXIgc3RyQ21wID0gZnVuY3Rpb24gc3RyQ21wKGEsIGIpIHtcbiAgICByZXR1cm4gYSA+IGIgPyAxIDogYSA8IGIgPyAtMSA6IDA7XG59O1xudmFyIGZpcnN0RWwgPSBmdW5jdGlvbiBmaXJzdEVsKGVsKSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoZWwpID8gZWxbMF0gOiBlbDtcbn07XG52YXIgc29ydE9wZXJhdGlvbiA9IGZ1bmN0aW9uIHNvcnRPcGVyYXRpb24oYXJyYXksIHN0X29wZXJhdGlvbikge1xuICAgIHJldHVybiBzdF9vcGVyYXRpb24ubm9zb3J0ID8gYXJyYXkgOiBzdF9vcGVyYXRpb24uY29tcGFyZSA/IGFycmF5LnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIHN0X29wZXJhdGlvbi5jb21wYXJlKGZpcnN0RWwoYSksIGZpcnN0RWwoYikpO1xuICAgIH0pIDogLy8gY3VzdG9tIGNvbXBhcmUgb3BlcmF0aW9uXG4gICAgYXJyYXkuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICByZXR1cm4gdHlwZW9mIGZpcnN0RWwoYSkgPT09IFwibnVtYmVyXCIgJiYgdHlwZW9mIGZpcnN0RWwoYikgPT09IFwibnVtYmVyXCIgPyBmaXJzdEVsKGEpIC0gZmlyc3RFbChiKSA6XG4gICAgICAgIC8vIEEgYmluYXJ5IHN0cmluZyBjb21wYXJlIGRvZXMgbm90IHdvcmsuIFBlcmZvcm1hbmFuY2UgaXMgdmVyeSBnb29kIHNvIEhFWCBpcyB1c2VkLi4gIGxvY2FsZUNvbXBhcmUgaXMgYW5vdGhlciBvcHRpb24uXG4gICAgICAgIEJ1ZmZlci5pc0J1ZmZlcihmaXJzdEVsKGEpKSAmJiBCdWZmZXIuaXNCdWZmZXIoZmlyc3RFbChiKSkgPyBzdHJDbXAoZmlyc3RFbChhKS50b1N0cmluZyhcImhleFwiKSwgZmlyc3RFbChiKS50b1N0cmluZyhcImhleFwiKSkgOiBzdHJDbXAoZmlyc3RFbChhKS50b1N0cmluZygpLCBmaXJzdEVsKGIpLnRvU3RyaW5nKCkpO1xuICAgIH0pO1xufTsiLCIndXNlIHN0cmljdCc7XG5cbi8vIGNvbXBhcmUgYW5kIGlzQnVmZmVyIHRha2VuIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvYmxvYi82ODBlOWU1ZTQ4OGYyMmFhYzI3NTk5YTU3ZGM4NDRhNjMxNTkyOGRkL2luZGV4LmpzXG4vLyBvcmlnaW5hbCBub3RpY2U6XG5cbi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmUoYSwgYikge1xuICBpZiAoYSA9PT0gYikge1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgdmFyIHggPSBhLmxlbmd0aDtcbiAgdmFyIHkgPSBiLmxlbmd0aDtcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICB4ID0gYVtpXTtcbiAgICAgIHkgPSBiW2ldO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGlmICh5IDwgeCkge1xuICAgIHJldHVybiAxO1xuICB9XG4gIHJldHVybiAwO1xufVxuZnVuY3Rpb24gaXNCdWZmZXIoYikge1xuICBpZiAoZ2xvYmFsLkJ1ZmZlciAmJiB0eXBlb2YgZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKGIpO1xuICB9XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpO1xufVxuXG4vLyBiYXNlZCBvbiBub2RlIGFzc2VydCwgb3JpZ2luYWwgbm90aWNlOlxuXG4vLyBodHRwOi8vd2lraS5jb21tb25qcy5vcmcvd2lraS9Vbml0X1Rlc3RpbmcvMS4wXG4vL1xuLy8gVEhJUyBJUyBOT1QgVEVTVEVEIE5PUiBMSUtFTFkgVE8gV09SSyBPVVRTSURFIFY4IVxuLy9cbi8vIE9yaWdpbmFsbHkgZnJvbSBuYXJ3aGFsLmpzIChodHRwOi8vbmFyd2hhbGpzLm9yZylcbi8vIENvcHlyaWdodCAoYykgMjAwOSBUaG9tYXMgUm9iaW5zb24gPDI4MG5vcnRoLmNvbT5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAnU29mdHdhcmUnKSwgdG9cbi8vIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Jcbi8vIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgJ0FTIElTJywgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOXG4vLyBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OXG4vLyBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsLycpO1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgcFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGZ1bmN0aW9uc0hhdmVOYW1lcyA9IChmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmb28oKSB7fS5uYW1lID09PSAnZm9vJztcbn0oKSk7XG5mdW5jdGlvbiBwVG9TdHJpbmcgKG9iaikge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaik7XG59XG5mdW5jdGlvbiBpc1ZpZXcoYXJyYnVmKSB7XG4gIGlmIChpc0J1ZmZlcihhcnJidWYpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0eXBlb2YgZ2xvYmFsLkFycmF5QnVmZmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIEFycmF5QnVmZmVyLmlzVmlldyhhcnJidWYpO1xuICB9XG4gIGlmICghYXJyYnVmKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChhcnJidWYgaW5zdGFuY2VvZiBEYXRhVmlldykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChhcnJidWYuYnVmZmVyICYmIGFycmJ1Zi5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cbi8vIDEuIFRoZSBhc3NlcnQgbW9kdWxlIHByb3ZpZGVzIGZ1bmN0aW9ucyB0aGF0IHRocm93XG4vLyBBc3NlcnRpb25FcnJvcidzIHdoZW4gcGFydGljdWxhciBjb25kaXRpb25zIGFyZSBub3QgbWV0LiBUaGVcbi8vIGFzc2VydCBtb2R1bGUgbXVzdCBjb25mb3JtIHRvIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlLlxuXG52YXIgYXNzZXJ0ID0gbW9kdWxlLmV4cG9ydHMgPSBvaztcblxuLy8gMi4gVGhlIEFzc2VydGlvbkVycm9yIGlzIGRlZmluZWQgaW4gYXNzZXJ0LlxuLy8gbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7IG1lc3NhZ2U6IG1lc3NhZ2UsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkIH0pXG5cbnZhciByZWdleCA9IC9cXHMqZnVuY3Rpb25cXHMrKFteXFwoXFxzXSopXFxzKi87XG4vLyBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vbGpoYXJiL2Z1bmN0aW9uLnByb3RvdHlwZS5uYW1lL2Jsb2IvYWRlZWVlYzhiZmNjNjA2OGIxODdkN2Q5ZmIzZDViYjFkM2EzMDg5OS9pbXBsZW1lbnRhdGlvbi5qc1xuZnVuY3Rpb24gZ2V0TmFtZShmdW5jKSB7XG4gIGlmICghdXRpbC5pc0Z1bmN0aW9uKGZ1bmMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChmdW5jdGlvbnNIYXZlTmFtZXMpIHtcbiAgICByZXR1cm4gZnVuYy5uYW1lO1xuICB9XG4gIHZhciBzdHIgPSBmdW5jLnRvU3RyaW5nKCk7XG4gIHZhciBtYXRjaCA9IHN0ci5tYXRjaChyZWdleCk7XG4gIHJldHVybiBtYXRjaCAmJiBtYXRjaFsxXTtcbn1cbmFzc2VydC5Bc3NlcnRpb25FcnJvciA9IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG9wdGlvbnMpIHtcbiAgdGhpcy5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJztcbiAgdGhpcy5hY3R1YWwgPSBvcHRpb25zLmFjdHVhbDtcbiAgdGhpcy5leHBlY3RlZCA9IG9wdGlvbnMuZXhwZWN0ZWQ7XG4gIHRoaXMub3BlcmF0b3IgPSBvcHRpb25zLm9wZXJhdG9yO1xuICBpZiAob3B0aW9ucy5tZXNzYWdlKSB7XG4gICAgdGhpcy5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMubWVzc2FnZSA9IGdldE1lc3NhZ2UodGhpcyk7XG4gICAgdGhpcy5nZW5lcmF0ZWRNZXNzYWdlID0gdHJ1ZTtcbiAgfVxuICB2YXIgc3RhY2tTdGFydEZ1bmN0aW9uID0gb3B0aW9ucy5zdGFja1N0YXJ0RnVuY3Rpb24gfHwgZmFpbDtcbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgc3RhY2tTdGFydEZ1bmN0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBub24gdjggYnJvd3NlcnMgc28gd2UgY2FuIGhhdmUgYSBzdGFja3RyYWNlXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcigpO1xuICAgIGlmIChlcnIuc3RhY2spIHtcbiAgICAgIHZhciBvdXQgPSBlcnIuc3RhY2s7XG5cbiAgICAgIC8vIHRyeSB0byBzdHJpcCB1c2VsZXNzIGZyYW1lc1xuICAgICAgdmFyIGZuX25hbWUgPSBnZXROYW1lKHN0YWNrU3RhcnRGdW5jdGlvbik7XG4gICAgICB2YXIgaWR4ID0gb3V0LmluZGV4T2YoJ1xcbicgKyBmbl9uYW1lKTtcbiAgICAgIGlmIChpZHggPj0gMCkge1xuICAgICAgICAvLyBvbmNlIHdlIGhhdmUgbG9jYXRlZCB0aGUgZnVuY3Rpb24gZnJhbWVcbiAgICAgICAgLy8gd2UgbmVlZCB0byBzdHJpcCBvdXQgZXZlcnl0aGluZyBiZWZvcmUgaXQgKGFuZCBpdHMgbGluZSlcbiAgICAgICAgdmFyIG5leHRfbGluZSA9IG91dC5pbmRleE9mKCdcXG4nLCBpZHggKyAxKTtcbiAgICAgICAgb3V0ID0gb3V0LnN1YnN0cmluZyhuZXh0X2xpbmUgKyAxKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zdGFjayA9IG91dDtcbiAgICB9XG4gIH1cbn07XG5cbi8vIGFzc2VydC5Bc3NlcnRpb25FcnJvciBpbnN0YW5jZW9mIEVycm9yXG51dGlsLmluaGVyaXRzKGFzc2VydC5Bc3NlcnRpb25FcnJvciwgRXJyb3IpO1xuXG5mdW5jdGlvbiB0cnVuY2F0ZShzLCBuKSB7XG4gIGlmICh0eXBlb2YgcyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gcy5sZW5ndGggPCBuID8gcyA6IHMuc2xpY2UoMCwgbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHM7XG4gIH1cbn1cbmZ1bmN0aW9uIGluc3BlY3Qoc29tZXRoaW5nKSB7XG4gIGlmIChmdW5jdGlvbnNIYXZlTmFtZXMgfHwgIXV0aWwuaXNGdW5jdGlvbihzb21ldGhpbmcpKSB7XG4gICAgcmV0dXJuIHV0aWwuaW5zcGVjdChzb21ldGhpbmcpO1xuICB9XG4gIHZhciByYXduYW1lID0gZ2V0TmFtZShzb21ldGhpbmcpO1xuICB2YXIgbmFtZSA9IHJhd25hbWUgPyAnOiAnICsgcmF3bmFtZSA6ICcnO1xuICByZXR1cm4gJ1tGdW5jdGlvbicgKyAgbmFtZSArICddJztcbn1cbmZ1bmN0aW9uIGdldE1lc3NhZ2Uoc2VsZikge1xuICByZXR1cm4gdHJ1bmNhdGUoaW5zcGVjdChzZWxmLmFjdHVhbCksIDEyOCkgKyAnICcgK1xuICAgICAgICAgc2VsZi5vcGVyYXRvciArICcgJyArXG4gICAgICAgICB0cnVuY2F0ZShpbnNwZWN0KHNlbGYuZXhwZWN0ZWQpLCAxMjgpO1xufVxuXG4vLyBBdCBwcmVzZW50IG9ubHkgdGhlIHRocmVlIGtleXMgbWVudGlvbmVkIGFib3ZlIGFyZSB1c2VkIGFuZFxuLy8gdW5kZXJzdG9vZCBieSB0aGUgc3BlYy4gSW1wbGVtZW50YXRpb25zIG9yIHN1YiBtb2R1bGVzIGNhbiBwYXNzXG4vLyBvdGhlciBrZXlzIHRvIHRoZSBBc3NlcnRpb25FcnJvcidzIGNvbnN0cnVjdG9yIC0gdGhleSB3aWxsIGJlXG4vLyBpZ25vcmVkLlxuXG4vLyAzLiBBbGwgb2YgdGhlIGZvbGxvd2luZyBmdW5jdGlvbnMgbXVzdCB0aHJvdyBhbiBBc3NlcnRpb25FcnJvclxuLy8gd2hlbiBhIGNvcnJlc3BvbmRpbmcgY29uZGl0aW9uIGlzIG5vdCBtZXQsIHdpdGggYSBtZXNzYWdlIHRoYXRcbi8vIG1heSBiZSB1bmRlZmluZWQgaWYgbm90IHByb3ZpZGVkLiAgQWxsIGFzc2VydGlvbiBtZXRob2RzIHByb3ZpZGVcbi8vIGJvdGggdGhlIGFjdHVhbCBhbmQgZXhwZWN0ZWQgdmFsdWVzIHRvIHRoZSBhc3NlcnRpb24gZXJyb3IgZm9yXG4vLyBkaXNwbGF5IHB1cnBvc2VzLlxuXG5mdW5jdGlvbiBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wZXJhdG9yLCBzdGFja1N0YXJ0RnVuY3Rpb24pIHtcbiAgdGhyb3cgbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7XG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICBhY3R1YWw6IGFjdHVhbCxcbiAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgb3BlcmF0b3I6IG9wZXJhdG9yLFxuICAgIHN0YWNrU3RhcnRGdW5jdGlvbjogc3RhY2tTdGFydEZ1bmN0aW9uXG4gIH0pO1xufVxuXG4vLyBFWFRFTlNJT04hIGFsbG93cyBmb3Igd2VsbCBiZWhhdmVkIGVycm9ycyBkZWZpbmVkIGVsc2V3aGVyZS5cbmFzc2VydC5mYWlsID0gZmFpbDtcblxuLy8gNC4gUHVyZSBhc3NlcnRpb24gdGVzdHMgd2hldGhlciBhIHZhbHVlIGlzIHRydXRoeSwgYXMgZGV0ZXJtaW5lZFxuLy8gYnkgISFndWFyZC5cbi8vIGFzc2VydC5vayhndWFyZCwgbWVzc2FnZV9vcHQpO1xuLy8gVGhpcyBzdGF0ZW1lbnQgaXMgZXF1aXZhbGVudCB0byBhc3NlcnQuZXF1YWwodHJ1ZSwgISFndWFyZCxcbi8vIG1lc3NhZ2Vfb3B0KTsuIFRvIHRlc3Qgc3RyaWN0bHkgZm9yIHRoZSB2YWx1ZSB0cnVlLCB1c2Vcbi8vIGFzc2VydC5zdHJpY3RFcXVhbCh0cnVlLCBndWFyZCwgbWVzc2FnZV9vcHQpOy5cblxuZnVuY3Rpb24gb2sodmFsdWUsIG1lc3NhZ2UpIHtcbiAgaWYgKCF2YWx1ZSkgZmFpbCh2YWx1ZSwgdHJ1ZSwgbWVzc2FnZSwgJz09JywgYXNzZXJ0Lm9rKTtcbn1cbmFzc2VydC5vayA9IG9rO1xuXG4vLyA1LiBUaGUgZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIHNoYWxsb3csIGNvZXJjaXZlIGVxdWFsaXR5IHdpdGhcbi8vID09LlxuLy8gYXNzZXJ0LmVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LmVxdWFsID0gZnVuY3Rpb24gZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9IGV4cGVjdGVkKSBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5lcXVhbCk7XG59O1xuXG4vLyA2LiBUaGUgbm9uLWVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBmb3Igd2hldGhlciB0d28gb2JqZWN0cyBhcmUgbm90IGVxdWFsXG4vLyB3aXRoICE9IGFzc2VydC5ub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3RFcXVhbCA9IGZ1bmN0aW9uIG5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCA9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJyE9JywgYXNzZXJ0Lm5vdEVxdWFsKTtcbiAgfVxufTtcblxuLy8gNy4gVGhlIGVxdWl2YWxlbmNlIGFzc2VydGlvbiB0ZXN0cyBhIGRlZXAgZXF1YWxpdHkgcmVsYXRpb24uXG4vLyBhc3NlcnQuZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LmRlZXBFcXVhbCA9IGZ1bmN0aW9uIGRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmICghX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBmYWxzZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwRXF1YWwnLCBhc3NlcnQuZGVlcEVxdWFsKTtcbiAgfVxufTtcblxuYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIGRlZXBTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmICghX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCB0cnVlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ2RlZXBTdHJpY3RFcXVhbCcsIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIHN0cmljdCwgbWVtb3MpIHtcbiAgLy8gNy4xLiBBbGwgaWRlbnRpY2FsIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgYXMgZGV0ZXJtaW5lZCBieSA9PT0uXG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoaXNCdWZmZXIoYWN0dWFsKSAmJiBpc0J1ZmZlcihleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gY29tcGFyZShhY3R1YWwsIGV4cGVjdGVkKSA9PT0gMDtcblxuICAvLyA3LjIuIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIERhdGUgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIERhdGUgb2JqZWN0IHRoYXQgcmVmZXJzIHRvIHRoZSBzYW1lIHRpbWUuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0RhdGUoYWN0dWFsKSAmJiB1dGlsLmlzRGF0ZShleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLmdldFRpbWUoKSA9PT0gZXhwZWN0ZWQuZ2V0VGltZSgpO1xuXG4gIC8vIDcuMyBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIFJlZ0V4cCBvYmplY3Qgd2l0aCB0aGUgc2FtZSBzb3VyY2UgYW5kXG4gIC8vIHByb3BlcnRpZXMgKGBnbG9iYWxgLCBgbXVsdGlsaW5lYCwgYGxhc3RJbmRleGAsIGBpZ25vcmVDYXNlYCkuXG4gIH0gZWxzZSBpZiAodXRpbC5pc1JlZ0V4cChhY3R1YWwpICYmIHV0aWwuaXNSZWdFeHAoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5zb3VyY2UgPT09IGV4cGVjdGVkLnNvdXJjZSAmJlxuICAgICAgICAgICBhY3R1YWwuZ2xvYmFsID09PSBleHBlY3RlZC5nbG9iYWwgJiZcbiAgICAgICAgICAgYWN0dWFsLm11bHRpbGluZSA9PT0gZXhwZWN0ZWQubXVsdGlsaW5lICYmXG4gICAgICAgICAgIGFjdHVhbC5sYXN0SW5kZXggPT09IGV4cGVjdGVkLmxhc3RJbmRleCAmJlxuICAgICAgICAgICBhY3R1YWwuaWdub3JlQ2FzZSA9PT0gZXhwZWN0ZWQuaWdub3JlQ2FzZTtcblxuICAvLyA3LjQuIE90aGVyIHBhaXJzIHRoYXQgZG8gbm90IGJvdGggcGFzcyB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcsXG4gIC8vIGVxdWl2YWxlbmNlIGlzIGRldGVybWluZWQgYnkgPT0uXG4gIH0gZWxzZSBpZiAoKGFjdHVhbCA9PT0gbnVsbCB8fCB0eXBlb2YgYWN0dWFsICE9PSAnb2JqZWN0JykgJiZcbiAgICAgICAgICAgICAoZXhwZWN0ZWQgPT09IG51bGwgfHwgdHlwZW9mIGV4cGVjdGVkICE9PSAnb2JqZWN0JykpIHtcbiAgICByZXR1cm4gc3RyaWN0ID8gYWN0dWFsID09PSBleHBlY3RlZCA6IGFjdHVhbCA9PSBleHBlY3RlZDtcblxuICAvLyBJZiBib3RoIHZhbHVlcyBhcmUgaW5zdGFuY2VzIG9mIHR5cGVkIGFycmF5cywgd3JhcCB0aGVpciB1bmRlcmx5aW5nXG4gIC8vIEFycmF5QnVmZmVycyBpbiBhIEJ1ZmZlciBlYWNoIHRvIGluY3JlYXNlIHBlcmZvcm1hbmNlXG4gIC8vIFRoaXMgb3B0aW1pemF0aW9uIHJlcXVpcmVzIHRoZSBhcnJheXMgdG8gaGF2ZSB0aGUgc2FtZSB0eXBlIGFzIGNoZWNrZWQgYnlcbiAgLy8gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyAoYWthIHBUb1N0cmluZykuIE5ldmVyIHBlcmZvcm0gYmluYXJ5XG4gIC8vIGNvbXBhcmlzb25zIGZvciBGbG9hdCpBcnJheXMsIHRob3VnaCwgc2luY2UgZS5nLiArMCA9PT0gLTAgYnV0IHRoZWlyXG4gIC8vIGJpdCBwYXR0ZXJucyBhcmUgbm90IGlkZW50aWNhbC5cbiAgfSBlbHNlIGlmIChpc1ZpZXcoYWN0dWFsKSAmJiBpc1ZpZXcoZXhwZWN0ZWQpICYmXG4gICAgICAgICAgICAgcFRvU3RyaW5nKGFjdHVhbCkgPT09IHBUb1N0cmluZyhleHBlY3RlZCkgJiZcbiAgICAgICAgICAgICAhKGFjdHVhbCBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSB8fFxuICAgICAgICAgICAgICAgYWN0dWFsIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5KSkge1xuICAgIHJldHVybiBjb21wYXJlKG5ldyBVaW50OEFycmF5KGFjdHVhbC5idWZmZXIpLFxuICAgICAgICAgICAgICAgICAgIG5ldyBVaW50OEFycmF5KGV4cGVjdGVkLmJ1ZmZlcikpID09PSAwO1xuXG4gIC8vIDcuNSBGb3IgYWxsIG90aGVyIE9iamVjdCBwYWlycywgaW5jbHVkaW5nIEFycmF5IG9iamVjdHMsIGVxdWl2YWxlbmNlIGlzXG4gIC8vIGRldGVybWluZWQgYnkgaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChhcyB2ZXJpZmllZFxuICAvLyB3aXRoIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCksIHRoZSBzYW1lIHNldCBvZiBrZXlzXG4gIC8vIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLCBlcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnlcbiAgLy8gY29ycmVzcG9uZGluZyBrZXksIGFuZCBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuIE5vdGU6IHRoaXNcbiAgLy8gYWNjb3VudHMgZm9yIGJvdGggbmFtZWQgYW5kIGluZGV4ZWQgcHJvcGVydGllcyBvbiBBcnJheXMuXG4gIH0gZWxzZSBpZiAoaXNCdWZmZXIoYWN0dWFsKSAhPT0gaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIG1lbW9zID0gbWVtb3MgfHwge2FjdHVhbDogW10sIGV4cGVjdGVkOiBbXX07XG5cbiAgICB2YXIgYWN0dWFsSW5kZXggPSBtZW1vcy5hY3R1YWwuaW5kZXhPZihhY3R1YWwpO1xuICAgIGlmIChhY3R1YWxJbmRleCAhPT0gLTEpIHtcbiAgICAgIGlmIChhY3R1YWxJbmRleCA9PT0gbWVtb3MuZXhwZWN0ZWQuaW5kZXhPZihleHBlY3RlZCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbWVtb3MuYWN0dWFsLnB1c2goYWN0dWFsKTtcbiAgICBtZW1vcy5leHBlY3RlZC5wdXNoKGV4cGVjdGVkKTtcblxuICAgIHJldHVybiBvYmpFcXVpdihhY3R1YWwsIGV4cGVjdGVkLCBzdHJpY3QsIG1lbW9zKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0FyZ3VtZW50cyhvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xufVxuXG5mdW5jdGlvbiBvYmpFcXVpdihhLCBiLCBzdHJpY3QsIGFjdHVhbFZpc2l0ZWRPYmplY3RzKSB7XG4gIGlmIChhID09PSBudWxsIHx8IGEgPT09IHVuZGVmaW5lZCB8fCBiID09PSBudWxsIHx8IGIgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vIGlmIG9uZSBpcyBhIHByaW1pdGl2ZSwgdGhlIG90aGVyIG11c3QgYmUgc2FtZVxuICBpZiAodXRpbC5pc1ByaW1pdGl2ZShhKSB8fCB1dGlsLmlzUHJpbWl0aXZlKGIpKVxuICAgIHJldHVybiBhID09PSBiO1xuICBpZiAoc3RyaWN0ICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSAhPT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGIpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgdmFyIGFJc0FyZ3MgPSBpc0FyZ3VtZW50cyhhKTtcbiAgdmFyIGJJc0FyZ3MgPSBpc0FyZ3VtZW50cyhiKTtcbiAgaWYgKChhSXNBcmdzICYmICFiSXNBcmdzKSB8fCAoIWFJc0FyZ3MgJiYgYklzQXJncykpXG4gICAgcmV0dXJuIGZhbHNlO1xuICBpZiAoYUlzQXJncykge1xuICAgIGEgPSBwU2xpY2UuY2FsbChhKTtcbiAgICBiID0gcFNsaWNlLmNhbGwoYik7XG4gICAgcmV0dXJuIF9kZWVwRXF1YWwoYSwgYiwgc3RyaWN0KTtcbiAgfVxuICB2YXIga2EgPSBvYmplY3RLZXlzKGEpO1xuICB2YXIga2IgPSBvYmplY3RLZXlzKGIpO1xuICB2YXIga2V5LCBpO1xuICAvLyBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGtleXMgaW5jb3Jwb3JhdGVzXG4gIC8vIGhhc093blByb3BlcnR5KVxuICBpZiAoa2EubGVuZ3RoICE9PSBrYi5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlO1xuICAvL3RoZSBzYW1lIHNldCBvZiBrZXlzIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLFxuICBrYS5zb3J0KCk7XG4gIGtiLnNvcnQoKTtcbiAgLy9+fn5jaGVhcCBrZXkgdGVzdFxuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGlmIChrYVtpXSAhPT0ga2JbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9lcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnkgY29ycmVzcG9uZGluZyBrZXksIGFuZFxuICAvL35+fnBvc3NpYmx5IGV4cGVuc2l2ZSBkZWVwIHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBrZXkgPSBrYVtpXTtcbiAgICBpZiAoIV9kZWVwRXF1YWwoYVtrZXldLCBiW2tleV0sIHN0cmljdCwgYWN0dWFsVmlzaXRlZE9iamVjdHMpKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vLyA4LiBUaGUgbm9uLWVxdWl2YWxlbmNlIGFzc2VydGlvbiB0ZXN0cyBmb3IgYW55IGRlZXAgaW5lcXVhbGl0eS5cbi8vIGFzc2VydC5ub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RGVlcEVxdWFsID0gZnVuY3Rpb24gbm90RGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgZmFsc2UpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnbm90RGVlcEVxdWFsJywgYXNzZXJ0Lm5vdERlZXBFcXVhbCk7XG4gIH1cbn07XG5cbmFzc2VydC5ub3REZWVwU3RyaWN0RXF1YWwgPSBub3REZWVwU3RyaWN0RXF1YWw7XG5mdW5jdGlvbiBub3REZWVwU3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCB0cnVlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBTdHJpY3RFcXVhbCcsIG5vdERlZXBTdHJpY3RFcXVhbCk7XG4gIH1cbn1cblxuXG4vLyA5LiBUaGUgc3RyaWN0IGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzdHJpY3QgZXF1YWxpdHksIGFzIGRldGVybWluZWQgYnkgPT09LlxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnN0cmljdEVxdWFsID0gZnVuY3Rpb24gc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09PScsIGFzc2VydC5zdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDEwLiBUaGUgc3RyaWN0IG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHN0cmljdCBpbmVxdWFsaXR5LCBhc1xuLy8gZGV0ZXJtaW5lZCBieSAhPT0uICBhc3NlcnQubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90U3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT09JywgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkge1xuICBpZiAoIWFjdHVhbCB8fCAhZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGV4cGVjdGVkKSA9PSAnW29iamVjdCBSZWdFeHBdJykge1xuICAgIHJldHVybiBleHBlY3RlZC50ZXN0KGFjdHVhbCk7XG4gIH1cblxuICB0cnkge1xuICAgIGlmIChhY3R1YWwgaW5zdGFuY2VvZiBleHBlY3RlZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gSWdub3JlLiAgVGhlIGluc3RhbmNlb2YgY2hlY2sgZG9lc24ndCB3b3JrIGZvciBhcnJvdyBmdW5jdGlvbnMuXG4gIH1cblxuICBpZiAoRXJyb3IuaXNQcm90b3R5cGVPZihleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gZXhwZWN0ZWQuY2FsbCh7fSwgYWN0dWFsKSA9PT0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gX3RyeUJsb2NrKGJsb2NrKSB7XG4gIHZhciBlcnJvcjtcbiAgdHJ5IHtcbiAgICBibG9jaygpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyb3IgPSBlO1xuICB9XG4gIHJldHVybiBlcnJvcjtcbn1cblxuZnVuY3Rpb24gX3Rocm93cyhzaG91bGRUaHJvdywgYmxvY2ssIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIHZhciBhY3R1YWw7XG5cbiAgaWYgKHR5cGVvZiBibG9jayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYmxvY2tcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZXhwZWN0ZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgbWVzc2FnZSA9IGV4cGVjdGVkO1xuICAgIGV4cGVjdGVkID0gbnVsbDtcbiAgfVxuXG4gIGFjdHVhbCA9IF90cnlCbG9jayhibG9jayk7XG5cbiAgbWVzc2FnZSA9IChleHBlY3RlZCAmJiBleHBlY3RlZC5uYW1lID8gJyAoJyArIGV4cGVjdGVkLm5hbWUgKyAnKS4nIDogJy4nKSArXG4gICAgICAgICAgICAobWVzc2FnZSA/ICcgJyArIG1lc3NhZ2UgOiAnLicpO1xuXG4gIGlmIChzaG91bGRUaHJvdyAmJiAhYWN0dWFsKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnTWlzc2luZyBleHBlY3RlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICB2YXIgdXNlclByb3ZpZGVkTWVzc2FnZSA9IHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJztcbiAgdmFyIGlzVW53YW50ZWRFeGNlcHRpb24gPSAhc2hvdWxkVGhyb3cgJiYgdXRpbC5pc0Vycm9yKGFjdHVhbCk7XG4gIHZhciBpc1VuZXhwZWN0ZWRFeGNlcHRpb24gPSAhc2hvdWxkVGhyb3cgJiYgYWN0dWFsICYmICFleHBlY3RlZDtcblxuICBpZiAoKGlzVW53YW50ZWRFeGNlcHRpb24gJiZcbiAgICAgIHVzZXJQcm92aWRlZE1lc3NhZ2UgJiZcbiAgICAgIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB8fFxuICAgICAgaXNVbmV4cGVjdGVkRXhjZXB0aW9uKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnR290IHVud2FudGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIGlmICgoc2hvdWxkVGhyb3cgJiYgYWN0dWFsICYmIGV4cGVjdGVkICYmXG4gICAgICAhZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8ICghc2hvdWxkVGhyb3cgJiYgYWN0dWFsKSkge1xuICAgIHRocm93IGFjdHVhbDtcbiAgfVxufVxuXG4vLyAxMS4gRXhwZWN0ZWQgdG8gdGhyb3cgYW4gZXJyb3I6XG4vLyBhc3NlcnQudGhyb3dzKGJsb2NrLCBFcnJvcl9vcHQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnRocm93cyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzKHRydWUsIGJsb2NrLCBlcnJvciwgbWVzc2FnZSk7XG59O1xuXG4vLyBFWFRFTlNJT04hIFRoaXMgaXMgYW5ub3lpbmcgdG8gd3JpdGUgb3V0c2lkZSB0aGlzIG1vZHVsZS5cbmFzc2VydC5kb2VzTm90VGhyb3cgPSBmdW5jdGlvbihibG9jaywgLypvcHRpb25hbCovZXJyb3IsIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cyhmYWxzZSwgYmxvY2ssIGVycm9yLCBtZXNzYWdlKTtcbn07XG5cbmFzc2VydC5pZkVycm9yID0gZnVuY3Rpb24oZXJyKSB7IGlmIChlcnIpIHRocm93IGVycjsgfTtcblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoaGFzT3duLmNhbGwob2JqLCBrZXkpKSBrZXlzLnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4ga2V5cztcbn07XG4iLCIvLyBiYXNlLXggZW5jb2Rpbmdcbi8vIEZvcmtlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG9jb2luanMvYnM1OFxuLy8gT3JpZ2luYWxseSB3cml0dGVuIGJ5IE1pa2UgSGVhcm4gZm9yIEJpdGNvaW5KXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTEgR29vZ2xlIEluY1xuLy8gUG9ydGVkIHRvIEphdmFTY3JpcHQgYnkgU3RlZmFuIFRob21hc1xuLy8gTWVyZ2VkIEJ1ZmZlciByZWZhY3RvcmluZ3MgZnJvbSBiYXNlNTgtbmF0aXZlIGJ5IFN0ZXBoZW4gUGFpclxuLy8gQ29weXJpZ2h0IChjKSAyMDEzIEJpdFBheSBJbmNcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiYXNlIChBTFBIQUJFVCkge1xuICB2YXIgQUxQSEFCRVRfTUFQID0ge31cbiAgdmFyIEJBU0UgPSBBTFBIQUJFVC5sZW5ndGhcbiAgdmFyIExFQURFUiA9IEFMUEhBQkVULmNoYXJBdCgwKVxuXG4gIC8vIHByZS1jb21wdXRlIGxvb2t1cCB0YWJsZVxuICBmb3IgKHZhciBpID0gMDsgaSA8IEFMUEhBQkVULmxlbmd0aDsgaSsrKSB7XG4gICAgQUxQSEFCRVRfTUFQW0FMUEhBQkVULmNoYXJBdChpKV0gPSBpXG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGUgKHNvdXJjZSkge1xuICAgIGlmIChzb3VyY2UubGVuZ3RoID09PSAwKSByZXR1cm4gJydcblxuICAgIHZhciBkaWdpdHMgPSBbMF1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGg7ICsraSkge1xuICAgICAgZm9yICh2YXIgaiA9IDAsIGNhcnJ5ID0gc291cmNlW2ldOyBqIDwgZGlnaXRzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIGNhcnJ5ICs9IGRpZ2l0c1tqXSA8PCA4XG4gICAgICAgIGRpZ2l0c1tqXSA9IGNhcnJ5ICUgQkFTRVxuICAgICAgICBjYXJyeSA9IChjYXJyeSAvIEJBU0UpIHwgMFxuICAgICAgfVxuXG4gICAgICB3aGlsZSAoY2FycnkgPiAwKSB7XG4gICAgICAgIGRpZ2l0cy5wdXNoKGNhcnJ5ICUgQkFTRSlcbiAgICAgICAgY2FycnkgPSAoY2FycnkgLyBCQVNFKSB8IDBcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc3RyaW5nID0gJydcblxuICAgIC8vIGRlYWwgd2l0aCBsZWFkaW5nIHplcm9zXG4gICAgZm9yICh2YXIgayA9IDA7IHNvdXJjZVtrXSA9PT0gMCAmJiBrIDwgc291cmNlLmxlbmd0aCAtIDE7ICsraykgc3RyaW5nICs9IEFMUEhBQkVUWzBdXG4gICAgLy8gY29udmVydCBkaWdpdHMgdG8gYSBzdHJpbmdcbiAgICBmb3IgKHZhciBxID0gZGlnaXRzLmxlbmd0aCAtIDE7IHEgPj0gMDsgLS1xKSBzdHJpbmcgKz0gQUxQSEFCRVRbZGlnaXRzW3FdXVxuXG4gICAgcmV0dXJuIHN0cmluZ1xuICB9XG5cbiAgZnVuY3Rpb24gZGVjb2RlVW5zYWZlIChzdHJpbmcpIHtcbiAgICBpZiAoc3RyaW5nLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdXG5cbiAgICB2YXIgYnl0ZXMgPSBbMF1cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHZhbHVlID0gQUxQSEFCRVRfTUFQW3N0cmluZ1tpXV1cbiAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm5cblxuICAgICAgZm9yICh2YXIgaiA9IDAsIGNhcnJ5ID0gdmFsdWU7IGogPCBieXRlcy5sZW5ndGg7ICsraikge1xuICAgICAgICBjYXJyeSArPSBieXRlc1tqXSAqIEJBU0VcbiAgICAgICAgYnl0ZXNbal0gPSBjYXJyeSAmIDB4ZmZcbiAgICAgICAgY2FycnkgPj49IDhcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKGNhcnJ5ID4gMCkge1xuICAgICAgICBieXRlcy5wdXNoKGNhcnJ5ICYgMHhmZilcbiAgICAgICAgY2FycnkgPj49IDhcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkZWFsIHdpdGggbGVhZGluZyB6ZXJvc1xuICAgIGZvciAodmFyIGsgPSAwOyBzdHJpbmdba10gPT09IExFQURFUiAmJiBrIDwgc3RyaW5nLmxlbmd0aCAtIDE7ICsraykge1xuICAgICAgYnl0ZXMucHVzaCgwKVxuICAgIH1cblxuICAgIHJldHVybiBieXRlcy5yZXZlcnNlKClcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlY29kZSAoc3RyaW5nKSB7XG4gICAgdmFyIGFycmF5ID0gZGVjb2RlVW5zYWZlKHN0cmluZylcbiAgICBpZiAoYXJyYXkpIHJldHVybiBhcnJheVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdOb24tYmFzZScgKyBCQVNFICsgJyBjaGFyYWN0ZXInKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlbmNvZGU6IGVuY29kZSxcbiAgICBkZWNvZGVVbnNhZmU6IGRlY29kZVVuc2FmZSxcbiAgICBkZWNvZGU6IGRlY29kZVxuICB9XG59XG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKFxuICAgICAgdWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKVxuICAgICkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIi8vIChwdWJsaWMpIENvbnN0cnVjdG9yXG5mdW5jdGlvbiBCaWdJbnRlZ2VyKGEsIGIsIGMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJpZ0ludGVnZXIpKVxuICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihhLCBiLCBjKVxuXG4gIGlmIChhICE9IG51bGwpIHtcbiAgICBpZiAoXCJudW1iZXJcIiA9PSB0eXBlb2YgYSkgdGhpcy5mcm9tTnVtYmVyKGEsIGIsIGMpXG4gICAgZWxzZSBpZiAoYiA9PSBudWxsICYmIFwic3RyaW5nXCIgIT0gdHlwZW9mIGEpIHRoaXMuZnJvbVN0cmluZyhhLCAyNTYpXG4gICAgZWxzZSB0aGlzLmZyb21TdHJpbmcoYSwgYilcbiAgfVxufVxuXG52YXIgcHJvdG8gPSBCaWdJbnRlZ2VyLnByb3RvdHlwZVxuXG4vLyBkdWNrLXR5cGVkIGlzQmlnSW50ZWdlclxucHJvdG8uX19iaWdpID0gcmVxdWlyZSgnLi4vcGFja2FnZS5qc29uJykudmVyc2lvblxuQmlnSW50ZWdlci5pc0JpZ0ludGVnZXIgPSBmdW5jdGlvbiAob2JqLCBjaGVja192ZXIpIHtcbiAgcmV0dXJuIG9iaiAmJiBvYmouX19iaWdpICYmICghY2hlY2tfdmVyIHx8IG9iai5fX2JpZ2kgPT09IHByb3RvLl9fYmlnaSlcbn1cblxuLy8gQml0cyBwZXIgZGlnaXRcbnZhciBkYml0c1xuXG4vLyBhbTogQ29tcHV0ZSB3X2ogKz0gKHgqdGhpc19pKSwgcHJvcGFnYXRlIGNhcnJpZXMsXG4vLyBjIGlzIGluaXRpYWwgY2FycnksIHJldHVybnMgZmluYWwgY2FycnkuXG4vLyBjIDwgMypkdmFsdWUsIHggPCAyKmR2YWx1ZSwgdGhpc19pIDwgZHZhbHVlXG4vLyBXZSBuZWVkIHRvIHNlbGVjdCB0aGUgZmFzdGVzdCBvbmUgdGhhdCB3b3JrcyBpbiB0aGlzIGVudmlyb25tZW50LlxuXG4vLyBhbTE6IHVzZSBhIHNpbmdsZSBtdWx0IGFuZCBkaXZpZGUgdG8gZ2V0IHRoZSBoaWdoIGJpdHMsXG4vLyBtYXggZGlnaXQgYml0cyBzaG91bGQgYmUgMjYgYmVjYXVzZVxuLy8gbWF4IGludGVybmFsIHZhbHVlID0gMipkdmFsdWVeMi0yKmR2YWx1ZSAoPCAyXjUzKVxuZnVuY3Rpb24gYW0xKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIHYgPSB4ICogdGhpc1tpKytdICsgd1tqXSArIGNcbiAgICBjID0gTWF0aC5mbG9vcih2IC8gMHg0MDAwMDAwKVxuICAgIHdbaisrXSA9IHYgJiAweDNmZmZmZmZcbiAgfVxuICByZXR1cm4gY1xufVxuLy8gYW0yIGF2b2lkcyBhIGJpZyBtdWx0LWFuZC1leHRyYWN0IGNvbXBsZXRlbHkuXG4vLyBNYXggZGlnaXQgYml0cyBzaG91bGQgYmUgPD0gMzAgYmVjYXVzZSB3ZSBkbyBiaXR3aXNlIG9wc1xuLy8gb24gdmFsdWVzIHVwIHRvIDIqaGR2YWx1ZV4yLWhkdmFsdWUtMSAoPCAyXjMxKVxuZnVuY3Rpb24gYW0yKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgdmFyIHhsID0geCAmIDB4N2ZmZixcbiAgICB4aCA9IHggPj4gMTVcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIGwgPSB0aGlzW2ldICYgMHg3ZmZmXG4gICAgdmFyIGggPSB0aGlzW2krK10gPj4gMTVcbiAgICB2YXIgbSA9IHhoICogbCArIGggKiB4bFxuICAgIGwgPSB4bCAqIGwgKyAoKG0gJiAweDdmZmYpIDw8IDE1KSArIHdbal0gKyAoYyAmIDB4M2ZmZmZmZmYpXG4gICAgYyA9IChsID4+PiAzMCkgKyAobSA+Pj4gMTUpICsgeGggKiBoICsgKGMgPj4+IDMwKVxuICAgIHdbaisrXSA9IGwgJiAweDNmZmZmZmZmXG4gIH1cbiAgcmV0dXJuIGNcbn1cbi8vIEFsdGVybmF0ZWx5LCBzZXQgbWF4IGRpZ2l0IGJpdHMgdG8gMjggc2luY2Ugc29tZVxuLy8gYnJvd3NlcnMgc2xvdyBkb3duIHdoZW4gZGVhbGluZyB3aXRoIDMyLWJpdCBudW1iZXJzLlxuZnVuY3Rpb24gYW0zKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgdmFyIHhsID0geCAmIDB4M2ZmZixcbiAgICB4aCA9IHggPj4gMTRcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIGwgPSB0aGlzW2ldICYgMHgzZmZmXG4gICAgdmFyIGggPSB0aGlzW2krK10gPj4gMTRcbiAgICB2YXIgbSA9IHhoICogbCArIGggKiB4bFxuICAgIGwgPSB4bCAqIGwgKyAoKG0gJiAweDNmZmYpIDw8IDE0KSArIHdbal0gKyBjXG4gICAgYyA9IChsID4+IDI4KSArIChtID4+IDE0KSArIHhoICogaFxuICAgIHdbaisrXSA9IGwgJiAweGZmZmZmZmZcbiAgfVxuICByZXR1cm4gY1xufVxuXG4vLyB3dGY/XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMVxuZGJpdHMgPSAyNlxuXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5EQiA9IGRiaXRzXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMSA8PCBkYml0cykgLSAxKVxudmFyIERWID0gQmlnSW50ZWdlci5wcm90b3R5cGUuRFYgPSAoMSA8PCBkYml0cylcblxudmFyIEJJX0ZQID0gNTJcbkJpZ0ludGVnZXIucHJvdG90eXBlLkZWID0gTWF0aC5wb3coMiwgQklfRlApXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5GMSA9IEJJX0ZQIC0gZGJpdHNcbkJpZ0ludGVnZXIucHJvdG90eXBlLkYyID0gMiAqIGRiaXRzIC0gQklfRlBcblxuLy8gRGlnaXQgY29udmVyc2lvbnNcbnZhciBCSV9STSA9IFwiMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XCJcbnZhciBCSV9SQyA9IG5ldyBBcnJheSgpXG52YXIgcnIsIHZ2XG5yciA9IFwiMFwiLmNoYXJDb2RlQXQoMClcbmZvciAodnYgPSAwOyB2diA8PSA5OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2XG5yciA9IFwiYVwiLmNoYXJDb2RlQXQoMClcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2dlxucnIgPSBcIkFcIi5jaGFyQ29kZUF0KDApXG5mb3IgKHZ2ID0gMTA7IHZ2IDwgMzY7ICsrdnYpIEJJX1JDW3JyKytdID0gdnZcblxuZnVuY3Rpb24gaW50MmNoYXIobikge1xuICByZXR1cm4gQklfUk0uY2hhckF0KG4pXG59XG5cbmZ1bmN0aW9uIGludEF0KHMsIGkpIHtcbiAgdmFyIGMgPSBCSV9SQ1tzLmNoYXJDb2RlQXQoaSldXG4gIHJldHVybiAoYyA9PSBudWxsKSA/IC0xIDogY1xufVxuXG4vLyAocHJvdGVjdGVkKSBjb3B5IHRoaXMgdG8gclxuZnVuY3Rpb24gYm5wQ29weVRvKHIpIHtcbiAgZm9yICh2YXIgaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByW2ldID0gdGhpc1tpXVxuICByLnQgPSB0aGlzLnRcbiAgci5zID0gdGhpcy5zXG59XG5cbi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIGludGVnZXIgdmFsdWUgeCwgLURWIDw9IHggPCBEVlxuZnVuY3Rpb24gYm5wRnJvbUludCh4KSB7XG4gIHRoaXMudCA9IDFcbiAgdGhpcy5zID0gKHggPCAwKSA/IC0xIDogMFxuICBpZiAoeCA+IDApIHRoaXNbMF0gPSB4XG4gIGVsc2UgaWYgKHggPCAtMSkgdGhpc1swXSA9IHggKyBEVlxuICBlbHNlIHRoaXMudCA9IDBcbn1cblxuLy8gcmV0dXJuIGJpZ2ludCBpbml0aWFsaXplZCB0byB2YWx1ZVxuZnVuY3Rpb24gbmJ2KGkpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHIuZnJvbUludChpKVxuICByZXR1cm4gclxufVxuXG4vLyAocHJvdGVjdGVkKSBzZXQgZnJvbSBzdHJpbmcgYW5kIHJhZGl4XG5mdW5jdGlvbiBibnBGcm9tU3RyaW5nKHMsIGIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgdmFyIGtcbiAgaWYgKGIgPT0gMTYpIGsgPSA0XG4gIGVsc2UgaWYgKGIgPT0gOCkgayA9IDNcbiAgZWxzZSBpZiAoYiA9PSAyNTYpIGsgPSA4OyAvLyBieXRlIGFycmF5XG4gIGVsc2UgaWYgKGIgPT0gMikgayA9IDFcbiAgZWxzZSBpZiAoYiA9PSAzMikgayA9IDVcbiAgZWxzZSBpZiAoYiA9PSA0KSBrID0gMlxuICBlbHNlIHtcbiAgICBzZWxmLmZyb21SYWRpeChzLCBiKVxuICAgIHJldHVyblxuICB9XG4gIHNlbGYudCA9IDBcbiAgc2VsZi5zID0gMFxuICB2YXIgaSA9IHMubGVuZ3RoLFxuICAgIG1pID0gZmFsc2UsXG4gICAgc2ggPSAwXG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIHZhciB4ID0gKGsgPT0gOCkgPyBzW2ldICYgMHhmZiA6IGludEF0KHMsIGkpXG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBpZiAocy5jaGFyQXQoaSkgPT0gXCItXCIpIG1pID0gdHJ1ZVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgbWkgPSBmYWxzZVxuICAgIGlmIChzaCA9PSAwKVxuICAgICAgc2VsZltzZWxmLnQrK10gPSB4XG4gICAgZWxzZSBpZiAoc2ggKyBrID4gc2VsZi5EQikge1xuICAgICAgc2VsZltzZWxmLnQgLSAxXSB8PSAoeCAmICgoMSA8PCAoc2VsZi5EQiAtIHNoKSkgLSAxKSkgPDwgc2hcbiAgICAgIHNlbGZbc2VsZi50KytdID0gKHggPj4gKHNlbGYuREIgLSBzaCkpXG4gICAgfSBlbHNlXG4gICAgICBzZWxmW3NlbGYudCAtIDFdIHw9IHggPDwgc2hcbiAgICBzaCArPSBrXG4gICAgaWYgKHNoID49IHNlbGYuREIpIHNoIC09IHNlbGYuREJcbiAgfVxuICBpZiAoayA9PSA4ICYmIChzWzBdICYgMHg4MCkgIT0gMCkge1xuICAgIHNlbGYucyA9IC0xXG4gICAgaWYgKHNoID4gMCkgc2VsZltzZWxmLnQgLSAxXSB8PSAoKDEgPDwgKHNlbGYuREIgLSBzaCkpIC0gMSkgPDwgc2hcbiAgfVxuICBzZWxmLmNsYW1wKClcbiAgaWYgKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8oc2VsZiwgc2VsZilcbn1cblxuLy8gKHByb3RlY3RlZCkgY2xhbXAgb2ZmIGV4Y2VzcyBoaWdoIHdvcmRzXG5mdW5jdGlvbiBibnBDbGFtcCgpIHtcbiAgdmFyIGMgPSB0aGlzLnMgJiB0aGlzLkRNXG4gIHdoaWxlICh0aGlzLnQgPiAwICYmIHRoaXNbdGhpcy50IC0gMV0gPT0gYyktLXRoaXMudFxufVxuXG4vLyAocHVibGljKSByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIGluIGdpdmVuIHJhZGl4XG5mdW5jdGlvbiBiblRvU3RyaW5nKGIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmIChzZWxmLnMgPCAwKSByZXR1cm4gXCItXCIgKyBzZWxmLm5lZ2F0ZSgpXG4gICAgLnRvU3RyaW5nKGIpXG4gIHZhciBrXG4gIGlmIChiID09IDE2KSBrID0gNFxuICBlbHNlIGlmIChiID09IDgpIGsgPSAzXG4gIGVsc2UgaWYgKGIgPT0gMikgayA9IDFcbiAgZWxzZSBpZiAoYiA9PSAzMikgayA9IDVcbiAgZWxzZSBpZiAoYiA9PSA0KSBrID0gMlxuICBlbHNlIHJldHVybiBzZWxmLnRvUmFkaXgoYilcbiAgdmFyIGttID0gKDEgPDwgaykgLSAxLFxuICAgIGQsIG0gPSBmYWxzZSxcbiAgICByID0gXCJcIixcbiAgICBpID0gc2VsZi50XG4gIHZhciBwID0gc2VsZi5EQiAtIChpICogc2VsZi5EQikgJSBrXG4gIGlmIChpLS0gPiAwKSB7XG4gICAgaWYgKHAgPCBzZWxmLkRCICYmIChkID0gc2VsZltpXSA+PiBwKSA+IDApIHtcbiAgICAgIG0gPSB0cnVlXG4gICAgICByID0gaW50MmNoYXIoZClcbiAgICB9XG4gICAgd2hpbGUgKGkgPj0gMCkge1xuICAgICAgaWYgKHAgPCBrKSB7XG4gICAgICAgIGQgPSAoc2VsZltpXSAmICgoMSA8PCBwKSAtIDEpKSA8PCAoayAtIHApXG4gICAgICAgIGQgfD0gc2VsZlstLWldID4+IChwICs9IHNlbGYuREIgLSBrKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZCA9IChzZWxmW2ldID4+IChwIC09IGspKSAmIGttXG4gICAgICAgIGlmIChwIDw9IDApIHtcbiAgICAgICAgICBwICs9IHNlbGYuREJcbiAgICAgICAgICAtLWlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGQgPiAwKSBtID0gdHJ1ZVxuICAgICAgaWYgKG0pIHIgKz0gaW50MmNoYXIoZClcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG0gPyByIDogXCIwXCJcbn1cblxuLy8gKHB1YmxpYykgLXRoaXNcbmZ1bmN0aW9uIGJuTmVnYXRlKCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHx0aGlzfFxuZnVuY3Rpb24gYm5BYnMoKSB7XG4gIHJldHVybiAodGhpcy5zIDwgMCkgPyB0aGlzLm5lZ2F0ZSgpIDogdGhpc1xufVxuXG4vLyAocHVibGljKSByZXR1cm4gKyBpZiB0aGlzID4gYSwgLSBpZiB0aGlzIDwgYSwgMCBpZiBlcXVhbFxuZnVuY3Rpb24gYm5Db21wYXJlVG8oYSkge1xuICB2YXIgciA9IHRoaXMucyAtIGEuc1xuICBpZiAociAhPSAwKSByZXR1cm4gclxuICB2YXIgaSA9IHRoaXMudFxuICByID0gaSAtIGEudFxuICBpZiAociAhPSAwKSByZXR1cm4gKHRoaXMucyA8IDApID8gLXIgOiByXG4gIHdoaWxlICgtLWkgPj0gMClcbiAgICBpZiAoKHIgPSB0aGlzW2ldIC0gYVtpXSkgIT0gMCkgcmV0dXJuIHJcbiAgcmV0dXJuIDBcbn1cblxuLy8gcmV0dXJucyBiaXQgbGVuZ3RoIG9mIHRoZSBpbnRlZ2VyIHhcbmZ1bmN0aW9uIG5iaXRzKHgpIHtcbiAgdmFyIHIgPSAxLFxuICAgIHRcbiAgaWYgKCh0ID0geCA+Pj4gMTYpICE9IDApIHtcbiAgICB4ID0gdFxuICAgIHIgKz0gMTZcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDgpICE9IDApIHtcbiAgICB4ID0gdFxuICAgIHIgKz0gOFxuICB9XG4gIGlmICgodCA9IHggPj4gNCkgIT0gMCkge1xuICAgIHggPSB0XG4gICAgciArPSA0XG4gIH1cbiAgaWYgKCh0ID0geCA+PiAyKSAhPSAwKSB7XG4gICAgeCA9IHRcbiAgICByICs9IDJcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDEpICE9IDApIHtcbiAgICB4ID0gdFxuICAgIHIgKz0gMVxuICB9XG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHJldHVybiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gXCJ0aGlzXCJcbmZ1bmN0aW9uIGJuQml0TGVuZ3RoKCkge1xuICBpZiAodGhpcy50IDw9IDApIHJldHVybiAwXG4gIHJldHVybiB0aGlzLkRCICogKHRoaXMudCAtIDEpICsgbmJpdHModGhpc1t0aGlzLnQgLSAxXSBeICh0aGlzLnMgJiB0aGlzLkRNKSlcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gXCJ0aGlzXCJcbmZ1bmN0aW9uIGJuQnl0ZUxlbmd0aCgpIHtcbiAgcmV0dXJuIHRoaXMuYml0TGVuZ3RoKCkgPj4gM1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuKkRCXG5mdW5jdGlvbiBibnBETFNoaWZ0VG8obiwgcikge1xuICB2YXIgaVxuICBmb3IgKGkgPSB0aGlzLnQgLSAxOyBpID49IDA7IC0taSkgcltpICsgbl0gPSB0aGlzW2ldXG4gIGZvciAoaSA9IG4gLSAxOyBpID49IDA7IC0taSkgcltpXSA9IDBcbiAgci50ID0gdGhpcy50ICsgblxuICByLnMgPSB0aGlzLnNcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gbipEQlxuZnVuY3Rpb24gYm5wRFJTaGlmdFRvKG4sIHIpIHtcbiAgZm9yICh2YXIgaSA9IG47IGkgPCB0aGlzLnQ7ICsraSkgcltpIC0gbl0gPSB0aGlzW2ldXG4gIHIudCA9IE1hdGgubWF4KHRoaXMudCAtIG4sIDApXG4gIHIucyA9IHRoaXMuc1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuXG5mdW5jdGlvbiBibnBMU2hpZnRUbyhuLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgYnMgPSBuICUgc2VsZi5EQlxuICB2YXIgY2JzID0gc2VsZi5EQiAtIGJzXG4gIHZhciBibSA9ICgxIDw8IGNicykgLSAxXG4gIHZhciBkcyA9IE1hdGguZmxvb3IobiAvIHNlbGYuREIpLFxuICAgIGMgPSAoc2VsZi5zIDw8IGJzKSAmIHNlbGYuRE0sXG4gICAgaVxuICBmb3IgKGkgPSBzZWxmLnQgLSAxOyBpID49IDA7IC0taSkge1xuICAgIHJbaSArIGRzICsgMV0gPSAoc2VsZltpXSA+PiBjYnMpIHwgY1xuICAgIGMgPSAoc2VsZltpXSAmIGJtKSA8PCBic1xuICB9XG4gIGZvciAoaSA9IGRzIC0gMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSAwXG4gIHJbZHNdID0gY1xuICByLnQgPSBzZWxmLnQgKyBkcyArIDFcbiAgci5zID0gc2VsZi5zXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuXG5mdW5jdGlvbiBibnBSU2hpZnRUbyhuLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICByLnMgPSBzZWxmLnNcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gc2VsZi5EQilcbiAgaWYgKGRzID49IHNlbGYudCkge1xuICAgIHIudCA9IDBcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgYnMgPSBuICUgc2VsZi5EQlxuICB2YXIgY2JzID0gc2VsZi5EQiAtIGJzXG4gIHZhciBibSA9ICgxIDw8IGJzKSAtIDFcbiAgclswXSA9IHNlbGZbZHNdID4+IGJzXG4gIGZvciAodmFyIGkgPSBkcyArIDE7IGkgPCBzZWxmLnQ7ICsraSkge1xuICAgIHJbaSAtIGRzIC0gMV0gfD0gKHNlbGZbaV0gJiBibSkgPDwgY2JzXG4gICAgcltpIC0gZHNdID0gc2VsZltpXSA+PiBic1xuICB9XG4gIGlmIChicyA+IDApIHJbc2VsZi50IC0gZHMgLSAxXSB8PSAoc2VsZi5zICYgYm0pIDw8IGNic1xuICByLnQgPSBzZWxmLnQgLSBkc1xuICByLmNsYW1wKClcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhXG5mdW5jdGlvbiBibnBTdWJUbyhhLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgaSA9IDAsXG4gICAgYyA9IDAsXG4gICAgbSA9IE1hdGgubWluKGEudCwgc2VsZi50KVxuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBjICs9IHNlbGZbaV0gLSBhW2ldXG4gICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICBjID4+PSBzZWxmLkRCXG4gIH1cbiAgaWYgKGEudCA8IHNlbGYudCkge1xuICAgIGMgLT0gYS5zXG4gICAgd2hpbGUgKGkgPCBzZWxmLnQpIHtcbiAgICAgIGMgKz0gc2VsZltpXVxuICAgICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICAgIGMgPj49IHNlbGYuREJcbiAgICB9XG4gICAgYyArPSBzZWxmLnNcbiAgfSBlbHNlIHtcbiAgICBjICs9IHNlbGYuc1xuICAgIHdoaWxlIChpIDwgYS50KSB7XG4gICAgICBjIC09IGFbaV1cbiAgICAgIHJbaSsrXSA9IGMgJiBzZWxmLkRNXG4gICAgICBjID4+PSBzZWxmLkRCXG4gICAgfVxuICAgIGMgLT0gYS5zXG4gIH1cbiAgci5zID0gKGMgPCAwKSA/IC0xIDogMFxuICBpZiAoYyA8IC0xKSByW2krK10gPSBzZWxmLkRWICsgY1xuICBlbHNlIGlmIChjID4gMCkgcltpKytdID0gY1xuICByLnQgPSBpXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyAqIGEsIHIgIT0gdGhpcyxhIChIQUMgMTQuMTIpXG4vLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG5mdW5jdGlvbiBibnBNdWx0aXBseVRvKGEsIHIpIHtcbiAgdmFyIHggPSB0aGlzLmFicygpLFxuICAgIHkgPSBhLmFicygpXG4gIHZhciBpID0geC50XG4gIHIudCA9IGkgKyB5LnRcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgeS50OyArK2kpIHJbaSArIHgudF0gPSB4LmFtKDAsIHlbaV0sIHIsIGksIDAsIHgudClcbiAgci5zID0gMFxuICByLmNsYW1wKClcbiAgaWYgKHRoaXMucyAhPSBhLnMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLCByKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpc14yLCByICE9IHRoaXMgKEhBQyAxNC4xNilcbmZ1bmN0aW9uIGJucFNxdWFyZVRvKHIpIHtcbiAgdmFyIHggPSB0aGlzLmFicygpXG4gIHZhciBpID0gci50ID0gMiAqIHgudFxuICB3aGlsZSAoLS1pID49IDApIHJbaV0gPSAwXG4gIGZvciAoaSA9IDA7IGkgPCB4LnQgLSAxOyArK2kpIHtcbiAgICB2YXIgYyA9IHguYW0oaSwgeFtpXSwgciwgMiAqIGksIDAsIDEpXG4gICAgaWYgKChyW2kgKyB4LnRdICs9IHguYW0oaSArIDEsIDIgKiB4W2ldLCByLCAyICogaSArIDEsIGMsIHgudCAtIGkgLSAxKSkgPj0geC5EVikge1xuICAgICAgcltpICsgeC50XSAtPSB4LkRWXG4gICAgICByW2kgKyB4LnQgKyAxXSA9IDFcbiAgICB9XG4gIH1cbiAgaWYgKHIudCA+IDApIHJbci50IC0gMV0gKz0geC5hbShpLCB4W2ldLCByLCAyICogaSwgMCwgMSlcbiAgci5zID0gMFxuICByLmNsYW1wKClcbn1cblxuLy8gKHByb3RlY3RlZCkgZGl2aWRlIHRoaXMgYnkgbSwgcXVvdGllbnQgYW5kIHJlbWFpbmRlciB0byBxLCByIChIQUMgMTQuMjApXG4vLyByICE9IHEsIHRoaXMgIT0gbS4gIHEgb3IgciBtYXkgYmUgbnVsbC5cbmZ1bmN0aW9uIGJucERpdlJlbVRvKG0sIHEsIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBwbSA9IG0uYWJzKClcbiAgaWYgKHBtLnQgPD0gMCkgcmV0dXJuXG4gIHZhciBwdCA9IHNlbGYuYWJzKClcbiAgaWYgKHB0LnQgPCBwbS50KSB7XG4gICAgaWYgKHEgIT0gbnVsbCkgcS5mcm9tSW50KDApXG4gICAgaWYgKHIgIT0gbnVsbCkgc2VsZi5jb3B5VG8ocilcbiAgICByZXR1cm5cbiAgfVxuICBpZiAociA9PSBudWxsKSByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB2YXIgeSA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgdHMgPSBzZWxmLnMsXG4gICAgbXMgPSBtLnNcbiAgdmFyIG5zaCA9IHNlbGYuREIgLSBuYml0cyhwbVtwbS50IC0gMV0pOyAvLyBub3JtYWxpemUgbW9kdWx1c1xuICBpZiAobnNoID4gMCkge1xuICAgIHBtLmxTaGlmdFRvKG5zaCwgeSlcbiAgICBwdC5sU2hpZnRUbyhuc2gsIHIpXG4gIH0gZWxzZSB7XG4gICAgcG0uY29weVRvKHkpXG4gICAgcHQuY29weVRvKHIpXG4gIH1cbiAgdmFyIHlzID0geS50XG4gIHZhciB5MCA9IHlbeXMgLSAxXVxuICBpZiAoeTAgPT0gMCkgcmV0dXJuXG4gIHZhciB5dCA9IHkwICogKDEgPDwgc2VsZi5GMSkgKyAoKHlzID4gMSkgPyB5W3lzIC0gMl0gPj4gc2VsZi5GMiA6IDApXG4gIHZhciBkMSA9IHNlbGYuRlYgLyB5dCxcbiAgICBkMiA9ICgxIDw8IHNlbGYuRjEpIC8geXQsXG4gICAgZSA9IDEgPDwgc2VsZi5GMlxuICB2YXIgaSA9IHIudCxcbiAgICBqID0gaSAtIHlzLFxuICAgIHQgPSAocSA9PSBudWxsKSA/IG5ldyBCaWdJbnRlZ2VyKCkgOiBxXG4gIHkuZGxTaGlmdFRvKGosIHQpXG4gIGlmIChyLmNvbXBhcmVUbyh0KSA+PSAwKSB7XG4gICAgcltyLnQrK10gPSAxXG4gICAgci5zdWJUbyh0LCByKVxuICB9XG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbyh5cywgdClcbiAgdC5zdWJUbyh5LCB5KTsgLy8gXCJuZWdhdGl2ZVwiIHkgc28gd2UgY2FuIHJlcGxhY2Ugc3ViIHdpdGggYW0gbGF0ZXJcbiAgd2hpbGUgKHkudCA8IHlzKSB5W3kudCsrXSA9IDBcbiAgd2hpbGUgKC0taiA+PSAwKSB7XG4gICAgLy8gRXN0aW1hdGUgcXVvdGllbnQgZGlnaXRcbiAgICB2YXIgcWQgPSAoclstLWldID09IHkwKSA/IHNlbGYuRE0gOiBNYXRoLmZsb29yKHJbaV0gKiBkMSArIChyW2kgLSAxXSArIGUpICogZDIpXG4gICAgaWYgKChyW2ldICs9IHkuYW0oMCwgcWQsIHIsIGosIDAsIHlzKSkgPCBxZCkgeyAvLyBUcnkgaXQgb3V0XG4gICAgICB5LmRsU2hpZnRUbyhqLCB0KVxuICAgICAgci5zdWJUbyh0LCByKVxuICAgICAgd2hpbGUgKHJbaV0gPCAtLXFkKSByLnN1YlRvKHQsIHIpXG4gICAgfVxuICB9XG4gIGlmIChxICE9IG51bGwpIHtcbiAgICByLmRyU2hpZnRUbyh5cywgcSlcbiAgICBpZiAodHMgIT0gbXMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhxLCBxKVxuICB9XG4gIHIudCA9IHlzXG4gIHIuY2xhbXAoKVxuICBpZiAobnNoID4gMCkgci5yU2hpZnRUbyhuc2gsIHIpOyAvLyBEZW5vcm1hbGl6ZSByZW1haW5kZXJcbiAgaWYgKHRzIDwgMCkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIsIHIpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgbW9kIGFcbmZ1bmN0aW9uIGJuTW9kKGEpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMuYWJzKClcbiAgICAuZGl2UmVtVG8oYSwgbnVsbCwgcilcbiAgaWYgKHRoaXMucyA8IDAgJiYgci5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSA+IDApIGEuc3ViVG8ociwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gTW9kdWxhciByZWR1Y3Rpb24gdXNpbmcgXCJjbGFzc2ljXCIgYWxnb3JpdGhtXG5mdW5jdGlvbiBDbGFzc2ljKG0pIHtcbiAgdGhpcy5tID0gbVxufVxuXG5mdW5jdGlvbiBjQ29udmVydCh4KSB7XG4gIGlmICh4LnMgPCAwIHx8IHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgcmV0dXJuIHgubW9kKHRoaXMubSlcbiAgZWxzZSByZXR1cm4geFxufVxuXG5mdW5jdGlvbiBjUmV2ZXJ0KHgpIHtcbiAgcmV0dXJuIHhcbn1cblxuZnVuY3Rpb24gY1JlZHVjZSh4KSB7XG4gIHguZGl2UmVtVG8odGhpcy5tLCBudWxsLCB4KVxufVxuXG5mdW5jdGlvbiBjTXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcilcbiAgdGhpcy5yZWR1Y2Uocilcbn1cblxuZnVuY3Rpb24gY1NxclRvKHgsIHIpIHtcbiAgeC5zcXVhcmVUbyhyKVxuICB0aGlzLnJlZHVjZShyKVxufVxuXG5DbGFzc2ljLnByb3RvdHlwZS5jb252ZXJ0ID0gY0NvbnZlcnRcbkNsYXNzaWMucHJvdG90eXBlLnJldmVydCA9IGNSZXZlcnRcbkNsYXNzaWMucHJvdG90eXBlLnJlZHVjZSA9IGNSZWR1Y2VcbkNsYXNzaWMucHJvdG90eXBlLm11bFRvID0gY011bFRvXG5DbGFzc2ljLnByb3RvdHlwZS5zcXJUbyA9IGNTcXJUb1xuXG4vLyAocHJvdGVjdGVkKSByZXR1cm4gXCItMS90aGlzICUgMl5EQlwiOyB1c2VmdWwgZm9yIE1vbnQuIHJlZHVjdGlvblxuLy8ganVzdGlmaWNhdGlvbjpcbi8vICAgICAgICAgeHkgPT0gMSAobW9kIG0pXG4vLyAgICAgICAgIHh5ID0gIDEra21cbi8vICAgeHkoMi14eSkgPSAoMStrbSkoMS1rbSlcbi8vIHhbeSgyLXh5KV0gPSAxLWteMm1eMlxuLy8geFt5KDIteHkpXSA9PSAxIChtb2QgbV4yKVxuLy8gaWYgeSBpcyAxL3ggbW9kIG0sIHRoZW4geSgyLXh5KSBpcyAxL3ggbW9kIG1eMlxuLy8gc2hvdWxkIHJlZHVjZSB4IGFuZCB5KDIteHkpIGJ5IG1eMiBhdCBlYWNoIHN0ZXAgdG8ga2VlcCBzaXplIGJvdW5kZWQuXG4vLyBKUyBtdWx0aXBseSBcIm92ZXJmbG93c1wiIGRpZmZlcmVudGx5IGZyb20gQy9DKyssIHNvIGNhcmUgaXMgbmVlZGVkIGhlcmUuXG5mdW5jdGlvbiBibnBJbnZEaWdpdCgpIHtcbiAgaWYgKHRoaXMudCA8IDEpIHJldHVybiAwXG4gIHZhciB4ID0gdGhpc1swXVxuICBpZiAoKHggJiAxKSA9PSAwKSByZXR1cm4gMFxuICB2YXIgeSA9IHggJiAzOyAvLyB5ID09IDEveCBtb2QgMl4yXG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGYpICogeSkpICYgMHhmOyAvLyB5ID09IDEveCBtb2QgMl40XG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGZmKSAqIHkpKSAmIDB4ZmY7IC8vIHkgPT0gMS94IG1vZCAyXjhcbiAgeSA9ICh5ICogKDIgLSAoKCh4ICYgMHhmZmZmKSAqIHkpICYgMHhmZmZmKSkpICYgMHhmZmZmOyAvLyB5ID09IDEveCBtb2QgMl4xNlxuICAvLyBsYXN0IHN0ZXAgLSBjYWxjdWxhdGUgaW52ZXJzZSBtb2QgRFYgZGlyZWN0bHlcbiAgLy8gYXNzdW1lcyAxNiA8IERCIDw9IDMyIGFuZCBhc3N1bWVzIGFiaWxpdHkgdG8gaGFuZGxlIDQ4LWJpdCBpbnRzXG4gIHkgPSAoeSAqICgyIC0geCAqIHkgJSB0aGlzLkRWKSkgJSB0aGlzLkRWOyAvLyB5ID09IDEveCBtb2QgMl5kYml0c1xuICAvLyB3ZSByZWFsbHkgd2FudCB0aGUgbmVnYXRpdmUgaW52ZXJzZSwgYW5kIC1EViA8IHkgPCBEVlxuICByZXR1cm4gKHkgPiAwKSA/IHRoaXMuRFYgLSB5IDogLXlcbn1cblxuLy8gTW9udGdvbWVyeSByZWR1Y3Rpb25cbmZ1bmN0aW9uIE1vbnRnb21lcnkobSkge1xuICB0aGlzLm0gPSBtXG4gIHRoaXMubXAgPSBtLmludkRpZ2l0KClcbiAgdGhpcy5tcGwgPSB0aGlzLm1wICYgMHg3ZmZmXG4gIHRoaXMubXBoID0gdGhpcy5tcCA+PiAxNVxuICB0aGlzLnVtID0gKDEgPDwgKG0uREIgLSAxNSkpIC0gMVxuICB0aGlzLm10MiA9IDIgKiBtLnRcbn1cblxuLy8geFIgbW9kIG1cbmZ1bmN0aW9uIG1vbnRDb252ZXJ0KHgpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHguYWJzKClcbiAgICAuZGxTaGlmdFRvKHRoaXMubS50LCByKVxuICByLmRpdlJlbVRvKHRoaXMubSwgbnVsbCwgcilcbiAgaWYgKHgucyA8IDAgJiYgci5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSA+IDApIHRoaXMubS5zdWJUbyhyLCByKVxuICByZXR1cm4gclxufVxuXG4vLyB4L1IgbW9kIG1cbmZ1bmN0aW9uIG1vbnRSZXZlcnQoeCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgeC5jb3B5VG8ocilcbiAgdGhpcy5yZWR1Y2UocilcbiAgcmV0dXJuIHJcbn1cblxuLy8geCA9IHgvUiBtb2QgbSAoSEFDIDE0LjMyKVxuZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7XG4gIHdoaWxlICh4LnQgPD0gdGhpcy5tdDIpIC8vIHBhZCB4IHNvIGFtIGhhcyBlbm91Z2ggcm9vbSBsYXRlclxuICAgIHhbeC50KytdID0gMFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubS50OyArK2kpIHtcbiAgICAvLyBmYXN0ZXIgd2F5IG9mIGNhbGN1bGF0aW5nIHUwID0geFtpXSptcCBtb2QgRFZcbiAgICB2YXIgaiA9IHhbaV0gJiAweDdmZmZcbiAgICB2YXIgdTAgPSAoaiAqIHRoaXMubXBsICsgKCgoaiAqIHRoaXMubXBoICsgKHhbaV0gPj4gMTUpICogdGhpcy5tcGwpICYgdGhpcy51bSkgPDwgMTUpKSAmIHguRE1cbiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGxcbiAgICBqID0gaSArIHRoaXMubS50XG4gICAgeFtqXSArPSB0aGlzLm0uYW0oMCwgdTAsIHgsIGksIDAsIHRoaXMubS50KVxuICAgIC8vIHByb3BhZ2F0ZSBjYXJyeVxuICAgIHdoaWxlICh4W2pdID49IHguRFYpIHtcbiAgICAgIHhbal0gLT0geC5EVlxuICAgICAgeFsrK2pdKytcbiAgICB9XG4gIH1cbiAgeC5jbGFtcCgpXG4gIHguZHJTaGlmdFRvKHRoaXMubS50LCB4KVxuICBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSwgeClcbn1cblxuLy8gciA9IFwieF4yL1IgbW9kIG1cIjsgeCAhPSByXG5mdW5jdGlvbiBtb250U3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpXG4gIHRoaXMucmVkdWNlKHIpXG59XG5cbi8vIHIgPSBcInh5L1IgbW9kIG1cIjsgeCx5ICE9IHJcbmZ1bmN0aW9uIG1vbnRNdWxUbyh4LCB5LCByKSB7XG4gIHgubXVsdGlwbHlUbyh5LCByKVxuICB0aGlzLnJlZHVjZShyKVxufVxuXG5Nb250Z29tZXJ5LnByb3RvdHlwZS5jb252ZXJ0ID0gbW9udENvbnZlcnRcbk1vbnRnb21lcnkucHJvdG90eXBlLnJldmVydCA9IG1vbnRSZXZlcnRcbk1vbnRnb21lcnkucHJvdG90eXBlLnJlZHVjZSA9IG1vbnRSZWR1Y2Vcbk1vbnRnb21lcnkucHJvdG90eXBlLm11bFRvID0gbW9udE11bFRvXG5Nb250Z29tZXJ5LnByb3RvdHlwZS5zcXJUbyA9IG1vbnRTcXJUb1xuXG4vLyAocHJvdGVjdGVkKSB0cnVlIGlmZiB0aGlzIGlzIGV2ZW5cbmZ1bmN0aW9uIGJucElzRXZlbigpIHtcbiAgcmV0dXJuICgodGhpcy50ID4gMCkgPyAodGhpc1swXSAmIDEpIDogdGhpcy5zKSA9PSAwXG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXNeZSwgZSA8IDJeMzIsIGRvaW5nIHNxciBhbmQgbXVsIHdpdGggXCJyXCIgKEhBQyAxNC43OSlcbmZ1bmN0aW9uIGJucEV4cChlLCB6KSB7XG4gIGlmIChlID4gMHhmZmZmZmZmZiB8fCBlIDwgMSkgcmV0dXJuIEJpZ0ludGVnZXIuT05FXG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICByMiA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgZyA9IHouY29udmVydCh0aGlzKSxcbiAgICBpID0gbmJpdHMoZSkgLSAxXG4gIGcuY29weVRvKHIpXG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIHouc3FyVG8ociwgcjIpXG4gICAgaWYgKChlICYgKDEgPDwgaSkpID4gMCkgei5tdWxUbyhyMiwgZywgcilcbiAgICBlbHNlIHtcbiAgICAgIHZhciB0ID0gclxuICAgICAgciA9IHIyXG4gICAgICByMiA9IHRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHoucmV2ZXJ0KHIpXG59XG5cbi8vIChwdWJsaWMpIHRoaXNeZSAlIG0sIDAgPD0gZSA8IDJeMzJcbmZ1bmN0aW9uIGJuTW9kUG93SW50KGUsIG0pIHtcbiAgdmFyIHpcbiAgaWYgKGUgPCAyNTYgfHwgbS5pc0V2ZW4oKSkgeiA9IG5ldyBDbGFzc2ljKG0pXG4gIGVsc2UgeiA9IG5ldyBNb250Z29tZXJ5KG0pXG4gIHJldHVybiB0aGlzLmV4cChlLCB6KVxufVxuXG4vLyBwcm90ZWN0ZWRcbnByb3RvLmNvcHlUbyA9IGJucENvcHlUb1xucHJvdG8uZnJvbUludCA9IGJucEZyb21JbnRcbnByb3RvLmZyb21TdHJpbmcgPSBibnBGcm9tU3RyaW5nXG5wcm90by5jbGFtcCA9IGJucENsYW1wXG5wcm90by5kbFNoaWZ0VG8gPSBibnBETFNoaWZ0VG9cbnByb3RvLmRyU2hpZnRUbyA9IGJucERSU2hpZnRUb1xucHJvdG8ubFNoaWZ0VG8gPSBibnBMU2hpZnRUb1xucHJvdG8uclNoaWZ0VG8gPSBibnBSU2hpZnRUb1xucHJvdG8uc3ViVG8gPSBibnBTdWJUb1xucHJvdG8ubXVsdGlwbHlUbyA9IGJucE11bHRpcGx5VG9cbnByb3RvLnNxdWFyZVRvID0gYm5wU3F1YXJlVG9cbnByb3RvLmRpdlJlbVRvID0gYm5wRGl2UmVtVG9cbnByb3RvLmludkRpZ2l0ID0gYm5wSW52RGlnaXRcbnByb3RvLmlzRXZlbiA9IGJucElzRXZlblxucHJvdG8uZXhwID0gYm5wRXhwXG5cbi8vIHB1YmxpY1xucHJvdG8udG9TdHJpbmcgPSBiblRvU3RyaW5nXG5wcm90by5uZWdhdGUgPSBibk5lZ2F0ZVxucHJvdG8uYWJzID0gYm5BYnNcbnByb3RvLmNvbXBhcmVUbyA9IGJuQ29tcGFyZVRvXG5wcm90by5iaXRMZW5ndGggPSBibkJpdExlbmd0aFxucHJvdG8uYnl0ZUxlbmd0aCA9IGJuQnl0ZUxlbmd0aFxucHJvdG8ubW9kID0gYm5Nb2RcbnByb3RvLm1vZFBvd0ludCA9IGJuTW9kUG93SW50XG5cbi8vIChwdWJsaWMpXG5mdW5jdGlvbiBibkNsb25lKCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5jb3B5VG8ocilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGludGVnZXJcbmZ1bmN0aW9uIGJuSW50VmFsdWUoKSB7XG4gIGlmICh0aGlzLnMgPCAwKSB7XG4gICAgaWYgKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpc1swXSAtIHRoaXMuRFZcbiAgICBlbHNlIGlmICh0aGlzLnQgPT0gMCkgcmV0dXJuIC0xXG4gIH0gZWxzZSBpZiAodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdXG4gIGVsc2UgaWYgKHRoaXMudCA9PSAwKSByZXR1cm4gMFxuICAvLyBhc3N1bWVzIDE2IDwgREIgPCAzMlxuICByZXR1cm4gKCh0aGlzWzFdICYgKCgxIDw8ICgzMiAtIHRoaXMuREIpKSAtIDEpKSA8PCB0aGlzLkRCKSB8IHRoaXNbMF1cbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGVcbmZ1bmN0aW9uIGJuQnl0ZVZhbHVlKCkge1xuICByZXR1cm4gKHRoaXMudCA9PSAwKSA/IHRoaXMucyA6ICh0aGlzWzBdIDw8IDI0KSA+PiAyNFxufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KVxuZnVuY3Rpb24gYm5TaG9ydFZhbHVlKCkge1xuICByZXR1cm4gKHRoaXMudCA9PSAwKSA/IHRoaXMucyA6ICh0aGlzWzBdIDw8IDE2KSA+PiAxNlxufVxuXG4vLyAocHJvdGVjdGVkKSByZXR1cm4geCBzLnQuIHJeeCA8IERWXG5mdW5jdGlvbiBibnBDaHVua1NpemUocikge1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLkxOMiAqIHRoaXMuREIgLyBNYXRoLmxvZyhyKSlcbn1cblxuLy8gKHB1YmxpYykgMCBpZiB0aGlzID09IDAsIDEgaWYgdGhpcyA+IDBcbmZ1bmN0aW9uIGJuU2lnTnVtKCkge1xuICBpZiAodGhpcy5zIDwgMCkgcmV0dXJuIC0xXG4gIGVsc2UgaWYgKHRoaXMudCA8PSAwIHx8ICh0aGlzLnQgPT0gMSAmJiB0aGlzWzBdIDw9IDApKSByZXR1cm4gMFxuICBlbHNlIHJldHVybiAxXG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgdG8gcmFkaXggc3RyaW5nXG5mdW5jdGlvbiBibnBUb1JhZGl4KGIpIHtcbiAgaWYgKGIgPT0gbnVsbCkgYiA9IDEwXG4gIGlmICh0aGlzLnNpZ251bSgpID09IDAgfHwgYiA8IDIgfHwgYiA+IDM2KSByZXR1cm4gXCIwXCJcbiAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYilcbiAgdmFyIGEgPSBNYXRoLnBvdyhiLCBjcylcbiAgdmFyIGQgPSBuYnYoYSksXG4gICAgeSA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgeiA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgciA9IFwiXCJcbiAgdGhpcy5kaXZSZW1UbyhkLCB5LCB6KVxuICB3aGlsZSAoeS5zaWdudW0oKSA+IDApIHtcbiAgICByID0gKGEgKyB6LmludFZhbHVlKCkpXG4gICAgICAudG9TdHJpbmcoYilcbiAgICAgIC5zdWJzdHIoMSkgKyByXG4gICAgeS5kaXZSZW1UbyhkLCB5LCB6KVxuICB9XG4gIHJldHVybiB6LmludFZhbHVlKClcbiAgICAudG9TdHJpbmcoYikgKyByXG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgZnJvbSByYWRpeCBzdHJpbmdcbmZ1bmN0aW9uIGJucEZyb21SYWRpeChzLCBiKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBzZWxmLmZyb21JbnQoMClcbiAgaWYgKGIgPT0gbnVsbCkgYiA9IDEwXG4gIHZhciBjcyA9IHNlbGYuY2h1bmtTaXplKGIpXG4gIHZhciBkID0gTWF0aC5wb3coYiwgY3MpLFxuICAgIG1pID0gZmFsc2UsXG4gICAgaiA9IDAsXG4gICAgdyA9IDBcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzLmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHggPSBpbnRBdChzLCBpKVxuICAgIGlmICh4IDwgMCkge1xuICAgICAgaWYgKHMuY2hhckF0KGkpID09IFwiLVwiICYmIHNlbGYuc2lnbnVtKCkgPT0gMCkgbWkgPSB0cnVlXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICB3ID0gYiAqIHcgKyB4XG4gICAgaWYgKCsraiA+PSBjcykge1xuICAgICAgc2VsZi5kTXVsdGlwbHkoZClcbiAgICAgIHNlbGYuZEFkZE9mZnNldCh3LCAwKVxuICAgICAgaiA9IDBcbiAgICAgIHcgPSAwXG4gICAgfVxuICB9XG4gIGlmIChqID4gMCkge1xuICAgIHNlbGYuZE11bHRpcGx5KE1hdGgucG93KGIsIGopKVxuICAgIHNlbGYuZEFkZE9mZnNldCh3LCAwKVxuICB9XG4gIGlmIChtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHNlbGYsIHNlbGYpXG59XG5cbi8vIChwcm90ZWN0ZWQpIGFsdGVybmF0ZSBjb25zdHJ1Y3RvclxuZnVuY3Rpb24gYm5wRnJvbU51bWJlcihhLCBiLCBjKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBpZiAoXCJudW1iZXJcIiA9PSB0eXBlb2YgYikge1xuICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxpbnQsUk5HKVxuICAgIGlmIChhIDwgMikgc2VsZi5mcm9tSW50KDEpXG4gICAgZWxzZSB7XG4gICAgICBzZWxmLmZyb21OdW1iZXIoYSwgYylcbiAgICAgIGlmICghc2VsZi50ZXN0Qml0KGEgLSAxKSkgLy8gZm9yY2UgTVNCIHNldFxuICAgICAgICBzZWxmLmJpdHdpc2VUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYSAtIDEpLCBvcF9vciwgc2VsZilcbiAgICAgIGlmIChzZWxmLmlzRXZlbigpKSBzZWxmLmRBZGRPZmZzZXQoMSwgMCk7IC8vIGZvcmNlIG9kZFxuICAgICAgd2hpbGUgKCFzZWxmLmlzUHJvYmFibGVQcmltZShiKSkge1xuICAgICAgICBzZWxmLmRBZGRPZmZzZXQoMiwgMClcbiAgICAgICAgaWYgKHNlbGYuYml0TGVuZ3RoKCkgPiBhKSBzZWxmLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhIC0gMSksIHNlbGYpXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxSTkcpXG4gICAgdmFyIHggPSBuZXcgQXJyYXkoKSxcbiAgICAgIHQgPSBhICYgN1xuICAgIHgubGVuZ3RoID0gKGEgPj4gMykgKyAxXG4gICAgYi5uZXh0Qnl0ZXMoeClcbiAgICBpZiAodCA+IDApIHhbMF0gJj0gKCgxIDw8IHQpIC0gMSlcbiAgICBlbHNlIHhbMF0gPSAwXG4gICAgc2VsZi5mcm9tU3RyaW5nKHgsIDI1NilcbiAgfVxufVxuXG4vLyAocHVibGljKSBjb252ZXJ0IHRvIGJpZ2VuZGlhbiBieXRlIGFycmF5XG5mdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIGkgPSBzZWxmLnQsXG4gICAgciA9IG5ldyBBcnJheSgpXG4gIHJbMF0gPSBzZWxmLnNcbiAgdmFyIHAgPSBzZWxmLkRCIC0gKGkgKiBzZWxmLkRCKSAlIDgsXG4gICAgZCwgayA9IDBcbiAgaWYgKGktLSA+IDApIHtcbiAgICBpZiAocCA8IHNlbGYuREIgJiYgKGQgPSBzZWxmW2ldID4+IHApICE9IChzZWxmLnMgJiBzZWxmLkRNKSA+PiBwKVxuICAgICAgcltrKytdID0gZCB8IChzZWxmLnMgPDwgKHNlbGYuREIgLSBwKSlcbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAocCA8IDgpIHtcbiAgICAgICAgZCA9IChzZWxmW2ldICYgKCgxIDw8IHApIC0gMSkpIDw8ICg4IC0gcClcbiAgICAgICAgZCB8PSBzZWxmWy0taV0gPj4gKHAgKz0gc2VsZi5EQiAtIDgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkID0gKHNlbGZbaV0gPj4gKHAgLT0gOCkpICYgMHhmZlxuICAgICAgICBpZiAocCA8PSAwKSB7XG4gICAgICAgICAgcCArPSBzZWxmLkRCXG4gICAgICAgICAgLS1pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICgoZCAmIDB4ODApICE9IDApIGQgfD0gLTI1NlxuICAgICAgaWYgKGsgPT09IDAgJiYgKHNlbGYucyAmIDB4ODApICE9IChkICYgMHg4MCkpKytrXG4gICAgICBpZiAoayA+IDAgfHwgZCAhPSBzZWxmLnMpIHJbaysrXSA9IGRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJcbn1cblxuZnVuY3Rpb24gYm5FcXVhbHMoYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpID09IDApXG59XG5cbmZ1bmN0aW9uIGJuTWluKGEpIHtcbiAgcmV0dXJuICh0aGlzLmNvbXBhcmVUbyhhKSA8IDApID8gdGhpcyA6IGFcbn1cblxuZnVuY3Rpb24gYm5NYXgoYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpID4gMCkgPyB0aGlzIDogYVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyBvcCBhIChiaXR3aXNlKVxuZnVuY3Rpb24gYm5wQml0d2lzZVRvKGEsIG9wLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgaSwgZiwgbSA9IE1hdGgubWluKGEudCwgc2VsZi50KVxuICBmb3IgKGkgPSAwOyBpIDwgbTsgKytpKSByW2ldID0gb3Aoc2VsZltpXSwgYVtpXSlcbiAgaWYgKGEudCA8IHNlbGYudCkge1xuICAgIGYgPSBhLnMgJiBzZWxmLkRNXG4gICAgZm9yIChpID0gbTsgaSA8IHNlbGYudDsgKytpKSByW2ldID0gb3Aoc2VsZltpXSwgZilcbiAgICByLnQgPSBzZWxmLnRcbiAgfSBlbHNlIHtcbiAgICBmID0gc2VsZi5zICYgc2VsZi5ETVxuICAgIGZvciAoaSA9IG07IGkgPCBhLnQ7ICsraSkgcltpXSA9IG9wKGYsIGFbaV0pXG4gICAgci50ID0gYS50XG4gIH1cbiAgci5zID0gb3Aoc2VsZi5zLCBhLnMpXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHVibGljKSB0aGlzICYgYVxuZnVuY3Rpb24gb3BfYW5kKHgsIHkpIHtcbiAgcmV0dXJuIHggJiB5XG59XG5cbmZ1bmN0aW9uIGJuQW5kKGEpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMuYml0d2lzZVRvKGEsIG9wX2FuZCwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyB8IGFcbmZ1bmN0aW9uIG9wX29yKHgsIHkpIHtcbiAgcmV0dXJuIHggfCB5XG59XG5cbmZ1bmN0aW9uIGJuT3IoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3Bfb3IsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgXiBhXG5mdW5jdGlvbiBvcF94b3IoeCwgeSkge1xuICByZXR1cm4geCBeIHlcbn1cblxuZnVuY3Rpb24gYm5Yb3IoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfeG9yLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzICYgfmFcbmZ1bmN0aW9uIG9wX2FuZG5vdCh4LCB5KSB7XG4gIHJldHVybiB4ICYgfnlcbn1cblxuZnVuY3Rpb24gYm5BbmROb3QoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfYW5kbm90LCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB+dGhpc1xuZnVuY3Rpb24gYm5Ob3QoKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gdGhpcy5ETSAmIH50aGlzW2ldXG4gIHIudCA9IHRoaXMudFxuICByLnMgPSB+dGhpcy5zXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgPDwgblxuZnVuY3Rpb24gYm5TaGlmdExlZnQobikge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgaWYgKG4gPCAwKSB0aGlzLnJTaGlmdFRvKC1uLCByKVxuICBlbHNlIHRoaXMubFNoaWZ0VG8obiwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyA+PiBuXG5mdW5jdGlvbiBiblNoaWZ0UmlnaHQobikge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgaWYgKG4gPCAwKSB0aGlzLmxTaGlmdFRvKC1uLCByKVxuICBlbHNlIHRoaXMuclNoaWZ0VG8obiwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gcmV0dXJuIGluZGV4IG9mIGxvd2VzdCAxLWJpdCBpbiB4LCB4IDwgMl4zMVxuZnVuY3Rpb24gbGJpdCh4KSB7XG4gIGlmICh4ID09IDApIHJldHVybiAtMVxuICB2YXIgciA9IDBcbiAgaWYgKCh4ICYgMHhmZmZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gMTZcbiAgICByICs9IDE2XG4gIH1cbiAgaWYgKCh4ICYgMHhmZikgPT0gMCkge1xuICAgIHggPj49IDhcbiAgICByICs9IDhcbiAgfVxuICBpZiAoKHggJiAweGYpID09IDApIHtcbiAgICB4ID4+PSA0XG4gICAgciArPSA0XG4gIH1cbiAgaWYgKCh4ICYgMykgPT0gMCkge1xuICAgIHggPj49IDJcbiAgICByICs9IDJcbiAgfVxuICBpZiAoKHggJiAxKSA9PSAwKSsrclxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSByZXR1cm5zIGluZGV4IG9mIGxvd2VzdCAxLWJpdCAob3IgLTEgaWYgbm9uZSlcbmZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKVxuICAgIGlmICh0aGlzW2ldICE9IDApIHJldHVybiBpICogdGhpcy5EQiArIGxiaXQodGhpc1tpXSlcbiAgaWYgKHRoaXMucyA8IDApIHJldHVybiB0aGlzLnQgKiB0aGlzLkRCXG4gIHJldHVybiAtMVxufVxuXG4vLyByZXR1cm4gbnVtYmVyIG9mIDEgYml0cyBpbiB4XG5mdW5jdGlvbiBjYml0KHgpIHtcbiAgdmFyIHIgPSAwXG4gIHdoaWxlICh4ICE9IDApIHtcbiAgICB4ICY9IHggLSAxXG4gICAgKytyXG4gIH1cbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0c1xuZnVuY3Rpb24gYm5CaXRDb3VudCgpIHtcbiAgdmFyIHIgPSAwLFxuICAgIHggPSB0aGlzLnMgJiB0aGlzLkRNXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIgKz0gY2JpdCh0aGlzW2ldIF4geClcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdHJ1ZSBpZmYgbnRoIGJpdCBpcyBzZXRcbmZ1bmN0aW9uIGJuVGVzdEJpdChuKSB7XG4gIHZhciBqID0gTWF0aC5mbG9vcihuIC8gdGhpcy5EQilcbiAgaWYgKGogPj0gdGhpcy50KSByZXR1cm4gKHRoaXMucyAhPSAwKVxuICByZXR1cm4gKCh0aGlzW2pdICYgKDEgPDwgKG4gJSB0aGlzLkRCKSkpICE9IDApXG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgb3AgKDE8PG4pXG5mdW5jdGlvbiBibnBDaGFuZ2VCaXQobiwgb3ApIHtcbiAgdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobilcbiAgdGhpcy5iaXR3aXNlVG8ociwgb3AsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgfCAoMTw8bilcbmZ1bmN0aW9uIGJuU2V0Qml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX29yKVxufVxuXG4vLyAocHVibGljKSB0aGlzICYgfigxPDxuKVxuZnVuY3Rpb24gYm5DbGVhckJpdChuKSB7XG4gIHJldHVybiB0aGlzLmNoYW5nZUJpdChuLCBvcF9hbmRub3QpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgXiAoMTw8bilcbmZ1bmN0aW9uIGJuRmxpcEJpdChuKSB7XG4gIHJldHVybiB0aGlzLmNoYW5nZUJpdChuLCBvcF94b3IpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYVxuZnVuY3Rpb24gYm5wQWRkVG8oYSwgcikge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICB2YXIgaSA9IDAsXG4gICAgYyA9IDAsXG4gICAgbSA9IE1hdGgubWluKGEudCwgc2VsZi50KVxuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBjICs9IHNlbGZbaV0gKyBhW2ldXG4gICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICBjID4+PSBzZWxmLkRCXG4gIH1cbiAgaWYgKGEudCA8IHNlbGYudCkge1xuICAgIGMgKz0gYS5zXG4gICAgd2hpbGUgKGkgPCBzZWxmLnQpIHtcbiAgICAgIGMgKz0gc2VsZltpXVxuICAgICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICAgIGMgPj49IHNlbGYuREJcbiAgICB9XG4gICAgYyArPSBzZWxmLnNcbiAgfSBlbHNlIHtcbiAgICBjICs9IHNlbGYuc1xuICAgIHdoaWxlIChpIDwgYS50KSB7XG4gICAgICBjICs9IGFbaV1cbiAgICAgIHJbaSsrXSA9IGMgJiBzZWxmLkRNXG4gICAgICBjID4+PSBzZWxmLkRCXG4gICAgfVxuICAgIGMgKz0gYS5zXG4gIH1cbiAgci5zID0gKGMgPCAwKSA/IC0xIDogMFxuICBpZiAoYyA+IDApIHJbaSsrXSA9IGNcbiAgZWxzZSBpZiAoYyA8IC0xKSByW2krK10gPSBzZWxmLkRWICsgY1xuICByLnQgPSBpXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHVibGljKSB0aGlzICsgYVxuZnVuY3Rpb24gYm5BZGQoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5hZGRUbyhhLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzIC0gYVxuZnVuY3Rpb24gYm5TdWJ0cmFjdChhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLnN1YlRvKGEsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgKiBhXG5mdW5jdGlvbiBibk11bHRpcGx5KGEpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMubXVsdGlwbHlUbyhhLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzXjJcbmZ1bmN0aW9uIGJuU3F1YXJlKCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5zcXVhcmVUbyhyKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzIC8gYVxuZnVuY3Rpb24gYm5EaXZpZGUoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5kaXZSZW1UbyhhLCByLCBudWxsKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzICUgYVxuZnVuY3Rpb24gYm5SZW1haW5kZXIoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5kaXZSZW1UbyhhLCBudWxsLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSBbdGhpcy9hLHRoaXMlYV1cbmZ1bmN0aW9uIGJuRGl2aWRlQW5kUmVtYWluZGVyKGEpIHtcbiAgdmFyIHEgPSBuZXcgQmlnSW50ZWdlcigpLFxuICAgIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMuZGl2UmVtVG8oYSwgcSwgcilcbiAgcmV0dXJuIG5ldyBBcnJheShxLCByKVxufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzICo9IG4sIHRoaXMgPj0gMCwgMSA8IG4gPCBEVlxuZnVuY3Rpb24gYm5wRE11bHRpcGx5KG4pIHtcbiAgdGhpc1t0aGlzLnRdID0gdGhpcy5hbSgwLCBuIC0gMSwgdGhpcywgMCwgMCwgdGhpcy50KVxuICArK3RoaXMudFxuICB0aGlzLmNsYW1wKClcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyArPSBuIDw8IHcgd29yZHMsIHRoaXMgPj0gMFxuZnVuY3Rpb24gYm5wREFkZE9mZnNldChuLCB3KSB7XG4gIGlmIChuID09IDApIHJldHVyblxuICB3aGlsZSAodGhpcy50IDw9IHcpIHRoaXNbdGhpcy50KytdID0gMFxuICB0aGlzW3ddICs9IG5cbiAgd2hpbGUgKHRoaXNbd10gPj0gdGhpcy5EVikge1xuICAgIHRoaXNbd10gLT0gdGhpcy5EVlxuICAgIGlmICgrK3cgPj0gdGhpcy50KSB0aGlzW3RoaXMudCsrXSA9IDBcbiAgICArK3RoaXNbd11cbiAgfVxufVxuXG4vLyBBIFwibnVsbFwiIHJlZHVjZXJcbmZ1bmN0aW9uIE51bGxFeHAoKSB7fVxuXG5mdW5jdGlvbiBuTm9wKHgpIHtcbiAgcmV0dXJuIHhcbn1cblxuZnVuY3Rpb24gbk11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpXG59XG5cbmZ1bmN0aW9uIG5TcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocilcbn1cblxuTnVsbEV4cC5wcm90b3R5cGUuY29udmVydCA9IG5Ob3Bcbk51bGxFeHAucHJvdG90eXBlLnJldmVydCA9IG5Ob3Bcbk51bGxFeHAucHJvdG90eXBlLm11bFRvID0gbk11bFRvXG5OdWxsRXhwLnByb3RvdHlwZS5zcXJUbyA9IG5TcXJUb1xuXG4vLyAocHVibGljKSB0aGlzXmVcbmZ1bmN0aW9uIGJuUG93KGUpIHtcbiAgcmV0dXJuIHRoaXMuZXhwKGUsIG5ldyBOdWxsRXhwKCkpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mIFwidGhpcyAqIGFcIiwgYS50IDw9IG5cbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbmZ1bmN0aW9uIGJucE11bHRpcGx5TG93ZXJUbyhhLCBuLCByKSB7XG4gIHZhciBpID0gTWF0aC5taW4odGhpcy50ICsgYS50LCBuKVxuICByLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwXG4gIHIudCA9IGlcbiAgd2hpbGUgKGkgPiAwKSByWy0taV0gPSAwXG4gIHZhciBqXG4gIGZvciAoaiA9IHIudCAtIHRoaXMudDsgaSA8IGo7ICsraSkgcltpICsgdGhpcy50XSA9IHRoaXMuYW0oMCwgYVtpXSwgciwgaSwgMCwgdGhpcy50KVxuICBmb3IgKGogPSBNYXRoLm1pbihhLnQsIG4pOyBpIDwgajsgKytpKSB0aGlzLmFtKDAsIGFbaV0sIHIsIGksIDAsIG4gLSBpKVxuICByLmNsYW1wKClcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IFwidGhpcyAqIGFcIiB3aXRob3V0IGxvd2VyIG4gd29yZHMsIG4gPiAwXG4vLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG5mdW5jdGlvbiBibnBNdWx0aXBseVVwcGVyVG8oYSwgbiwgcikge1xuICAtLW5cbiAgdmFyIGkgPSByLnQgPSB0aGlzLnQgKyBhLnQgLSBuXG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMFxuICBmb3IgKGkgPSBNYXRoLm1heChuIC0gdGhpcy50LCAwKTsgaSA8IGEudDsgKytpKVxuICAgIHJbdGhpcy50ICsgaSAtIG5dID0gdGhpcy5hbShuIC0gaSwgYVtpXSwgciwgMCwgMCwgdGhpcy50ICsgaSAtIG4pXG4gIHIuY2xhbXAoKVxuICByLmRyU2hpZnRUbygxLCByKVxufVxuXG4vLyBCYXJyZXR0IG1vZHVsYXIgcmVkdWN0aW9uXG5mdW5jdGlvbiBCYXJyZXR0KG0pIHtcbiAgLy8gc2V0dXAgQmFycmV0dFxuICB0aGlzLnIyID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLnEzID0gbmV3IEJpZ0ludGVnZXIoKVxuICBCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oMiAqIG0udCwgdGhpcy5yMilcbiAgdGhpcy5tdSA9IHRoaXMucjIuZGl2aWRlKG0pXG4gIHRoaXMubSA9IG1cbn1cblxuZnVuY3Rpb24gYmFycmV0dENvbnZlcnQoeCkge1xuICBpZiAoeC5zIDwgMCB8fCB4LnQgPiAyICogdGhpcy5tLnQpIHJldHVybiB4Lm1vZCh0aGlzLm0pXG4gIGVsc2UgaWYgKHguY29tcGFyZVRvKHRoaXMubSkgPCAwKSByZXR1cm4geFxuICBlbHNlIHtcbiAgICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgICB4LmNvcHlUbyhyKVxuICAgIHRoaXMucmVkdWNlKHIpXG4gICAgcmV0dXJuIHJcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXJyZXR0UmV2ZXJ0KHgpIHtcbiAgcmV0dXJuIHhcbn1cblxuLy8geCA9IHggbW9kIG0gKEhBQyAxNC40MilcbmZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoeCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgeC5kclNoaWZ0VG8oc2VsZi5tLnQgLSAxLCBzZWxmLnIyKVxuICBpZiAoeC50ID4gc2VsZi5tLnQgKyAxKSB7XG4gICAgeC50ID0gc2VsZi5tLnQgKyAxXG4gICAgeC5jbGFtcCgpXG4gIH1cbiAgc2VsZi5tdS5tdWx0aXBseVVwcGVyVG8oc2VsZi5yMiwgc2VsZi5tLnQgKyAxLCBzZWxmLnEzKVxuICBzZWxmLm0ubXVsdGlwbHlMb3dlclRvKHNlbGYucTMsIHNlbGYubS50ICsgMSwgc2VsZi5yMilcbiAgd2hpbGUgKHguY29tcGFyZVRvKHNlbGYucjIpIDwgMCkgeC5kQWRkT2Zmc2V0KDEsIHNlbGYubS50ICsgMSlcbiAgeC5zdWJUbyhzZWxmLnIyLCB4KVxuICB3aGlsZSAoeC5jb21wYXJlVG8oc2VsZi5tKSA+PSAwKSB4LnN1YlRvKHNlbGYubSwgeClcbn1cblxuLy8gciA9IHheMiBtb2QgbTsgeCAhPSByXG5mdW5jdGlvbiBiYXJyZXR0U3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpXG4gIHRoaXMucmVkdWNlKHIpXG59XG5cbi8vIHIgPSB4KnkgbW9kIG07IHgseSAhPSByXG5mdW5jdGlvbiBiYXJyZXR0TXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcilcbiAgdGhpcy5yZWR1Y2Uocilcbn1cblxuQmFycmV0dC5wcm90b3R5cGUuY29udmVydCA9IGJhcnJldHRDb252ZXJ0XG5CYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0XG5CYXJyZXR0LnByb3RvdHlwZS5yZWR1Y2UgPSBiYXJyZXR0UmVkdWNlXG5CYXJyZXR0LnByb3RvdHlwZS5tdWxUbyA9IGJhcnJldHRNdWxUb1xuQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG9cblxuLy8gKHB1YmxpYykgdGhpc15lICUgbSAoSEFDIDE0Ljg1KVxuZnVuY3Rpb24gYm5Nb2RQb3coZSwgbSkge1xuICB2YXIgaSA9IGUuYml0TGVuZ3RoKCksXG4gICAgaywgciA9IG5idigxKSxcbiAgICB6XG4gIGlmIChpIDw9IDApIHJldHVybiByXG4gIGVsc2UgaWYgKGkgPCAxOCkgayA9IDFcbiAgZWxzZSBpZiAoaSA8IDQ4KSBrID0gM1xuICBlbHNlIGlmIChpIDwgMTQ0KSBrID0gNFxuICBlbHNlIGlmIChpIDwgNzY4KSBrID0gNVxuICBlbHNlIGsgPSA2XG4gIGlmIChpIDwgOClcbiAgICB6ID0gbmV3IENsYXNzaWMobSlcbiAgZWxzZSBpZiAobS5pc0V2ZW4oKSlcbiAgICB6ID0gbmV3IEJhcnJldHQobSlcbiAgZWxzZVxuICAgIHogPSBuZXcgTW9udGdvbWVyeShtKVxuXG4gIC8vIHByZWNvbXB1dGF0aW9uXG4gIHZhciBnID0gbmV3IEFycmF5KCksXG4gICAgbiA9IDMsXG4gICAgazEgPSBrIC0gMSxcbiAgICBrbSA9ICgxIDw8IGspIC0gMVxuICBnWzFdID0gei5jb252ZXJ0KHRoaXMpXG4gIGlmIChrID4gMSkge1xuICAgIHZhciBnMiA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgICB6LnNxclRvKGdbMV0sIGcyKVxuICAgIHdoaWxlIChuIDw9IGttKSB7XG4gICAgICBnW25dID0gbmV3IEJpZ0ludGVnZXIoKVxuICAgICAgei5tdWxUbyhnMiwgZ1tuIC0gMl0sIGdbbl0pXG4gICAgICBuICs9IDJcbiAgICB9XG4gIH1cblxuICB2YXIgaiA9IGUudCAtIDEsXG4gICAgdywgaXMxID0gdHJ1ZSxcbiAgICByMiA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgdFxuICBpID0gbmJpdHMoZVtqXSkgLSAxXG4gIHdoaWxlIChqID49IDApIHtcbiAgICBpZiAoaSA+PSBrMSkgdyA9IChlW2pdID4+IChpIC0gazEpKSAmIGttXG4gICAgZWxzZSB7XG4gICAgICB3ID0gKGVbal0gJiAoKDEgPDwgKGkgKyAxKSkgLSAxKSkgPDwgKGsxIC0gaSlcbiAgICAgIGlmIChqID4gMCkgdyB8PSBlW2ogLSAxXSA+PiAodGhpcy5EQiArIGkgLSBrMSlcbiAgICB9XG5cbiAgICBuID0ga1xuICAgIHdoaWxlICgodyAmIDEpID09IDApIHtcbiAgICAgIHcgPj49IDFcbiAgICAgIC0tblxuICAgIH1cbiAgICBpZiAoKGkgLT0gbikgPCAwKSB7XG4gICAgICBpICs9IHRoaXMuREJcbiAgICAgIC0talxuICAgIH1cbiAgICBpZiAoaXMxKSB7IC8vIHJldCA9PSAxLCBkb24ndCBib3RoZXIgc3F1YXJpbmcgb3IgbXVsdGlwbHlpbmcgaXRcbiAgICAgIGdbd10uY29weVRvKHIpXG4gICAgICBpczEgPSBmYWxzZVxuICAgIH0gZWxzZSB7XG4gICAgICB3aGlsZSAobiA+IDEpIHtcbiAgICAgICAgei5zcXJUbyhyLCByMilcbiAgICAgICAgei5zcXJUbyhyMiwgcilcbiAgICAgICAgbiAtPSAyXG4gICAgICB9XG4gICAgICBpZiAobiA+IDApIHouc3FyVG8ociwgcjIpXG4gICAgICBlbHNlIHtcbiAgICAgICAgdCA9IHJcbiAgICAgICAgciA9IHIyXG4gICAgICAgIHIyID0gdFxuICAgICAgfVxuICAgICAgei5tdWxUbyhyMiwgZ1t3XSwgcilcbiAgICB9XG5cbiAgICB3aGlsZSAoaiA+PSAwICYmIChlW2pdICYgKDEgPDwgaSkpID09IDApIHtcbiAgICAgIHouc3FyVG8ociwgcjIpXG4gICAgICB0ID0gclxuICAgICAgciA9IHIyXG4gICAgICByMiA9IHRcbiAgICAgIGlmICgtLWkgPCAwKSB7XG4gICAgICAgIGkgPSB0aGlzLkRCIC0gMVxuICAgICAgICAtLWpcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHoucmV2ZXJ0KHIpXG59XG5cbi8vIChwdWJsaWMpIGdjZCh0aGlzLGEpIChIQUMgMTQuNTQpXG5mdW5jdGlvbiBibkdDRChhKSB7XG4gIHZhciB4ID0gKHRoaXMucyA8IDApID8gdGhpcy5uZWdhdGUoKSA6IHRoaXMuY2xvbmUoKVxuICB2YXIgeSA9IChhLnMgPCAwKSA/IGEubmVnYXRlKCkgOiBhLmNsb25lKClcbiAgaWYgKHguY29tcGFyZVRvKHkpIDwgMCkge1xuICAgIHZhciB0ID0geFxuICAgIHggPSB5XG4gICAgeSA9IHRcbiAgfVxuICB2YXIgaSA9IHguZ2V0TG93ZXN0U2V0Qml0KCksXG4gICAgZyA9IHkuZ2V0TG93ZXN0U2V0Qml0KClcbiAgaWYgKGcgPCAwKSByZXR1cm4geFxuICBpZiAoaSA8IGcpIGcgPSBpXG4gIGlmIChnID4gMCkge1xuICAgIHguclNoaWZ0VG8oZywgeClcbiAgICB5LnJTaGlmdFRvKGcsIHkpXG4gIH1cbiAgd2hpbGUgKHguc2lnbnVtKCkgPiAwKSB7XG4gICAgaWYgKChpID0geC5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB4LnJTaGlmdFRvKGksIHgpXG4gICAgaWYgKChpID0geS5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB5LnJTaGlmdFRvKGksIHkpXG4gICAgaWYgKHguY29tcGFyZVRvKHkpID49IDApIHtcbiAgICAgIHguc3ViVG8oeSwgeClcbiAgICAgIHguclNoaWZ0VG8oMSwgeClcbiAgICB9IGVsc2Uge1xuICAgICAgeS5zdWJUbyh4LCB5KVxuICAgICAgeS5yU2hpZnRUbygxLCB5KVxuICAgIH1cbiAgfVxuICBpZiAoZyA+IDApIHkubFNoaWZ0VG8oZywgeSlcbiAgcmV0dXJuIHlcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyAlIG4sIG4gPCAyXjI2XG5mdW5jdGlvbiBibnBNb2RJbnQobikge1xuICBpZiAobiA8PSAwKSByZXR1cm4gMFxuICB2YXIgZCA9IHRoaXMuRFYgJSBuLFxuICAgIHIgPSAodGhpcy5zIDwgMCkgPyBuIC0gMSA6IDBcbiAgaWYgKHRoaXMudCA+IDApXG4gICAgaWYgKGQgPT0gMCkgciA9IHRoaXNbMF0gJSBuXG4gICAgZWxzZVxuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByID0gKGQgKiByICsgdGhpc1tpXSkgJSBuXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIDEvdGhpcyAlIG0gKEhBQyAxNC42MSlcbmZ1bmN0aW9uIGJuTW9kSW52ZXJzZShtKSB7XG4gIHZhciBhYyA9IG0uaXNFdmVuKClcbiAgaWYgKHRoaXMuc2lnbnVtKCkgPT09IDApIHRocm93IG5ldyBFcnJvcignZGl2aXNpb24gYnkgemVybycpXG4gIGlmICgodGhpcy5pc0V2ZW4oKSAmJiBhYykgfHwgbS5zaWdudW0oKSA9PSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPXG4gIHZhciB1ID0gbS5jbG9uZSgpLFxuICAgIHYgPSB0aGlzLmNsb25lKClcbiAgdmFyIGEgPSBuYnYoMSksXG4gICAgYiA9IG5idigwKSxcbiAgICBjID0gbmJ2KDApLFxuICAgIGQgPSBuYnYoMSlcbiAgd2hpbGUgKHUuc2lnbnVtKCkgIT0gMCkge1xuICAgIHdoaWxlICh1LmlzRXZlbigpKSB7XG4gICAgICB1LnJTaGlmdFRvKDEsIHUpXG4gICAgICBpZiAoYWMpIHtcbiAgICAgICAgaWYgKCFhLmlzRXZlbigpIHx8ICFiLmlzRXZlbigpKSB7XG4gICAgICAgICAgYS5hZGRUbyh0aGlzLCBhKVxuICAgICAgICAgIGIuc3ViVG8obSwgYilcbiAgICAgICAgfVxuICAgICAgICBhLnJTaGlmdFRvKDEsIGEpXG4gICAgICB9IGVsc2UgaWYgKCFiLmlzRXZlbigpKSBiLnN1YlRvKG0sIGIpXG4gICAgICBiLnJTaGlmdFRvKDEsIGIpXG4gICAgfVxuICAgIHdoaWxlICh2LmlzRXZlbigpKSB7XG4gICAgICB2LnJTaGlmdFRvKDEsIHYpXG4gICAgICBpZiAoYWMpIHtcbiAgICAgICAgaWYgKCFjLmlzRXZlbigpIHx8ICFkLmlzRXZlbigpKSB7XG4gICAgICAgICAgYy5hZGRUbyh0aGlzLCBjKVxuICAgICAgICAgIGQuc3ViVG8obSwgZClcbiAgICAgICAgfVxuICAgICAgICBjLnJTaGlmdFRvKDEsIGMpXG4gICAgICB9IGVsc2UgaWYgKCFkLmlzRXZlbigpKSBkLnN1YlRvKG0sIGQpXG4gICAgICBkLnJTaGlmdFRvKDEsIGQpXG4gICAgfVxuICAgIGlmICh1LmNvbXBhcmVUbyh2KSA+PSAwKSB7XG4gICAgICB1LnN1YlRvKHYsIHUpXG4gICAgICBpZiAoYWMpIGEuc3ViVG8oYywgYSlcbiAgICAgIGIuc3ViVG8oZCwgYilcbiAgICB9IGVsc2Uge1xuICAgICAgdi5zdWJUbyh1LCB2KVxuICAgICAgaWYgKGFjKSBjLnN1YlRvKGEsIGMpXG4gICAgICBkLnN1YlRvKGIsIGQpXG4gICAgfVxuICB9XG4gIGlmICh2LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVST1xuICB3aGlsZSAoZC5jb21wYXJlVG8obSkgPj0gMCkgZC5zdWJUbyhtLCBkKVxuICB3aGlsZSAoZC5zaWdudW0oKSA8IDApIGQuYWRkVG8obSwgZClcbiAgcmV0dXJuIGRcbn1cblxudmFyIGxvd3ByaW1lcyA9IFtcbiAgMiwgMywgNSwgNywgMTEsIDEzLCAxNywgMTksIDIzLCAyOSwgMzEsIDM3LCA0MSwgNDMsIDQ3LCA1MywgNTksIDYxLCA2NywgNzEsXG4gIDczLCA3OSwgODMsIDg5LCA5NywgMTAxLCAxMDMsIDEwNywgMTA5LCAxMTMsIDEyNywgMTMxLCAxMzcsIDEzOSwgMTQ5LCAxNTEsXG4gIDE1NywgMTYzLCAxNjcsIDE3MywgMTc5LCAxODEsIDE5MSwgMTkzLCAxOTcsIDE5OSwgMjExLCAyMjMsIDIyNywgMjI5LCAyMzMsXG4gIDIzOSwgMjQxLCAyNTEsIDI1NywgMjYzLCAyNjksIDI3MSwgMjc3LCAyODEsIDI4MywgMjkzLCAzMDcsIDMxMSwgMzEzLCAzMTcsXG4gIDMzMSwgMzM3LCAzNDcsIDM0OSwgMzUzLCAzNTksIDM2NywgMzczLCAzNzksIDM4MywgMzg5LCAzOTcsIDQwMSwgNDA5LCA0MTksXG4gIDQyMSwgNDMxLCA0MzMsIDQzOSwgNDQzLCA0NDksIDQ1NywgNDYxLCA0NjMsIDQ2NywgNDc5LCA0ODcsIDQ5MSwgNDk5LCA1MDMsXG4gIDUwOSwgNTIxLCA1MjMsIDU0MSwgNTQ3LCA1NTcsIDU2MywgNTY5LCA1NzEsIDU3NywgNTg3LCA1OTMsIDU5OSwgNjAxLCA2MDcsXG4gIDYxMywgNjE3LCA2MTksIDYzMSwgNjQxLCA2NDMsIDY0NywgNjUzLCA2NTksIDY2MSwgNjczLCA2NzcsIDY4MywgNjkxLCA3MDEsXG4gIDcwOSwgNzE5LCA3MjcsIDczMywgNzM5LCA3NDMsIDc1MSwgNzU3LCA3NjEsIDc2OSwgNzczLCA3ODcsIDc5NywgODA5LCA4MTEsXG4gIDgyMSwgODIzLCA4MjcsIDgyOSwgODM5LCA4NTMsIDg1NywgODU5LCA4NjMsIDg3NywgODgxLCA4ODMsIDg4NywgOTA3LCA5MTEsXG4gIDkxOSwgOTI5LCA5MzcsIDk0MSwgOTQ3LCA5NTMsIDk2NywgOTcxLCA5NzcsIDk4MywgOTkxLCA5OTdcbl1cblxudmFyIGxwbGltID0gKDEgPDwgMjYpIC8gbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGggLSAxXVxuXG4vLyAocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnRcbmZ1bmN0aW9uIGJuSXNQcm9iYWJsZVByaW1lKHQpIHtcbiAgdmFyIGksIHggPSB0aGlzLmFicygpXG4gIGlmICh4LnQgPT0gMSAmJiB4WzBdIDw9IGxvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoIC0gMV0pIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKHhbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZVxuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIGlmICh4LmlzRXZlbigpKSByZXR1cm4gZmFsc2VcbiAgaSA9IDFcbiAgd2hpbGUgKGkgPCBsb3dwcmltZXMubGVuZ3RoKSB7XG4gICAgdmFyIG0gPSBsb3dwcmltZXNbaV0sXG4gICAgICBqID0gaSArIDFcbiAgICB3aGlsZSAoaiA8IGxvd3ByaW1lcy5sZW5ndGggJiYgbSA8IGxwbGltKSBtICo9IGxvd3ByaW1lc1tqKytdXG4gICAgbSA9IHgubW9kSW50KG0pXG4gICAgd2hpbGUgKGkgPCBqKSBpZiAobSAlIGxvd3ByaW1lc1tpKytdID09IDApIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiB4Lm1pbGxlclJhYmluKHQpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHRydWUgaWYgcHJvYmFibHkgcHJpbWUgKEhBQyA0LjI0LCBNaWxsZXItUmFiaW4pXG5mdW5jdGlvbiBibnBNaWxsZXJSYWJpbih0KSB7XG4gIHZhciBuMSA9IHRoaXMuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpXG4gIHZhciBrID0gbjEuZ2V0TG93ZXN0U2V0Qml0KClcbiAgaWYgKGsgPD0gMCkgcmV0dXJuIGZhbHNlXG4gIHZhciByID0gbjEuc2hpZnRSaWdodChrKVxuICB0ID0gKHQgKyAxKSA+PiAxXG4gIGlmICh0ID4gbG93cHJpbWVzLmxlbmd0aCkgdCA9IGxvd3ByaW1lcy5sZW5ndGhcbiAgdmFyIGEgPSBuZXcgQmlnSW50ZWdlcihudWxsKVxuICB2YXIgaiwgYmFzZXMgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHQ7ICsraSkge1xuICAgIGZvciAoOzspIHtcbiAgICAgIGogPSBsb3dwcmltZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogbG93cHJpbWVzLmxlbmd0aCldXG4gICAgICBpZiAoYmFzZXMuaW5kZXhPZihqKSA9PSAtMSkgYnJlYWtcbiAgICB9XG4gICAgYmFzZXMucHVzaChqKVxuICAgIGEuZnJvbUludChqKVxuICAgIHZhciB5ID0gYS5tb2RQb3cociwgdGhpcylcbiAgICBpZiAoeS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDAgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgIHZhciBqID0gMVxuICAgICAgd2hpbGUgKGorKyA8IGsgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgICAgeSA9IHkubW9kUG93SW50KDIsIHRoaXMpXG4gICAgICAgIGlmICh5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCkgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgICBpZiAoeS5jb21wYXJlVG8objEpICE9IDApIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG4vLyBwcm90ZWN0ZWRcbnByb3RvLmNodW5rU2l6ZSA9IGJucENodW5rU2l6ZVxucHJvdG8udG9SYWRpeCA9IGJucFRvUmFkaXhcbnByb3RvLmZyb21SYWRpeCA9IGJucEZyb21SYWRpeFxucHJvdG8uZnJvbU51bWJlciA9IGJucEZyb21OdW1iZXJcbnByb3RvLmJpdHdpc2VUbyA9IGJucEJpdHdpc2VUb1xucHJvdG8uY2hhbmdlQml0ID0gYm5wQ2hhbmdlQml0XG5wcm90by5hZGRUbyA9IGJucEFkZFRvXG5wcm90by5kTXVsdGlwbHkgPSBibnBETXVsdGlwbHlcbnByb3RvLmRBZGRPZmZzZXQgPSBibnBEQWRkT2Zmc2V0XG5wcm90by5tdWx0aXBseUxvd2VyVG8gPSBibnBNdWx0aXBseUxvd2VyVG9cbnByb3RvLm11bHRpcGx5VXBwZXJUbyA9IGJucE11bHRpcGx5VXBwZXJUb1xucHJvdG8ubW9kSW50ID0gYm5wTW9kSW50XG5wcm90by5taWxsZXJSYWJpbiA9IGJucE1pbGxlclJhYmluXG5cbi8vIHB1YmxpY1xucHJvdG8uY2xvbmUgPSBibkNsb25lXG5wcm90by5pbnRWYWx1ZSA9IGJuSW50VmFsdWVcbnByb3RvLmJ5dGVWYWx1ZSA9IGJuQnl0ZVZhbHVlXG5wcm90by5zaG9ydFZhbHVlID0gYm5TaG9ydFZhbHVlXG5wcm90by5zaWdudW0gPSBiblNpZ051bVxucHJvdG8udG9CeXRlQXJyYXkgPSBiblRvQnl0ZUFycmF5XG5wcm90by5lcXVhbHMgPSBibkVxdWFsc1xucHJvdG8ubWluID0gYm5NaW5cbnByb3RvLm1heCA9IGJuTWF4XG5wcm90by5hbmQgPSBibkFuZFxucHJvdG8ub3IgPSBibk9yXG5wcm90by54b3IgPSBiblhvclxucHJvdG8uYW5kTm90ID0gYm5BbmROb3RcbnByb3RvLm5vdCA9IGJuTm90XG5wcm90by5zaGlmdExlZnQgPSBiblNoaWZ0TGVmdFxucHJvdG8uc2hpZnRSaWdodCA9IGJuU2hpZnRSaWdodFxucHJvdG8uZ2V0TG93ZXN0U2V0Qml0ID0gYm5HZXRMb3dlc3RTZXRCaXRcbnByb3RvLmJpdENvdW50ID0gYm5CaXRDb3VudFxucHJvdG8udGVzdEJpdCA9IGJuVGVzdEJpdFxucHJvdG8uc2V0Qml0ID0gYm5TZXRCaXRcbnByb3RvLmNsZWFyQml0ID0gYm5DbGVhckJpdFxucHJvdG8uZmxpcEJpdCA9IGJuRmxpcEJpdFxucHJvdG8uYWRkID0gYm5BZGRcbnByb3RvLnN1YnRyYWN0ID0gYm5TdWJ0cmFjdFxucHJvdG8ubXVsdGlwbHkgPSBibk11bHRpcGx5XG5wcm90by5kaXZpZGUgPSBibkRpdmlkZVxucHJvdG8ucmVtYWluZGVyID0gYm5SZW1haW5kZXJcbnByb3RvLmRpdmlkZUFuZFJlbWFpbmRlciA9IGJuRGl2aWRlQW5kUmVtYWluZGVyXG5wcm90by5tb2RQb3cgPSBibk1vZFBvd1xucHJvdG8ubW9kSW52ZXJzZSA9IGJuTW9kSW52ZXJzZVxucHJvdG8ucG93ID0gYm5Qb3dcbnByb3RvLmdjZCA9IGJuR0NEXG5wcm90by5pc1Byb2JhYmxlUHJpbWUgPSBibklzUHJvYmFibGVQcmltZVxuXG4vLyBKU0JOLXNwZWNpZmljIGV4dGVuc2lvblxucHJvdG8uc3F1YXJlID0gYm5TcXVhcmVcblxuLy8gY29uc3RhbnRzXG5CaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMClcbkJpZ0ludGVnZXIuT05FID0gbmJ2KDEpXG5CaWdJbnRlZ2VyLnZhbHVlT2YgPSBuYnZcblxubW9kdWxlLmV4cG9ydHMgPSBCaWdJbnRlZ2VyXG4iLCIvLyBGSVhNRTogS2luZCBvZiBhIHdlaXJkIHdheSB0byB0aHJvdyBleGNlcHRpb25zLCBjb25zaWRlciByZW1vdmluZ1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vYmlnaScpXG5cbi8qKlxuICogVHVybnMgYSBieXRlIGFycmF5IGludG8gYSBiaWcgaW50ZWdlci5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgaW50ZXJwcmV0IGEgYnl0ZSBhcnJheSBhcyBhIGJpZyBpbnRlZ2VyIGluIGJpZ1xuICogZW5kaWFuIG5vdGF0aW9uLlxuICovXG5CaWdJbnRlZ2VyLmZyb21CeXRlQXJyYXlVbnNpZ25lZCA9IGZ1bmN0aW9uKGJ5dGVBcnJheSkge1xuICAvLyBCaWdJbnRlZ2VyIGV4cGVjdHMgYSBERVIgaW50ZWdlciBjb25mb3JtYW50IGJ5dGUgYXJyYXlcbiAgaWYgKGJ5dGVBcnJheVswXSAmIDB4ODApIHtcbiAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoWzBdLmNvbmNhdChieXRlQXJyYXkpKVxuICB9XG5cbiAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGJ5dGVBcnJheSlcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgYnl0ZSBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgYmlnIGludGVnZXIuXG4gKlxuICogVGhpcyByZXR1cm5zIHRoZSBhYnNvbHV0ZSBvZiB0aGUgY29udGFpbmVkIHZhbHVlIGluIGJpZyBlbmRpYW5cbiAqIGZvcm0uIEEgdmFsdWUgb2YgemVybyByZXN1bHRzIGluIGFuIGVtcHR5IGFycmF5LlxuICovXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J5dGVBcnJheVVuc2lnbmVkID0gZnVuY3Rpb24oKSB7XG4gIHZhciBieXRlQXJyYXkgPSB0aGlzLnRvQnl0ZUFycmF5KClcbiAgcmV0dXJuIGJ5dGVBcnJheVswXSA9PT0gMCA/IGJ5dGVBcnJheS5zbGljZSgxKSA6IGJ5dGVBcnJheVxufVxuXG5CaWdJbnRlZ2VyLmZyb21ERVJJbnRlZ2VyID0gZnVuY3Rpb24oYnl0ZUFycmF5KSB7XG4gIHJldHVybiBuZXcgQmlnSW50ZWdlcihieXRlQXJyYXkpXG59XG5cbi8qXG4gKiBDb252ZXJ0cyBCaWdJbnRlZ2VyIHRvIGEgREVSIGludGVnZXIgcmVwcmVzZW50YXRpb24uXG4gKlxuICogVGhlIGZvcm1hdCBmb3IgdGhpcyB2YWx1ZSB1c2VzIHRoZSBtb3N0IHNpZ25pZmljYW50IGJpdCBhcyBhIHNpZ25cbiAqIGJpdC4gIElmIHRoZSBtb3N0IHNpZ25pZmljYW50IGJpdCBpcyBhbHJlYWR5IHNldCBhbmQgdGhlIGludGVnZXIgaXNcbiAqIHBvc2l0aXZlLCBhIDB4MDAgaXMgcHJlcGVuZGVkLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgMCA9PiAgICAgMHgwMFxuICogICAgICAxID0+ICAgICAweDAxXG4gKiAgICAgLTEgPT4gICAgIDB4ZmZcbiAqICAgIDEyNyA9PiAgICAgMHg3ZlxuICogICAtMTI3ID0+ICAgICAweDgxXG4gKiAgICAxMjggPT4gICAweDAwODBcbiAqICAgLTEyOCA9PiAgICAgMHg4MFxuICogICAgMjU1ID0+ICAgMHgwMGZmXG4gKiAgIC0yNTUgPT4gICAweGZmMDFcbiAqICAxNjMwMCA9PiAgIDB4M2ZhY1xuICogLTE2MzAwID0+ICAgMHhjMDU0XG4gKiAgNjIzMDAgPT4gMHgwMGYzNWNcbiAqIC02MjMwMCA9PiAweGZmMGNhNFxuKi9cbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvREVSSW50ZWdlciA9IEJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5XG5cbkJpZ0ludGVnZXIuZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAvLyBCaWdJbnRlZ2VyIGV4cGVjdHMgYSBERVIgaW50ZWdlciBjb25mb3JtYW50IGJ5dGUgYXJyYXlcbiAgaWYgKGJ1ZmZlclswXSAmIDB4ODApIHtcbiAgICB2YXIgYnl0ZUFycmF5ID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYnVmZmVyKVxuXG4gICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKFswXS5jb25jYXQoYnl0ZUFycmF5KSlcbiAgfVxuXG4gIHJldHVybiBuZXcgQmlnSW50ZWdlcihidWZmZXIpXG59XG5cbkJpZ0ludGVnZXIuZnJvbUhleCA9IGZ1bmN0aW9uKGhleCkge1xuICBpZiAoaGV4ID09PSAnJykgcmV0dXJuIEJpZ0ludGVnZXIuWkVST1xuXG4gIGFzc2VydC5lcXVhbChoZXgsIGhleC5tYXRjaCgvXltBLUZhLWYwLTldKy8pLCAnSW52YWxpZCBoZXggc3RyaW5nJylcbiAgYXNzZXJ0LmVxdWFsKGhleC5sZW5ndGggJSAyLCAwLCAnSW5jb21wbGV0ZSBoZXgnKVxuICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoaGV4LCAxNilcbn1cblxuQmlnSW50ZWdlci5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbihzaXplKSB7XG4gIHZhciBieXRlQXJyYXkgPSB0aGlzLnRvQnl0ZUFycmF5VW5zaWduZWQoKVxuICB2YXIgemVyb3MgPSBbXVxuXG4gIHZhciBwYWRkaW5nID0gc2l6ZSAtIGJ5dGVBcnJheS5sZW5ndGhcbiAgd2hpbGUgKHplcm9zLmxlbmd0aCA8IHBhZGRpbmcpIHplcm9zLnB1c2goMClcblxuICByZXR1cm4gbmV3IEJ1ZmZlcih6ZXJvcy5jb25jYXQoYnl0ZUFycmF5KSlcbn1cblxuQmlnSW50ZWdlci5wcm90b3R5cGUudG9IZXggPSBmdW5jdGlvbihzaXplKSB7XG4gIHJldHVybiB0aGlzLnRvQnVmZmVyKHNpemUpLnRvU3RyaW5nKCdoZXgnKVxufVxuIiwidmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL2JpZ2knKVxuXG4vL2FkZG9uc1xucmVxdWlyZSgnLi9jb252ZXJ0JylcblxubW9kdWxlLmV4cG9ydHMgPSBCaWdJbnRlZ2VyIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIl9mcm9tXCI6IFwiYmlnaUBeMS40LjFcIixcbiAgXCJfaWRcIjogXCJiaWdpQDEuNC4yXCIsXG4gIFwiX2luQnVuZGxlXCI6IGZhbHNlLFxuICBcIl9pbnRlZ3JpdHlcIjogXCJzaGExLW5HWmFsZmlMaXdqOEJjL1hNZlZoaFoxeVdDVT1cIixcbiAgXCJfbG9jYXRpb25cIjogXCIvcGVlcnBsYXlzanMtbGliL2JpZ2lcIixcbiAgXCJfcGhhbnRvbUNoaWxkcmVuXCI6IHt9LFxuICBcIl9yZXF1ZXN0ZWRcIjoge1xuICAgIFwidHlwZVwiOiBcInJhbmdlXCIsXG4gICAgXCJyZWdpc3RyeVwiOiB0cnVlLFxuICAgIFwicmF3XCI6IFwiYmlnaUBeMS40LjFcIixcbiAgICBcIm5hbWVcIjogXCJiaWdpXCIsXG4gICAgXCJlc2NhcGVkTmFtZVwiOiBcImJpZ2lcIixcbiAgICBcInJhd1NwZWNcIjogXCJeMS40LjFcIixcbiAgICBcInNhdmVTcGVjXCI6IG51bGwsXG4gICAgXCJmZXRjaFNwZWNcIjogXCJeMS40LjFcIlxuICB9LFxuICBcIl9yZXF1aXJlZEJ5XCI6IFtcbiAgICBcIi9wZWVycGxheXNqcy1saWJcIixcbiAgICBcIi9wZWVycGxheXNqcy1saWIvZWN1cnZlXCJcbiAgXSxcbiAgXCJfcmVzb2x2ZWRcIjogXCJodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZy9iaWdpLy0vYmlnaS0xLjQuMi50Z3pcIixcbiAgXCJfc2hhc3VtXCI6IFwiOWM2NjVhOTVmODhiOGIwOGZjMDVjZmQ3MzFmNTYxODU5ZDcyNTgyNVwiLFxuICBcIl9zcGVjXCI6IFwiYmlnaUBeMS40LjFcIixcbiAgXCJfd2hlcmVcIjogXCIvVXNlcnMvbXNlYXdhcmQvRG9jdW1lbnRzL2NvZGUvcGVlcnBsYXlzanMtbGliXCIsXG4gIFwiYnVnc1wiOiB7XG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vY3J5cHRvY29pbmpzL2JpZ2kvaXNzdWVzXCJcbiAgfSxcbiAgXCJidW5kbGVEZXBlbmRlbmNpZXNcIjogZmFsc2UsXG4gIFwiZGVwZW5kZW5jaWVzXCI6IHt9LFxuICBcImRlcHJlY2F0ZWRcIjogZmFsc2UsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJCaWcgaW50ZWdlcnMuXCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImNvdmVyYWxsc1wiOiBcIl4yLjExLjJcIixcbiAgICBcImlzdGFuYnVsXCI6IFwiXjAuMy41XCIsXG4gICAgXCJqc2hpbnRcIjogXCJeMi41LjFcIixcbiAgICBcIm1vY2hhXCI6IFwiXjIuMS4wXCIsXG4gICAgXCJtb2NoaWZ5XCI6IFwiXjIuMS4wXCJcbiAgfSxcbiAgXCJob21lcGFnZVwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG9jb2luanMvYmlnaSNyZWFkbWVcIixcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJjcnlwdG9ncmFwaHlcIixcbiAgICBcIm1hdGhcIixcbiAgICBcImJpdGNvaW5cIixcbiAgICBcImFyYml0cmFyeVwiLFxuICAgIFwicHJlY2lzaW9uXCIsXG4gICAgXCJhcml0aG1ldGljXCIsXG4gICAgXCJiaWdcIixcbiAgICBcImludGVnZXJcIixcbiAgICBcImludFwiLFxuICAgIFwibnVtYmVyXCIsXG4gICAgXCJiaWdpbnRlZ2VyXCIsXG4gICAgXCJiaWdpbnRcIixcbiAgICBcImJpZ251bWJlclwiLFxuICAgIFwiZGVjaW1hbFwiLFxuICAgIFwiZmxvYXRcIlxuICBdLFxuICBcIm1haW5cIjogXCIuL2xpYi9pbmRleC5qc1wiLFxuICBcIm5hbWVcIjogXCJiaWdpXCIsXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ1cmxcIjogXCJnaXQraHR0cHM6Ly9naXRodWIuY29tL2NyeXB0b2NvaW5qcy9iaWdpLmdpdFwiLFxuICAgIFwidHlwZVwiOiBcImdpdFwiXG4gIH0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJicm93c2VyLXRlc3RcIjogXCJtb2NoaWZ5IC0td2QgLVIgc3BlY1wiLFxuICAgIFwiY292ZXJhZ2VcIjogXCJpc3RhbmJ1bCBjb3ZlciAuL25vZGVfbW9kdWxlcy8uYmluL19tb2NoYSAtLSAtLXJlcG9ydGVyIGxpc3QgdGVzdC8qLmpzXCIsXG4gICAgXCJjb3ZlcmFsbHNcIjogXCJucG0gcnVuLXNjcmlwdCBjb3ZlcmFnZSAmJiBub2RlIC4vbm9kZV9tb2R1bGVzLy5iaW4vY292ZXJhbGxzIDwgY292ZXJhZ2UvbGNvdi5pbmZvXCIsXG4gICAgXCJqc2hpbnRcIjogXCJqc2hpbnQgLS1jb25maWcganNoaW50Lmpzb24gbGliLyouanMgOyB0cnVlXCIsXG4gICAgXCJ0ZXN0XCI6IFwiX21vY2hhIC0tIHRlc3QvKi5qc1wiLFxuICAgIFwidW5pdFwiOiBcIm1vY2hhXCJcbiAgfSxcbiAgXCJ0ZXN0bGluZ1wiOiB7XG4gICAgXCJmaWxlc1wiOiBcInRlc3QvKi5qc1wiLFxuICAgIFwiaGFybmVzc1wiOiBcIm1vY2hhXCIsXG4gICAgXCJicm93c2Vyc1wiOiBbXG4gICAgICBcImllLzkuLmxhdGVzdFwiLFxuICAgICAgXCJmaXJlZm94L2xhdGVzdFwiLFxuICAgICAgXCJjaHJvbWUvbGF0ZXN0XCIsXG4gICAgICBcInNhZmFyaS82LjAuLmxhdGVzdFwiLFxuICAgICAgXCJpcGhvbmUvNi4wLi5sYXRlc3RcIixcbiAgICAgIFwiYW5kcm9pZC1icm93c2VyLzQuMi4ubGF0ZXN0XCJcbiAgICBdXG4gIH0sXG4gIFwidmVyc2lvblwiOiBcIjEuNC4yXCJcbn1cbiIsIiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIER1ZSB0byB2YXJpb3VzIGJyb3dzZXIgYnVncywgc29tZXRpbWVzIHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24gd2lsbCBiZSB1c2VkIGV2ZW5cbiAqIHdoZW4gdGhlIGJyb3dzZXIgc3VwcG9ydHMgdHlwZWQgYXJyYXlzLlxuICpcbiAqIE5vdGU6XG4gKlxuICogICAtIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcyxcbiAqICAgICBTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOC5cbiAqXG4gKiAgIC0gQ2hyb21lIDktMTAgaXMgbWlzc2luZyB0aGUgYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbi5cbiAqXG4gKiAgIC0gSUUxMCBoYXMgYSBicm9rZW4gYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFycmF5cyBvZlxuICogICAgIGluY29ycmVjdCBsZW5ndGggaW4gc29tZSBzaXR1YXRpb25zLlxuXG4gKiBXZSBkZXRlY3QgdGhlc2UgYnVnZ3kgYnJvd3NlcnMgYW5kIHNldCBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgIHRvIGBmYWxzZWAgc28gdGhleVxuICogZ2V0IHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHNsb3dlciBidXQgYmVoYXZlcyBjb3JyZWN0bHkuXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlQgIT09IHVuZGVmaW5lZFxuICA/IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gIDogdHlwZWRBcnJheVN1cHBvcnQoKVxuXG4vKlxuICogRXhwb3J0IGtNYXhMZW5ndGggYWZ0ZXIgdHlwZWQgYXJyYXkgc3VwcG9ydCBpcyBkZXRlcm1pbmVkLlxuICovXG5leHBvcnRzLmtNYXhMZW5ndGggPSBrTWF4TGVuZ3RoKClcblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5fX3Byb3RvX18gPSB7X19wcm90b19fOiBVaW50OEFycmF5LnByb3RvdHlwZSwgZm9vOiBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9fVxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gICAgICAgIGFyci5zdWJhcnJheSgxLCAxKS5ieXRlTGVuZ3RoID09PSAwIC8vIGllMTAgaGFzIGJyb2tlbiBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5mdW5jdGlvbiBrTWF4TGVuZ3RoICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gICAgPyAweDdmZmZmZmZmXG4gICAgOiAweDNmZmZmZmZmXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlciAodGhhdCwgbGVuZ3RoKSB7XG4gIGlmIChrTWF4TGVuZ3RoKCkgPCBsZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCB0eXBlZCBhcnJheSBsZW5ndGgnKVxuICB9XG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpXG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIGlmICh0aGF0ID09PSBudWxsKSB7XG4gICAgICB0aGF0ID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gICAgfVxuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiAhKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICAvLyBDb21tb24gY2FzZS5cbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnSWYgZW5jb2RpbmcgaXMgc3BlY2lmaWVkIHRoZW4gdGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcnXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiBhbGxvY1Vuc2FmZSh0aGlzLCBhcmcpXG4gIH1cbiAgcmV0dXJuIGZyb20odGhpcywgYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG4vLyBUT0RPOiBMZWdhY3ksIG5vdCBuZWVkZWQgYW55bW9yZS4gUmVtb3ZlIGluIG5leHQgbWFqb3IgdmVyc2lvbi5cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiBmcm9tICh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuXG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5QnVmZmVyKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhhdCwgdmFsdWUpXG59XG5cbi8qKlxuICogRnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gQnVmZmVyKGFyZywgZW5jb2RpbmcpIGJ1dCB0aHJvd3MgYSBUeXBlRXJyb3JcbiAqIGlmIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQnVmZmVyLmZyb20oc3RyWywgZW5jb2RpbmddKVxuICogQnVmZmVyLmZyb20oYXJyYXkpXG4gKiBCdWZmZXIuZnJvbShidWZmZXIpXG4gKiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlclssIGJ5dGVPZmZzZXRbLCBsZW5ndGhdXSlcbiAqKi9cbkJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGZyb20obnVsbCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC5zcGVjaWVzICYmXG4gICAgICBCdWZmZXJbU3ltYm9sLnNwZWNpZXNdID09PSBCdWZmZXIpIHtcbiAgICAvLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgICB2YWx1ZTogbnVsbCxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzZXJ0U2l6ZSAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH0gZWxzZSBpZiAoc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jICh0aGF0LCBzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhudWxsLCBzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHRoYXQsIHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyArK2kpIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImVuY29kaW5nXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBlbmNvZGluZycpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG5cbiAgdmFyIGFjdHVhbCA9IHRoYXQud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIHRoYXQgPSB0aGF0LnNsaWNlKDAsIGFjdHVhbClcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIgKHRoYXQsIGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgYXJyYXkuYnl0ZUxlbmd0aCAvLyB0aGlzIHRocm93cyBpZiBgYXJyYXlgIGlzIG5vdCBhIHZhbGlkIEFycmF5QnVmZmVyXG5cbiAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0KSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ29mZnNldFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCArIChsZW5ndGggfHwgMCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnbGVuZ3RoXFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBhcnJheVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbUFycmF5TGlrZSh0aGF0LCBhcnJheSlcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmopIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmopKSB7XG4gICAgdmFyIGxlbiA9IGNoZWNrZWQob2JqLmxlbmd0aCkgfCAwXG4gICAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW4pXG5cbiAgICBpZiAodGhhdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGF0XG4gICAgfVxuXG4gICAgb2JqLmNvcHkodGhhdCwgMCwgMCwgbGVuKVxuICAgIHJldHVybiB0aGF0XG4gIH1cblxuICBpZiAob2JqKSB7XG4gICAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIG9iai5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gb2JqKSB7XG4gICAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IGlzbmFuKG9iai5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgMClcbiAgICAgIH1cbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iailcbiAgICB9XG5cbiAgICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmouZGF0YSlcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuJylcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGgoKWAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBrTWF4TGVuZ3RoKCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsga01heExlbmd0aCgpLnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgICB9XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpXG4gICAgcG9zICs9IGJ1Zi5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgc3RyaW5nIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgc3RyaW5nID0gJycgKyBzdHJpbmdcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhlIHByb3BlcnR5IGlzIHVzZWQgYnkgYEJ1ZmZlci5pc0J1ZmZlcmAgYW5kIGBpcy1idWZmZXJgIChpbiBTYWZhcmkgNS03KSB0byBkZXRlY3Rcbi8vIEJ1ZmZlciBpbnN0YW5jZXMuXG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpc1N0YXJ0LCB0aGlzRW5kKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5kID0gdGFyZ2V0ID8gdGFyZ2V0Lmxlbmd0aCA6IDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzU3RhcnQgPSAwXG4gIH1cbiAgaWYgKHRoaXNFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNFbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiB0YXJnZXQubGVuZ3RoIHx8IHRoaXNTdGFydCA8IDAgfHwgdGhpc0VuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQgJiYgc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuICBpZiAoc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIHN0YXJ0ID4+Pj0gMFxuICBlbmQgPj4+PSAwXG4gIHRoaXNTdGFydCA+Pj49IDBcbiAgdGhpc0VuZCA+Pj49IDBcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0KSByZXR1cm4gMFxuXG4gIHZhciB4ID0gdGhpc0VuZCAtIHRoaXNTdGFydFxuICB2YXIgeSA9IGVuZCAtIHN0YXJ0XG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuXG4gIHZhciB0aGlzQ29weSA9IHRoaXMuc2xpY2UodGhpc1N0YXJ0LCB0aGlzRW5kKVxuICB2YXIgdGFyZ2V0Q29weSA9IHRhcmdldC5zbGljZShzdGFydCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAodGhpc0NvcHlbaV0gIT09IHRhcmdldENvcHlbaV0pIHtcbiAgICAgIHggPSB0aGlzQ29weVtpXVxuICAgICAgeSA9IHRhcmdldENvcHlbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG4vLyBGaW5kcyBlaXRoZXIgdGhlIGZpcnN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA+PSBgYnl0ZU9mZnNldGAsXG4vLyBPUiB0aGUgbGFzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPD0gYGJ5dGVPZmZzZXRgLlxuLy9cbi8vIEFyZ3VtZW50czpcbi8vIC0gYnVmZmVyIC0gYSBCdWZmZXIgdG8gc2VhcmNoXG4vLyAtIHZhbCAtIGEgc3RyaW5nLCBCdWZmZXIsIG9yIG51bWJlclxuLy8gLSBieXRlT2Zmc2V0IC0gYW4gaW5kZXggaW50byBgYnVmZmVyYDsgd2lsbCBiZSBjbGFtcGVkIHRvIGFuIGludDMyXG4vLyAtIGVuY29kaW5nIC0gYW4gb3B0aW9uYWwgZW5jb2RpbmcsIHJlbGV2YW50IGlzIHZhbCBpcyBhIHN0cmluZ1xuLy8gLSBkaXIgLSB0cnVlIGZvciBpbmRleE9mLCBmYWxzZSBmb3IgbGFzdEluZGV4T2ZcbmZ1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mIChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICAvLyBFbXB0eSBidWZmZXIgbWVhbnMgbm8gbWF0Y2hcbiAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybiAtMVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID0gK2J5dGVPZmZzZXQgIC8vIENvZXJjZSB0byBOdW1iZXIuXG4gIGlmIChpc05hTihieXRlT2Zmc2V0KSkge1xuICAgIC8vIGJ5dGVPZmZzZXQ6IGl0IGl0J3MgdW5kZWZpbmVkLCBudWxsLCBOYU4sIFwiZm9vXCIsIGV0Yywgc2VhcmNoIHdob2xlIGJ1ZmZlclxuICAgIGJ5dGVPZmZzZXQgPSBkaXIgPyAwIDogKGJ1ZmZlci5sZW5ndGggLSAxKVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXQ6IG5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCArIGJ5dGVPZmZzZXRcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkge1xuICAgIGlmIChkaXIpIHJldHVybiAtMVxuICAgIGVsc2UgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggLSAxXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IDApIHtcbiAgICBpZiAoZGlyKSBieXRlT2Zmc2V0ID0gMFxuICAgIGVsc2UgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBOb3JtYWxpemUgdmFsXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICAvLyBGaW5hbGx5LCBzZWFyY2ggZWl0aGVyIGluZGV4T2YgKGlmIGRpciBpcyB0cnVlKSBvciBsYXN0SW5kZXhPZlxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMHhGRiAvLyBTZWFyY2ggZm9yIGEgYnl0ZSB2YWx1ZSBbMC0yNTVdXG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmXG4gICAgICAgIHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZGlyKSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBhcnJheUluZGV4T2YgKGFyciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIHZhciBpbmRleFNpemUgPSAxXG4gIHZhciBhcnJMZW5ndGggPSBhcnIubGVuZ3RoXG4gIHZhciB2YWxMZW5ndGggPSB2YWwubGVuZ3RoXG5cbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgIGlmIChlbmNvZGluZyA9PT0gJ3VjczInIHx8IGVuY29kaW5nID09PSAndWNzLTInIHx8XG4gICAgICAgIGVuY29kaW5nID09PSAndXRmMTZsZScgfHwgZW5jb2RpbmcgPT09ICd1dGYtMTZsZScpIHtcbiAgICAgIGlmIChhcnIubGVuZ3RoIDwgMiB8fCB2YWwubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH1cbiAgICAgIGluZGV4U2l6ZSA9IDJcbiAgICAgIGFyckxlbmd0aCAvPSAyXG4gICAgICB2YWxMZW5ndGggLz0gMlxuICAgICAgYnl0ZU9mZnNldCAvPSAyXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZCAoYnVmLCBpKSB7XG4gICAgaWYgKGluZGV4U2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGJ1ZltpXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpICogaW5kZXhTaXplKVxuICAgIH1cbiAgfVxuXG4gIHZhciBpXG4gIGlmIChkaXIpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA8IGFyckxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmVhZChhcnIsIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsTGVuZ3RoKSByZXR1cm4gZm91bmRJbmRleCAqIGluZGV4U2l6ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggIT09IC0xKSBpIC09IGkgLSBmb3VuZEluZGV4XG4gICAgICAgIGZvdW5kSW5kZXggPSAtMVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoYnl0ZU9mZnNldCArIHZhbExlbmd0aCA+IGFyckxlbmd0aCkgYnl0ZU9mZnNldCA9IGFyckxlbmd0aCAtIHZhbExlbmd0aFxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgZm91bmQgPSB0cnVlXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbExlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChyZWFkKGFyciwgaSArIGopICE9PSByZWFkKHZhbCwgaikpIHtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gaVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24gaW5jbHVkZXMgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSAhPT0gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgdHJ1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uIGxhc3RJbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGxhdGluMVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoIHwgMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIC8vIGxlZ2FjeSB3cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aCkgLSByZW1vdmUgaW4gdjAuMTNcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBsYXRpbjFTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAgIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgKytpKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmZmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gd3JpdGVVSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiB3cml0ZVVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgMik7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MzIgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDQpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlID4+PiAobGl0dGxlRW5kaWFuID8gaSA6IDMgLSBpKSAqIDgpICYgMHhmZlxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFID0gZnVuY3Rpb24gd3JpdGVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpIC0gMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpICsgMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5mdW5jdGlvbiB3cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDQsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gd3JpdGVGbG9hdEJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDgsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuICB2YXIgaVxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAoaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIGlmIChsZW4gPCAxMDAwIHx8ICFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIGFzY2VuZGluZyBjb3B5IGZyb20gc3RhcnRcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIFVzYWdlOlxuLy8gICAgYnVmZmVyLmZpbGwobnVtYmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChidWZmZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKHN0cmluZ1ssIG9mZnNldFssIGVuZF1dWywgZW5jb2RpbmddKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsLCBzdGFydCwgZW5kLCBlbmNvZGluZykge1xuICAvLyBIYW5kbGUgc3RyaW5nIGNhc2VzOlxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIHN0YXJ0ID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBzdGFydFxuICAgICAgc3RhcnQgPSAwXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVuZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gZW5kXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH1cbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIGNvZGUgPSB2YWwuY2hhckNvZGVBdCgwKVxuICAgICAgaWYgKGNvZGUgPCAyNTYpIHtcbiAgICAgICAgdmFsID0gY29kZVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDI1NVxuICB9XG5cbiAgLy8gSW52YWxpZCByYW5nZXMgYXJlIG5vdCBzZXQgdG8gYSBkZWZhdWx0LCBzbyBjYW4gcmFuZ2UgY2hlY2sgZWFybHkuXG4gIGlmIChzdGFydCA8IDAgfHwgdGhpcy5sZW5ndGggPCBzdGFydCB8fCB0aGlzLmxlbmd0aCA8IGVuZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBzdGFydCA9IHN0YXJ0ID4+PiAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gdGhpcy5sZW5ndGggOiBlbmQgPj4+IDBcblxuICBpZiAoIXZhbCkgdmFsID0gMFxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIHRoaXNbaV0gPSB2YWxcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gQnVmZmVyLmlzQnVmZmVyKHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IHV0ZjhUb0J5dGVzKG5ldyBCdWZmZXIodmFsLCBlbmNvZGluZykudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gaXNuYW4gKHZhbCkge1xuICByZXR1cm4gdmFsICE9PSB2YWwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbn1cbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG52YXIgaXNCdWZmZXJFbmNvZGluZyA9IEJ1ZmZlci5pc0VuY29kaW5nXG4gIHx8IGZ1bmN0aW9uKGVuY29kaW5nKSB7XG4gICAgICAgc3dpdGNoIChlbmNvZGluZyAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICBjYXNlICdoZXgnOiBjYXNlICd1dGY4JzogY2FzZSAndXRmLTgnOiBjYXNlICdhc2NpaSc6IGNhc2UgJ2JpbmFyeSc6IGNhc2UgJ2Jhc2U2NCc6IGNhc2UgJ3VjczInOiBjYXNlICd1Y3MtMic6IGNhc2UgJ3V0ZjE2bGUnOiBjYXNlICd1dGYtMTZsZSc6IGNhc2UgJ3Jhdyc6IHJldHVybiB0cnVlO1xuICAgICAgICAgZGVmYXVsdDogcmV0dXJuIGZhbHNlO1xuICAgICAgIH1cbiAgICAgfVxuXG5cbmZ1bmN0aW9uIGFzc2VydEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIGlmIChlbmNvZGluZyAmJiAhaXNCdWZmZXJFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIH1cbn1cblxuLy8gU3RyaW5nRGVjb2RlciBwcm92aWRlcyBhbiBpbnRlcmZhY2UgZm9yIGVmZmljaWVudGx5IHNwbGl0dGluZyBhIHNlcmllcyBvZlxuLy8gYnVmZmVycyBpbnRvIGEgc2VyaWVzIG9mIEpTIHN0cmluZ3Mgd2l0aG91dCBicmVha2luZyBhcGFydCBtdWx0aS1ieXRlXG4vLyBjaGFyYWN0ZXJzLiBDRVNVLTggaXMgaGFuZGxlZCBhcyBwYXJ0IG9mIHRoZSBVVEYtOCBlbmNvZGluZy5cbi8vXG4vLyBAVE9ETyBIYW5kbGluZyBhbGwgZW5jb2RpbmdzIGluc2lkZSBhIHNpbmdsZSBvYmplY3QgbWFrZXMgaXQgdmVyeSBkaWZmaWN1bHRcbi8vIHRvIHJlYXNvbiBhYm91dCB0aGlzIGNvZGUsIHNvIGl0IHNob3VsZCBiZSBzcGxpdCB1cCBpbiB0aGUgZnV0dXJlLlxuLy8gQFRPRE8gVGhlcmUgc2hvdWxkIGJlIGEgdXRmOC1zdHJpY3QgZW5jb2RpbmcgdGhhdCByZWplY3RzIGludmFsaWQgVVRGLTggY29kZVxuLy8gcG9pbnRzIGFzIHVzZWQgYnkgQ0VTVS04LlxudmFyIFN0cmluZ0RlY29kZXIgPSBleHBvcnRzLlN0cmluZ0RlY29kZXIgPSBmdW5jdGlvbihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV9dLywgJycpO1xuICBhc3NlcnRFbmNvZGluZyhlbmNvZGluZyk7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgLy8gQ0VTVS04IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAzLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAvLyBVVEYtMTYgcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDItYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDI7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAvLyBCYXNlLTY0IHN0b3JlcyAzIGJ5dGVzIGluIDQgY2hhcnMsIGFuZCBwYWRzIHRoZSByZW1haW5kZXIuXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBwYXNzVGhyb3VnaFdyaXRlO1xuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRW5vdWdoIHNwYWNlIHRvIHN0b3JlIGFsbCBieXRlcyBvZiBhIHNpbmdsZSBjaGFyYWN0ZXIuIFVURi04IG5lZWRzIDRcbiAgLy8gYnl0ZXMsIGJ1dCBDRVNVLTggbWF5IHJlcXVpcmUgdXAgdG8gNiAoMyBieXRlcyBwZXIgc3Vycm9nYXRlKS5cbiAgdGhpcy5jaGFyQnVmZmVyID0gbmV3IEJ1ZmZlcig2KTtcbiAgLy8gTnVtYmVyIG9mIGJ5dGVzIHJlY2VpdmVkIGZvciB0aGUgY3VycmVudCBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgY2hhcmFjdGVyLlxuICB0aGlzLmNoYXJSZWNlaXZlZCA9IDA7XG4gIC8vIE51bWJlciBvZiBieXRlcyBleHBlY3RlZCBmb3IgdGhlIGN1cnJlbnQgaW5jb21wbGV0ZSBtdWx0aS1ieXRlIGNoYXJhY3Rlci5cbiAgdGhpcy5jaGFyTGVuZ3RoID0gMDtcbn07XG5cblxuLy8gd3JpdGUgZGVjb2RlcyB0aGUgZ2l2ZW4gYnVmZmVyIGFuZCByZXR1cm5zIGl0IGFzIEpTIHN0cmluZyB0aGF0IGlzXG4vLyBndWFyYW50ZWVkIHRvIG5vdCBjb250YWluIGFueSBwYXJ0aWFsIG11bHRpLWJ5dGUgY2hhcmFjdGVycy4gQW55IHBhcnRpYWxcbi8vIGNoYXJhY3RlciBmb3VuZCBhdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIgaXMgYnVmZmVyZWQgdXAsIGFuZCB3aWxsIGJlXG4vLyByZXR1cm5lZCB3aGVuIGNhbGxpbmcgd3JpdGUgYWdhaW4gd2l0aCB0aGUgcmVtYWluaW5nIGJ5dGVzLlxuLy9cbi8vIE5vdGU6IENvbnZlcnRpbmcgYSBCdWZmZXIgY29udGFpbmluZyBhbiBvcnBoYW4gc3Vycm9nYXRlIHRvIGEgU3RyaW5nXG4vLyBjdXJyZW50bHkgd29ya3MsIGJ1dCBjb252ZXJ0aW5nIGEgU3RyaW5nIHRvIGEgQnVmZmVyICh2aWEgYG5ldyBCdWZmZXJgLCBvclxuLy8gQnVmZmVyI3dyaXRlKSB3aWxsIHJlcGxhY2UgaW5jb21wbGV0ZSBzdXJyb2dhdGVzIHdpdGggdGhlIHVuaWNvZGVcbi8vIHJlcGxhY2VtZW50IGNoYXJhY3Rlci4gU2VlIGh0dHBzOi8vY29kZXJldmlldy5jaHJvbWl1bS5vcmcvMTIxMTczMDA5LyAuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgY2hhclN0ciA9ICcnO1xuICAvLyBpZiBvdXIgbGFzdCB3cml0ZSBlbmRlZCB3aXRoIGFuIGluY29tcGxldGUgbXVsdGlieXRlIGNoYXJhY3RlclxuICB3aGlsZSAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IHJlbWFpbmluZyBieXRlcyB0aGlzIGJ1ZmZlciBoYXMgdG8gb2ZmZXIgZm9yIHRoaXMgY2hhclxuICAgIHZhciBhdmFpbGFibGUgPSAoYnVmZmVyLmxlbmd0aCA+PSB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCkgP1xuICAgICAgICB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCA6XG4gICAgICAgIGJ1ZmZlci5sZW5ndGg7XG5cbiAgICAvLyBhZGQgdGhlIG5ldyBieXRlcyB0byB0aGUgY2hhciBidWZmZXJcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIHRoaXMuY2hhclJlY2VpdmVkLCAwLCBhdmFpbGFibGUpO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IGF2YWlsYWJsZTtcblxuICAgIGlmICh0aGlzLmNoYXJSZWNlaXZlZCA8IHRoaXMuY2hhckxlbmd0aCkge1xuICAgICAgLy8gc3RpbGwgbm90IGVub3VnaCBjaGFycyBpbiB0aGlzIGJ1ZmZlcj8gd2FpdCBmb3IgbW9yZSAuLi5cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICAvLyByZW1vdmUgYnl0ZXMgYmVsb25naW5nIHRvIHRoZSBjdXJyZW50IGNoYXJhY3RlciBmcm9tIHRoZSBidWZmZXJcbiAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UoYXZhaWxhYmxlLCBidWZmZXIubGVuZ3RoKTtcblxuICAgIC8vIGdldCB0aGUgY2hhcmFjdGVyIHRoYXQgd2FzIHNwbGl0XG4gICAgY2hhclN0ciA9IHRoaXMuY2hhckJ1ZmZlci5zbGljZSgwLCB0aGlzLmNoYXJMZW5ndGgpLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xuXG4gICAgLy8gQ0VTVS04OiBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICAgIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aCAtIDEpO1xuICAgIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggKz0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgICAgY2hhclN0ciA9ICcnO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHRoaXMuY2hhclJlY2VpdmVkID0gdGhpcy5jaGFyTGVuZ3RoID0gMDtcblxuICAgIC8vIGlmIHRoZXJlIGFyZSBubyBtb3JlIGJ5dGVzIGluIHRoaXMgYnVmZmVyLCBqdXN0IGVtaXQgb3VyIGNoYXJcbiAgICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNoYXJTdHI7XG4gICAgfVxuICAgIGJyZWFrO1xuICB9XG5cbiAgLy8gZGV0ZXJtaW5lIGFuZCBzZXQgY2hhckxlbmd0aCAvIGNoYXJSZWNlaXZlZFxuICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcik7XG5cbiAgdmFyIGVuZCA9IGJ1ZmZlci5sZW5ndGg7XG4gIGlmICh0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAvLyBidWZmZXIgdGhlIGluY29tcGxldGUgY2hhcmFjdGVyIGJ5dGVzIHdlIGdvdFxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkLCBlbmQpO1xuICAgIGVuZCAtPSB0aGlzLmNoYXJSZWNlaXZlZDtcbiAgfVxuXG4gIGNoYXJTdHIgKz0gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIGVuZCk7XG5cbiAgdmFyIGVuZCA9IGNoYXJTdHIubGVuZ3RoIC0gMTtcbiAgdmFyIGNoYXJDb2RlID0gY2hhclN0ci5jaGFyQ29kZUF0KGVuZCk7XG4gIC8vIENFU1UtODogbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgaWYgKGNoYXJDb2RlID49IDB4RDgwMCAmJiBjaGFyQ29kZSA8PSAweERCRkYpIHtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICB0aGlzLmNoYXJMZW5ndGggKz0gc2l6ZTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCArPSBzaXplO1xuICAgIHRoaXMuY2hhckJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgc2l6ZSwgMCwgc2l6ZSk7XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCAwLCBzaXplKTtcbiAgICByZXR1cm4gY2hhclN0ci5zdWJzdHJpbmcoMCwgZW5kKTtcbiAgfVxuXG4gIC8vIG9yIGp1c3QgZW1pdCB0aGUgY2hhclN0clxuICByZXR1cm4gY2hhclN0cjtcbn07XG5cbi8vIGRldGVjdEluY29tcGxldGVDaGFyIGRldGVybWluZXMgaWYgdGhlcmUgaXMgYW4gaW5jb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXIgYXRcbi8vIHRoZSBlbmQgb2YgdGhlIGdpdmVuIGJ1ZmZlci4gSWYgc28sIGl0IHNldHMgdGhpcy5jaGFyTGVuZ3RoIHRvIHRoZSBieXRlXG4vLyBsZW5ndGggdGhhdCBjaGFyYWN0ZXIsIGFuZCBzZXRzIHRoaXMuY2hhclJlY2VpdmVkIHRvIHRoZSBudW1iZXIgb2YgYnl0ZXNcbi8vIHRoYXQgYXJlIGF2YWlsYWJsZSBmb3IgdGhpcyBjaGFyYWN0ZXIuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgYnl0ZXMgd2UgaGF2ZSB0byBjaGVjayBhdCB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyXG4gIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gMykgPyAzIDogYnVmZmVyLmxlbmd0aDtcblxuICAvLyBGaWd1cmUgb3V0IGlmIG9uZSBvZiB0aGUgbGFzdCBpIGJ5dGVzIG9mIG91ciBidWZmZXIgYW5ub3VuY2VzIGFuXG4gIC8vIGluY29tcGxldGUgY2hhci5cbiAgZm9yICg7IGkgPiAwOyBpLS0pIHtcbiAgICB2YXIgYyA9IGJ1ZmZlcltidWZmZXIubGVuZ3RoIC0gaV07XG5cbiAgICAvLyBTZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VVEYtOCNEZXNjcmlwdGlvblxuXG4gICAgLy8gMTEwWFhYWFhcbiAgICBpZiAoaSA9PSAxICYmIGMgPj4gNSA9PSAweDA2KSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAyO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMFhYWFhcbiAgICBpZiAoaSA8PSAyICYmIGMgPj4gNCA9PSAweDBFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAzO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMTBYWFhcbiAgICBpZiAoaSA8PSAzICYmIGMgPj4gMyA9PSAweDFFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSA0O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gaTtcbn07XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgcmVzID0gJyc7XG4gIGlmIChidWZmZXIgJiYgYnVmZmVyLmxlbmd0aClcbiAgICByZXMgPSB0aGlzLndyaXRlKGJ1ZmZlcik7XG5cbiAgaWYgKHRoaXMuY2hhclJlY2VpdmVkKSB7XG4gICAgdmFyIGNyID0gdGhpcy5jaGFyUmVjZWl2ZWQ7XG4gICAgdmFyIGJ1ZiA9IHRoaXMuY2hhckJ1ZmZlcjtcbiAgICB2YXIgZW5jID0gdGhpcy5lbmNvZGluZztcbiAgICByZXMgKz0gYnVmLnNsaWNlKDAsIGNyKS50b1N0cmluZyhlbmMpO1xuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG5cbmZ1bmN0aW9uIHBhc3NUaHJvdWdoV3JpdGUoYnVmZmVyKSB7XG4gIHJldHVybiBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG59XG5cbmZ1bmN0aW9uIHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKSB7XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDI7XG4gIHRoaXMuY2hhckxlbmd0aCA9IHRoaXMuY2hhclJlY2VpdmVkID8gMiA6IDA7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAzO1xuICB0aGlzLmNoYXJMZW5ndGggPSB0aGlzLmNoYXJSZWNlaXZlZCA/IDMgOiAwO1xufVxuIiwidmFyIGJhc2V4ID0gcmVxdWlyZSgnYmFzZS14JylcbnZhciBBTFBIQUJFVCA9ICcxMjM0NTY3ODlBQkNERUZHSEpLTE1OUFFSU1RVVldYWVphYmNkZWZnaGlqa21ub3BxcnN0dXZ3eHl6J1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2V4KEFMUEhBQkVUKVxuIiwiLypcclxuIENvcHlyaWdodCAyMDEzLTIwMTQgRGFuaWVsIFdpcnR6IDxkY29kZUBkY29kZS5pbz5cclxuXHJcbiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xyXG4geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxyXG4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XHJcblxyXG4gaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXHJcblxyXG4gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxyXG4gZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxyXG4gV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXHJcbiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXHJcbiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cclxuICovXHJcblxyXG4vKipcclxuICogQGxpY2Vuc2UgYnl0ZWJ1ZmZlci5qcyAoYykgMjAxNSBEYW5pZWwgV2lydHogPGRjb2RlQGRjb2RlLmlvPlxyXG4gKiBCYWNraW5nIGJ1ZmZlcjogQXJyYXlCdWZmZXIsIEFjY2Vzc29yOiBVaW50OEFycmF5XHJcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjBcclxuICogc2VlOiBodHRwczovL2dpdGh1Yi5jb20vZGNvZGVJTy9ieXRlYnVmZmVyLmpzIGZvciBkZXRhaWxzXHJcbiAqL1xyXG4oZnVuY3Rpb24oZ2xvYmFsLCBmYWN0b3J5KSB7XHJcblxyXG4gICAgLyogQU1EICovIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZVtcImFtZFwiXSlcclxuICAgICAgICBkZWZpbmUoW1wibG9uZ1wiXSwgZmFjdG9yeSk7XHJcbiAgICAvKiBDb21tb25KUyAqLyBlbHNlIGlmICh0eXBlb2YgcmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIG1vZHVsZSAmJiBtb2R1bGVbXCJleHBvcnRzXCJdKVxyXG4gICAgICAgIG1vZHVsZVsnZXhwb3J0cyddID0gKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICB2YXIgTG9uZzsgdHJ5IHsgTG9uZyA9IHJlcXVpcmUoXCJsb25nXCIpOyB9IGNhdGNoIChlKSB7fVxyXG4gICAgICAgICAgICByZXR1cm4gZmFjdG9yeShMb25nKTtcclxuICAgICAgICB9KSgpO1xyXG4gICAgLyogR2xvYmFsICovIGVsc2VcclxuICAgICAgICAoZ2xvYmFsW1wiZGNvZGVJT1wiXSA9IGdsb2JhbFtcImRjb2RlSU9cIl0gfHwge30pW1wiQnl0ZUJ1ZmZlclwiXSA9IGZhY3RvcnkoZ2xvYmFsW1wiZGNvZGVJT1wiXVtcIkxvbmdcIl0pO1xyXG5cclxufSkodGhpcywgZnVuY3Rpb24oTG9uZykge1xyXG4gICAgXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEJ5dGVCdWZmZXIuXHJcbiAgICAgKiBAY2xhc3MgVGhlIHN3aXNzIGFybXkga25pZmUgZm9yIGJpbmFyeSBkYXRhIGluIEphdmFTY3JpcHQuXHJcbiAgICAgKiBAZXhwb3J0cyBCeXRlQnVmZmVyXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gY2FwYWNpdHkgSW5pdGlhbCBjYXBhY2l0eS4gRGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9DQVBBQ0lUWX0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0Fzc2VydCBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVH0uXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIHZhciBCeXRlQnVmZmVyID0gZnVuY3Rpb24oY2FwYWNpdHksIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGNhcGFjaXR5ID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgY2FwYWNpdHkgPSBCeXRlQnVmZmVyLkRFRkFVTFRfQ0FQQUNJVFk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOO1xyXG4gICAgICAgIGlmICh0eXBlb2Ygbm9Bc3NlcnQgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICBub0Fzc2VydCA9IEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVDtcclxuICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGNhcGFjaXR5ID0gY2FwYWNpdHkgfCAwO1xyXG4gICAgICAgICAgICBpZiAoY2FwYWNpdHkgPCAwKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgY2FwYWNpdHlcIik7XHJcbiAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9ICEhbGl0dGxlRW5kaWFuO1xyXG4gICAgICAgICAgICBub0Fzc2VydCA9ICEhbm9Bc3NlcnQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBCYWNraW5nIEFycmF5QnVmZmVyLlxyXG4gICAgICAgICAqIEB0eXBlIHshQXJyYXlCdWZmZXJ9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuYnVmZmVyID0gY2FwYWNpdHkgPT09IDAgPyBFTVBUWV9CVUZGRVIgOiBuZXcgQXJyYXlCdWZmZXIoY2FwYWNpdHkpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBVaW50OEFycmF5IHV0aWxpemVkIHRvIG1hbmlwdWxhdGUgdGhlIGJhY2tpbmcgYnVmZmVyLiBCZWNvbWVzIGBudWxsYCBpZiB0aGUgYmFja2luZyBidWZmZXIgaGFzIGEgY2FwYWNpdHkgb2YgYDBgLlxyXG4gICAgICAgICAqIEB0eXBlIHs/VWludDhBcnJheX1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy52aWV3ID0gY2FwYWNpdHkgPT09IDAgPyBudWxsIDogbmV3IFVpbnQ4QXJyYXkodGhpcy5idWZmZXIpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBBYnNvbHV0ZSByZWFkL3dyaXRlIG9mZnNldC5cclxuICAgICAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjZmxpcFxyXG4gICAgICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNjbGVhclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gMDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTWFya2VkIG9mZnNldC5cclxuICAgICAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjbWFya1xyXG4gICAgICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNyZXNldFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMubWFya2VkT2Zmc2V0ID0gLTE7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEFic29sdXRlIGxpbWl0IG9mIHRoZSBjb250YWluZWQgZGF0YS4gU2V0IHRvIHRoZSBiYWNraW5nIGJ1ZmZlcidzIGNhcGFjaXR5IHVwb24gYWxsb2NhdGlvbi5cclxuICAgICAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjZmxpcFxyXG4gICAgICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNjbGVhclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMubGltaXQgPSBjYXBhY2l0eTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV2hldGhlciB0byB1c2UgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLCBkZWZhdWx0cyB0byBgZmFsc2VgIGZvciBiaWcgZW5kaWFuLlxyXG4gICAgICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmxpdHRsZUVuZGlhbiA9IGxpdHRsZUVuZGlhbjtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV2hldGhlciB0byBza2lwIGFzc2VydGlvbnMgb2Ygb2Zmc2V0cyBhbmQgdmFsdWVzLCBkZWZhdWx0cyB0byBgZmFsc2VgLlxyXG4gICAgICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLm5vQXNzZXJ0ID0gbm9Bc3NlcnQ7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQnl0ZUJ1ZmZlciB2ZXJzaW9uLlxyXG4gICAgICogQHR5cGUge3N0cmluZ31cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLlZFUlNJT04gPSBcIjUuMC4xXCI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMaXR0bGUgZW5kaWFuIGNvbnN0YW50IHRoYXQgY2FuIGJlIHVzZWQgaW5zdGVhZCBvZiBpdHMgYm9vbGVhbiB2YWx1ZS4gRXZhbHVhdGVzIHRvIGB0cnVlYC5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuTElUVExFX0VORElBTiA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBCaWcgZW5kaWFuIGNvbnN0YW50IHRoYXQgY2FuIGJlIHVzZWQgaW5zdGVhZCBvZiBpdHMgYm9vbGVhbiB2YWx1ZS4gRXZhbHVhdGVzIHRvIGBmYWxzZWAuXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkJJR19FTkRJQU4gPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmF1bHQgaW5pdGlhbCBjYXBhY2l0eSBvZiBgMTZgLlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZID0gMTY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZhdWx0IGVuZGlhbmVzcyBvZiBgZmFsc2VgIGZvciBiaWcgZW5kaWFuLlxyXG4gICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU4gPSBCeXRlQnVmZmVyLkJJR19FTkRJQU47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWZhdWx0IG5vIGFzc2VydGlvbnMgZmxhZyBvZiBgZmFsc2VgLlxyXG4gICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBgTG9uZ2AgY2xhc3MgZm9yIHJlcHJlc2VudGluZyBhIDY0LWJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIgdmFsdWUuIE1heSBiZSBgbnVsbGAgaWYgTG9uZy5qcyBoYXMgbm90IGJlZW4gbG9hZGVkXHJcbiAgICAgKiAgYW5kIGludDY0IHN1cHBvcnQgaXMgbm90IGF2YWlsYWJsZS5cclxuICAgICAqIEB0eXBlIHs/TG9uZ31cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vZGNvZGVJTy9sb25nLmpzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuTG9uZyA9IExvbmcgfHwgbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBhbGlhcyBCeXRlQnVmZmVyLnByb3RvdHlwZVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBCeXRlQnVmZmVyUHJvdG90eXBlID0gQnl0ZUJ1ZmZlci5wcm90b3R5cGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbiBpbmRpY2F0b3IgdXNlZCB0byByZWxpYWJseSBkZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGlzIGEgQnl0ZUJ1ZmZlciBvciBub3QuXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5fX2lzQnl0ZUJ1ZmZlcl9fO1xyXG5cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCeXRlQnVmZmVyUHJvdG90eXBlLCBcIl9faXNCeXRlQnVmZmVyX19cIiwge1xyXG4gICAgICAgIHZhbHVlOiB0cnVlLFxyXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2VcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIGhlbHBlcnNcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshQXJyYXlCdWZmZXJ9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIEVNUFRZX0JVRkZFUiA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFN0cmluZy5mcm9tQ2hhckNvZGUgcmVmZXJlbmNlIGZvciBjb21waWxlLXRpbWUgcmVuYW1pbmcuXHJcbiAgICAgKiBAdHlwZSB7ZnVuY3Rpb24oLi4ubnVtYmVyKTpzdHJpbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIHN0cmluZ0Zyb21DaGFyQ29kZSA9IFN0cmluZy5mcm9tQ2hhckNvZGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgc291cmNlIGZ1bmN0aW9uIGZvciBhIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzIFN0cmluZyB0byByZWFkIGZyb21cclxuICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbigpOm51bWJlcnxudWxsfSBTb3VyY2UgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGNoYXIgY29kZSByZXNwZWN0aXZlbHkgYG51bGxgIGlmIHRoZXJlIGFyZVxyXG4gICAgICogIG5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0LlxyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiB0aGUgYXJndW1lbnQgaXMgaW52YWxpZFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHN0cmluZ1NvdXJjZShzKSB7XHJcbiAgICAgICAgdmFyIGk9MDsgcmV0dXJuIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gaSA8IHMubGVuZ3RoID8gcy5jaGFyQ29kZUF0KGkrKykgOiBudWxsO1xyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgZGVzdGluYXRpb24gZnVuY3Rpb24gZm9yIGEgc3RyaW5nLlxyXG4gICAgICogQHJldHVybnMge2Z1bmN0aW9uKG51bWJlcj0pOnVuZGVmaW5lZHxzdHJpbmd9IERlc3RpbmF0aW9uIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCB0aGUgbmV4dCBjaGFyIGNvZGUuXHJcbiAgICAgKiAgUmV0dXJucyB0aGUgZmluYWwgc3RyaW5nIHdoZW4gY2FsbGVkIHdpdGhvdXQgYXJndW1lbnRzLlxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHN0cmluZ0Rlc3RpbmF0aW9uKCkge1xyXG4gICAgICAgIHZhciBjcyA9IFtdLCBwcyA9IFtdOyByZXR1cm4gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBzLmpvaW4oJycpK3N0cmluZ0Zyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNzKTtcclxuICAgICAgICAgICAgaWYgKGNzLmxlbmd0aCArIGFyZ3VtZW50cy5sZW5ndGggPiAxMDI0KVxyXG4gICAgICAgICAgICAgICAgcHMucHVzaChzdHJpbmdGcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjcykpLFxyXG4gICAgICAgICAgICAgICAgICAgIGNzLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGNzLCBhcmd1bWVudHMpO1xyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBhY2Nlc3NvciB0eXBlLlxyXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBgQnVmZmVyYCB1bmRlciBub2RlLmpzLCBgVWludDhBcnJheWAgcmVzcGVjdGl2ZWx5IGBEYXRhVmlld2AgaW4gdGhlIGJyb3dzZXIgKGNsYXNzZXMpXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuYWNjZXNzb3IgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gVWludDhBcnJheTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEFsbG9jYXRlcyBhIG5ldyBCeXRlQnVmZmVyIGJhY2tlZCBieSBhIGJ1ZmZlciBvZiB0aGUgc3BlY2lmaWVkIGNhcGFjaXR5LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBjYXBhY2l0eSBJbml0aWFsIGNhcGFjaXR5LiBEZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcy4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5hbGxvY2F0ZSA9IGZ1bmN0aW9uKGNhcGFjaXR5LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBCeXRlQnVmZmVyKGNhcGFjaXR5LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb25jYXRlbmF0ZXMgbXVsdGlwbGUgQnl0ZUJ1ZmZlcnMgaW50byBvbmUuXHJcbiAgICAgKiBAcGFyYW0geyFBcnJheS48IUJ5dGVCdWZmZXJ8IUFycmF5QnVmZmVyfCFVaW50OEFycmF5fHN0cmluZz59IGJ1ZmZlcnMgQnVmZmVycyB0byBjb25jYXRlbmF0ZVxyXG4gICAgICogQHBhcmFtIHsoc3RyaW5nfGJvb2xlYW4pPX0gZW5jb2RpbmcgU3RyaW5nIGVuY29kaW5nIGlmIGBidWZmZXJzYCBjb250YWlucyBhIHN0cmluZyAoXCJiYXNlNjRcIiwgXCJoZXhcIiwgXCJiaW5hcnlcIixcclxuICAgICAqICBkZWZhdWx0cyB0byBcInV0ZjhcIilcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyIGZvciB0aGUgcmVzdWx0aW5nIEJ5dGVCdWZmZXIuIERlZmF1bHRzXHJcbiAgICAgKiAgdG8ge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbm9Bc3NlcnQgV2hldGhlciB0byBza2lwIGFzc2VydGlvbnMgb2Ygb2Zmc2V0cyBhbmQgdmFsdWVzIGZvciB0aGUgcmVzdWx0aW5nIEJ5dGVCdWZmZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IENvbmNhdGVuYXRlZCBCeXRlQnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24oYnVmZmVycywgZW5jb2RpbmcsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnYm9vbGVhbicgfHwgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBub0Fzc2VydCA9IGxpdHRsZUVuZGlhbjtcclxuICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gZW5jb2Rpbmc7XHJcbiAgICAgICAgICAgIGVuY29kaW5nID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgY2FwYWNpdHkgPSAwO1xyXG4gICAgICAgIGZvciAodmFyIGk9MCwgaz1idWZmZXJzLmxlbmd0aCwgbGVuZ3RoOyBpPGs7ICsraSkge1xyXG4gICAgICAgICAgICBpZiAoIUJ5dGVCdWZmZXIuaXNCeXRlQnVmZmVyKGJ1ZmZlcnNbaV0pKVxyXG4gICAgICAgICAgICAgICAgYnVmZmVyc1tpXSA9IEJ5dGVCdWZmZXIud3JhcChidWZmZXJzW2ldLCBlbmNvZGluZyk7XHJcbiAgICAgICAgICAgIGxlbmd0aCA9IGJ1ZmZlcnNbaV0ubGltaXQgLSBidWZmZXJzW2ldLm9mZnNldDtcclxuICAgICAgICAgICAgaWYgKGxlbmd0aCA+IDApIGNhcGFjaXR5ICs9IGxlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNhcGFjaXR5ID09PSAwKVxyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ5dGVCdWZmZXIoMCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCk7XHJcbiAgICAgICAgdmFyIGJiID0gbmV3IEJ5dGVCdWZmZXIoY2FwYWNpdHksIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpLFxyXG4gICAgICAgICAgICBiaTtcclxuICAgICAgICBpPTA7IHdoaWxlIChpPGspIHtcclxuICAgICAgICAgICAgYmkgPSBidWZmZXJzW2krK107XHJcbiAgICAgICAgICAgIGxlbmd0aCA9IGJpLmxpbWl0IC0gYmkub2Zmc2V0O1xyXG4gICAgICAgICAgICBpZiAobGVuZ3RoIDw9IDApIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBiYi52aWV3LnNldChiaS52aWV3LnN1YmFycmF5KGJpLm9mZnNldCwgYmkubGltaXQpLCBiYi5vZmZzZXQpO1xyXG4gICAgICAgICAgICBiYi5vZmZzZXQgKz0gbGVuZ3RoO1xyXG4gICAgICAgIH1cclxuICAgICAgICBiYi5saW1pdCA9IGJiLm9mZnNldDtcclxuICAgICAgICBiYi5vZmZzZXQgPSAwO1xyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIHR5cGUgaXMgYSBCeXRlQnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHsqfSBiYiBCeXRlQnVmZmVyIHRvIHRlc3RcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgaXQgaXMgYSBCeXRlQnVmZmVyLCBvdGhlcndpc2UgYGZhbHNlYFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmlzQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGJiKSB7XHJcbiAgICAgICAgcmV0dXJuIChiYiAmJiBiYltcIl9faXNCeXRlQnVmZmVyX19cIl0pID09PSB0cnVlO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgYmFja2luZyBidWZmZXIgdHlwZS5cclxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gYEJ1ZmZlcmAgdW5kZXIgbm9kZS5qcywgYEFycmF5QnVmZmVyYCBpbiB0aGUgYnJvd3NlciAoY2xhc3NlcylcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci50eXBlID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIEFycmF5QnVmZmVyO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogV3JhcHMgYSBidWZmZXIgb3IgYSBzdHJpbmcuIFNldHMgdGhlIGFsbG9jYXRlZCBCeXRlQnVmZmVyJ3Mge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSB0byBgMGAgYW5kIGl0c1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fSB0byB0aGUgbGVuZ3RoIG9mIHRoZSB3cmFwcGVkIGRhdGEuXHJcbiAgICAgKiBAcGFyYW0geyFCeXRlQnVmZmVyfCFBcnJheUJ1ZmZlcnwhVWludDhBcnJheXxzdHJpbmd8IUFycmF5LjxudW1iZXI+fSBidWZmZXIgQW55dGhpbmcgdGhhdCBjYW4gYmUgd3JhcHBlZFxyXG4gICAgICogQHBhcmFtIHsoc3RyaW5nfGJvb2xlYW4pPX0gZW5jb2RpbmcgU3RyaW5nIGVuY29kaW5nIGlmIGBidWZmZXJgIGlzIGEgc3RyaW5nIChcImJhc2U2NFwiLCBcImhleFwiLCBcImJpbmFyeVwiLCBkZWZhdWx0cyB0b1xyXG4gICAgICogIFwidXRmOFwiKVxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbm9Bc3NlcnQgV2hldGhlciB0byBza2lwIGFzc2VydGlvbnMgb2Ygb2Zmc2V0cyBhbmQgdmFsdWVzLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBBIEJ5dGVCdWZmZXIgd3JhcHBpbmcgYGJ1ZmZlcmBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci53cmFwID0gZnVuY3Rpb24oYnVmZmVyLCBlbmNvZGluZywgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIG5vQXNzZXJ0ID0gbGl0dGxlRW5kaWFuO1xyXG4gICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSBlbmNvZGluZztcclxuICAgICAgICAgICAgZW5jb2RpbmcgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlb2YgYnVmZmVyID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgICAgIGVuY29kaW5nID0gXCJ1dGY4XCI7XHJcbiAgICAgICAgICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgXCJiYXNlNjRcIjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnl0ZUJ1ZmZlci5mcm9tQmFzZTY0KGJ1ZmZlciwgbGl0dGxlRW5kaWFuKTtcclxuICAgICAgICAgICAgICAgIGNhc2UgXCJoZXhcIjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnl0ZUJ1ZmZlci5mcm9tSGV4KGJ1ZmZlciwgbGl0dGxlRW5kaWFuKTtcclxuICAgICAgICAgICAgICAgIGNhc2UgXCJiaW5hcnlcIjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnl0ZUJ1ZmZlci5mcm9tQmluYXJ5KGJ1ZmZlciwgbGl0dGxlRW5kaWFuKTtcclxuICAgICAgICAgICAgICAgIGNhc2UgXCJ1dGY4XCI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbVVURjgoYnVmZmVyLCBsaXR0bGVFbmRpYW4pO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBcImRlYnVnXCI6XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbURlYnVnKGJ1ZmZlciwgbGl0dGxlRW5kaWFuKTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJVbnN1cHBvcnRlZCBlbmNvZGluZzogXCIrZW5jb2RpbmcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChidWZmZXIgPT09IG51bGwgfHwgdHlwZW9mIGJ1ZmZlciAhPT0gJ29iamVjdCcpXHJcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYnVmZmVyXCIpO1xyXG4gICAgICAgIHZhciBiYjtcclxuICAgICAgICBpZiAoQnl0ZUJ1ZmZlci5pc0J5dGVCdWZmZXIoYnVmZmVyKSkge1xyXG4gICAgICAgICAgICBiYiA9IEJ5dGVCdWZmZXJQcm90b3R5cGUuY2xvbmUuY2FsbChidWZmZXIpO1xyXG4gICAgICAgICAgICBiYi5tYXJrZWRPZmZzZXQgPSAtMTtcclxuICAgICAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYnVmZmVyIGluc3RhbmNlb2YgVWludDhBcnJheSkgeyAvLyBFeHRyYWN0IEFycmF5QnVmZmVyIGZyb20gVWludDhBcnJheVxyXG4gICAgICAgICAgICBiYiA9IG5ldyBCeXRlQnVmZmVyKDAsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpO1xyXG4gICAgICAgICAgICBpZiAoYnVmZmVyLmxlbmd0aCA+IDApIHsgLy8gQXZvaWQgcmVmZXJlbmNlcyB0byBtb3JlIHRoYW4gb25lIEVNUFRZX0JVRkZFUlxyXG4gICAgICAgICAgICAgICAgYmIuYnVmZmVyID0gYnVmZmVyLmJ1ZmZlcjtcclxuICAgICAgICAgICAgICAgIGJiLm9mZnNldCA9IGJ1ZmZlci5ieXRlT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgYmIubGltaXQgPSBidWZmZXIuYnl0ZU9mZnNldCArIGJ1ZmZlci5ieXRlTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgYmIudmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlci5idWZmZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChidWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgeyAvLyBSZXVzZSBBcnJheUJ1ZmZlclxyXG4gICAgICAgICAgICBiYiA9IG5ldyBCeXRlQnVmZmVyKDAsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpO1xyXG4gICAgICAgICAgICBpZiAoYnVmZmVyLmJ5dGVMZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICBiYi5idWZmZXIgPSBidWZmZXI7XHJcbiAgICAgICAgICAgICAgICBiYi5vZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICAgICAgYmIubGltaXQgPSBidWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgICAgICAgICAgICAgIGJiLnZpZXcgPSBidWZmZXIuYnl0ZUxlbmd0aCA+IDAgPyBuZXcgVWludDhBcnJheShidWZmZXIpIDogbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGJ1ZmZlcikgPT09IFwiW29iamVjdCBBcnJheV1cIikgeyAvLyBDcmVhdGUgZnJvbSBvY3RldHNcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcihidWZmZXIubGVuZ3RoLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KTtcclxuICAgICAgICAgICAgYmIubGltaXQgPSBidWZmZXIubGVuZ3RoO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpPTA7IGk8YnVmZmVyLmxlbmd0aDsgKytpKVxyXG4gICAgICAgICAgICAgICAgYmIudmlld1tpXSA9IGJ1ZmZlcltpXTtcclxuICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBidWZmZXJcIik7IC8vIE90aGVyd2lzZSBmYWlsXHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyB0aGUgYXJyYXkgYXMgYSBiaXRzZXQuXHJcbiAgICAgKiBAcGFyYW0ge0FycmF5PGJvb2xlYW4+fSB2YWx1ZSBBcnJheSBvZiBib29sZWFucyB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYGxlbmd0aGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUJpdFNldCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBBcnJheSkpXHJcbiAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIEJpdFNldDogTm90IGFuIGFycmF5XCIpO1xyXG4gICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBzdGFydCA9IG9mZnNldCxcclxuICAgICAgICAgIGJpdHMgPSB2YWx1ZS5sZW5ndGgsXHJcbiAgICAgICAgICBieXRlcyA9IChiaXRzID4+IDMpLFxyXG4gICAgICAgICAgYml0ID0gMCxcclxuICAgICAgICAgIGs7XHJcblxyXG4gICAgICBvZmZzZXQgKz0gdGhpcy53cml0ZVZhcmludDMyKGJpdHMsb2Zmc2V0KTtcclxuXHJcbiAgICAgIHdoaWxlKGJ5dGVzLS0pIHtcclxuICAgICAgICBrID0gKCEhdmFsdWVbYml0KytdICYgMSkgfFxyXG4gICAgICAgICAgICAoKCEhdmFsdWVbYml0KytdICYgMSkgPDwgMSkgfFxyXG4gICAgICAgICAgICAoKCEhdmFsdWVbYml0KytdICYgMSkgPDwgMikgfFxyXG4gICAgICAgICAgICAoKCEhdmFsdWVbYml0KytdICYgMSkgPDwgMykgfFxyXG4gICAgICAgICAgICAoKCEhdmFsdWVbYml0KytdICYgMSkgPDwgNCkgfFxyXG4gICAgICAgICAgICAoKCEhdmFsdWVbYml0KytdICYgMSkgPDwgNSkgfFxyXG4gICAgICAgICAgICAoKCEhdmFsdWVbYml0KytdICYgMSkgPDwgNikgfFxyXG4gICAgICAgICAgICAoKCEhdmFsdWVbYml0KytdICYgMSkgPDwgNyk7XHJcbiAgICAgICAgdGhpcy53cml0ZUJ5dGUoayxvZmZzZXQrKyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmKGJpdCA8IGJpdHMpIHtcclxuICAgICAgICB2YXIgbSA9IDA7IGsgPSAwO1xyXG4gICAgICAgIHdoaWxlKGJpdCA8IGJpdHMpIGsgPSBrIHwgKCghIXZhbHVlW2JpdCsrXSAmIDEpIDw8IChtKyspKTtcclxuICAgICAgICB0aGlzLndyaXRlQnl0ZShrLG9mZnNldCsrKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSBCaXRTZXQgYXMgYW4gYXJyYXkgb2YgYm9vbGVhbnMuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgbGVuZ3RoYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge0FycmF5PGJvb2xlYW4+XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEJpdFNldCA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG5cclxuICAgICAgdmFyIHJldCA9IHRoaXMucmVhZFZhcmludDMyKG9mZnNldCksXHJcbiAgICAgICAgICBiaXRzID0gcmV0LnZhbHVlLFxyXG4gICAgICAgICAgYnl0ZXMgPSAoYml0cyA+PiAzKSxcclxuICAgICAgICAgIGJpdCA9IDAsXHJcbiAgICAgICAgICB2YWx1ZSA9IFtdLFxyXG4gICAgICAgICAgaztcclxuXHJcbiAgICAgIG9mZnNldCArPSByZXQubGVuZ3RoO1xyXG5cclxuICAgICAgd2hpbGUoYnl0ZXMtLSkge1xyXG4gICAgICAgIGsgPSB0aGlzLnJlYWRCeXRlKG9mZnNldCsrKTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHgwMSk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4MDIpO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDA0KTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHgwOCk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4MTApO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDIwKTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHg0MCk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4ODApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZihiaXQgPCBiaXRzKSB7XHJcbiAgICAgICAgdmFyIG0gPSAwO1xyXG4gICAgICAgIGsgPSB0aGlzLnJlYWRCeXRlKG9mZnNldCsrKTtcclxuICAgICAgICB3aGlsZShiaXQgPCBiaXRzKSB2YWx1ZVtiaXQrK10gPSAhISgoayA+PiAobSsrKSkgJiAxKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGBsZW5ndGhgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEJ5dGVzID0gZnVuY3Rpb24obGVuZ3RoLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyBsZW5ndGggPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIitsZW5ndGgrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHNsaWNlID0gdGhpcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGxlbmd0aCk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSBsZW5ndGg7XG4gICAgICAgIHJldHVybiBzbGljZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSBwYXlsb2FkIG9mIGJ5dGVzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI2FwcGVuZH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUJ5dGVCdWZmZXJ8IUFycmF5QnVmZmVyfCFVaW50OEFycmF5fHN0cmluZ30gc291cmNlIERhdGEgdG8gd3JpdGUuIElmIGBzb3VyY2VgIGlzIGEgQnl0ZUJ1ZmZlciwgaXRzIG9mZnNldHNcclxuICAgICAqICB3aWxsIGJlIG1vZGlmaWVkIGFjY29yZGluZyB0byB0aGUgcGVyZm9ybWVkIHJlYWQgb3BlcmF0aW9uLlxyXG4gICAgICogQHBhcmFtIHsoc3RyaW5nfG51bWJlcik9fSBlbmNvZGluZyBFbmNvZGluZyBpZiBgZGF0YWAgaXMgYSBzdHJpbmcgKFwiYmFzZTY0XCIsIFwiaGV4XCIsIFwiYmluYXJ5XCIsIGRlZmF1bHRzIHRvIFwidXRmOFwiKVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVCeXRlcyA9IEJ5dGVCdWZmZXJQcm90b3R5cGUuYXBwZW5kO1xyXG5cclxuICAgIC8vIHR5cGVzL2ludHMvaW50OFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIDhiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMWAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgfD0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgdmFyIGNhcGFjaXR5MCA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTApXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkwICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkwIDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDE7XG4gICAgICAgIHRoaXMudmlld1tvZmZzZXRdID0gdmFsdWU7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAxO1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYW4gOGJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZUludDh9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMWAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlQnl0ZSA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQ4O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gOGJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAxID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMStcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLnZpZXdbb2Zmc2V0XTtcclxuICAgICAgICBpZiAoKHZhbHVlICYgMHg4MCkgPT09IDB4ODApIHZhbHVlID0gLSgweEZGIC0gdmFsdWUgKyAxKTsgLy8gQ2FzdCB0byBzaWduZWRcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDE7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhbiA4Yml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRJbnQ4fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMWAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkQnl0ZSA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDg7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYW4gOGJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVpbnQ4ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgIHZhciBjYXBhY2l0eTEgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxKVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MSAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MSA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSAxO1xuICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0XSA9IHZhbHVlO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIDhiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZVVpbnQ4fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDFgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVJbnQ4ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVpbnQ4O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gOGJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMWAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDggPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAxID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMStcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLnZpZXdbb2Zmc2V0XTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDE7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhbiA4Yml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZFVpbnQ4fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMWAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVUludDggPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVaW50ODtcclxuXHJcbiAgICAvLyB0eXBlcy9pbnRzL2ludDE2XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAxNmJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAyYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgb2Zmc2V0YCBvciBgdmFsdWVgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50MTYgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgIHZhciBjYXBhY2l0eTIgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkyKVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MiAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MiA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSAyO1xuICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9ICh2YWx1ZSAmIDB4RkYwMCkgPj4+IDg7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgdmFsdWUgJiAweDAwRkY7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldF0gICA9ICh2YWx1ZSAmIDB4RkYwMCkgPj4+IDg7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAgdmFsdWUgJiAweDAwRkY7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMTZiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVJbnQxNn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAyYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgb2Zmc2V0YCBvciBgdmFsdWVgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlU2hvcnQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50MTY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDE2Yml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDE2ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMiA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzIrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gMDtcclxuICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCAgXTtcclxuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCA4O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgODtcclxuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsxXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCh2YWx1ZSAmIDB4ODAwMCkgPT09IDB4ODAwMCkgdmFsdWUgPSAtKDB4RkZGRiAtIHZhbHVlICsgMSk7IC8vIENhc3QgdG8gc2lnbmVkXHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAyO1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAxNmJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkSW50MTZ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAyYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkU2hvcnQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQxNjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDE2Yml0IHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgb3IgYHZhbHVlYCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVpbnQxNiA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICB2YXIgY2FwYWNpdHkzID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MylcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTMgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTMgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gMjtcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAodmFsdWUgJiAweEZGMDApID4+PiA4O1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIHZhbHVlICYgMHgwMEZGO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXRdICAgPSAodmFsdWUgJiAweEZGMDApID4+PiA4O1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gIHZhbHVlICYgMHgwMEZGO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDI7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDE2Yml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVVaW50MTZ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMmAgaWYgb21pdHRlZC5cclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYG9mZnNldGAgb3IgYHZhbHVlYCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVJbnQxNiA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50MTY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDE2Yml0IHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAyYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDE2ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMiA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzIrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gMDtcclxuICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCAgXTtcclxuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCA4O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgODtcclxuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsxXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAyO1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAxNmJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRVaW50MTZ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAyYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVUludDE2ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDE2O1xyXG5cclxuICAgIC8vIHR5cGVzL2ludHMvaW50MzJcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50MzIgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDQ7XG4gICAgICAgIHZhciBjYXBhY2l0eTQgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHk0KVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5NCAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5NCA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSA0O1xuICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAodmFsdWUgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKHZhbHVlID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9ICh2YWx1ZSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgdmFsdWUgICAgICAgICAmIDB4RkY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gKHZhbHVlID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9ICh2YWx1ZSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAodmFsdWUgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gIHZhbHVlICAgICAgICAgJiAweEZGO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gNDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMzJiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVJbnQzMn0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50MzI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDMyYml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDMyID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgNCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzQrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gMDtcclxuICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgMTY7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8ICA4O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCAgXTtcbiAgICAgICAgICAgIHZhbHVlICs9IHRoaXMudmlld1tvZmZzZXQrM10gPDwgMjQgPj4+IDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8IDE2O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAgODtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrM107XG4gICAgICAgICAgICB2YWx1ZSArPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDI0ID4+PiAwO1xuICAgICAgICB9XG4gICAgICAgIHZhbHVlIHw9IDA7IC8vIENhc3QgdG8gc2lnbmVkXHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA0O1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkSW50MzJ9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50MzI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAzMmJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDMyID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDQ7XG4gICAgICAgIHZhciBjYXBhY2l0eTUgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHk1KVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5NSAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5NSA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSA0O1xuICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAodmFsdWUgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKHZhbHVlID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9ICh2YWx1ZSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgdmFsdWUgICAgICAgICAmIDB4RkY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gKHZhbHVlID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9ICh2YWx1ZSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAodmFsdWUgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gIHZhbHVlICAgICAgICAgJiAweEZGO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gNDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMzJiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZVVpbnQzMn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVJbnQzMiA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50MzI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDMyYml0IHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDMyID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgNCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzQrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gMDtcclxuICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgMTY7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8ICA4O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCAgXTtcbiAgICAgICAgICAgIHZhbHVlICs9IHRoaXMudmlld1tvZmZzZXQrM10gPDwgMjQgPj4+IDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8IDE2O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAgODtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrM107XG4gICAgICAgICAgICB2YWx1ZSArPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDI0ID4+PiAwO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gNDtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMzJiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkVWludDMyfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVJbnQzMiA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQzMjtcclxuXHJcbiAgICAvLyB0eXBlcy9pbnRzL2ludDY0XHJcblxyXG4gICAgaWYgKExvbmcpIHtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV3JpdGVzIGEgNjRiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDY0ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCEodmFsdWUgJiYgdmFsdWUgaW5zdGFuY2VvZiBMb25nKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyIG9yIExvbmcpXCIpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIG9mZnNldCArPSA4O1xuICAgICAgICAgICAgdmFyIGNhcGFjaXR5NiA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHk2KVxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTYgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTYgOiBvZmZzZXQpO1xuICAgICAgICAgICAgb2Zmc2V0IC09IDg7XG4gICAgICAgICAgICB2YXIgbG8gPSB2YWx1ZS5sb3csXHJcbiAgICAgICAgICAgICAgICBoaSA9IHZhbHVlLmhpZ2g7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9IChsbyA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGxvID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAobG8gPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICBsbyAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAoaGkgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChoaSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGhpID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgaGkgICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9IChoaSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGhpID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAoaGkgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICBoaSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAobG8gPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChsbyA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGxvID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAgbG8gICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gODtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdyaXRlcyBhIDY0Yml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlSW50NjR9LlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVMb25nID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDY0O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZWFkcyBhIDY0Yml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50NjQgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgOCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIis4K1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGxvID0gMCxcclxuICAgICAgICAgICAgICAgIGhpID0gMDtcclxuICAgICAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgICAgICBsbyAgPSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgIDg7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCAgXTtcbiAgICAgICAgICAgICAgICBsbyArPSB0aGlzLnZpZXdbb2Zmc2V0KzNdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgaGkgID0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQgIF07XG4gICAgICAgICAgICAgICAgaGkgKz0gdGhpcy52aWV3W29mZnNldCszXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBoaSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgIDg7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCszXTtcbiAgICAgICAgICAgICAgICBoaSArPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgbG8gID0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQrM107XG4gICAgICAgICAgICAgICAgbG8gKz0gdGhpcy52aWV3W29mZnNldCAgXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIHZhbHVlID0gbmV3IExvbmcobG8sIGhpLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gODtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZWFkcyBhIDY0Yml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRJbnQ2NH0uXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRMb25nID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50NjQ7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdyaXRlcyBhIDY0Yml0IHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVpbnQ2NCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghKHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgTG9uZykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlciBvciBMb25nKVwiKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICBvZmZzZXQgKz0gODtcbiAgICAgICAgICAgIHZhciBjYXBhY2l0eTcgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5NylcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHk3ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHk3IDogb2Zmc2V0KTtcbiAgICAgICAgICAgIG9mZnNldCAtPSA4O1xuICAgICAgICAgICAgdmFyIGxvID0gdmFsdWUubG93LFxyXG4gICAgICAgICAgICAgICAgaGkgPSB2YWx1ZS5oaWdoO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAobG8gPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChsbyA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGxvID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgbG8gICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKGhpID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAoaGkgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChoaSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIGhpICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAoaGkgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChoaSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGhpID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAgaGkgICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gKGxvID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAobG8gPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChsbyA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gIGxvICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXcml0ZXMgYSA2NGJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlVWludDY0fS5cclxuICAgICAgICAgKiBAZnVuY3Rpb25cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVUludDY0ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVpbnQ2NDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSA2NGJpdCB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDY0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDggPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrOCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBsbyA9IDAsXHJcbiAgICAgICAgICAgICAgICBoaSA9IDA7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICAgICAgbG8gID0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQgIF07XG4gICAgICAgICAgICAgICAgbG8gKz0gdGhpcy52aWV3W29mZnNldCszXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIGhpICA9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgMTY7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xuICAgICAgICAgICAgICAgIGhpICs9IHRoaXMudmlld1tvZmZzZXQrM10gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaGkgID0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQrM107XG4gICAgICAgICAgICAgICAgaGkgKz0gdGhpcy52aWV3W29mZnNldCAgXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIGxvICA9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgMTY7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAgODtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgICAgIGxvICs9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IG5ldyBMb25nKGxvLCBoaSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gODtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZWFkcyBhIDY0Yml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZFVpbnQ2NH0uXHJcbiAgICAgICAgICogQGZ1bmN0aW9uXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVSW50NjQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVaW50NjQ7XHJcblxyXG4gICAgfSAvLyBMb25nXHJcblxyXG5cclxuICAgIC8vIHR5cGVzL2Zsb2F0cy9mbG9hdDMyXHJcblxyXG4gICAgLypcclxuICAgICBpZWVlNzU0IC0gaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9pZWVlNzU0XHJcblxyXG4gICAgIFRoZSBNSVQgTGljZW5zZSAoTUlUKVxyXG5cclxuICAgICBDb3B5cmlnaHQgKGMpIEZlcm9zcyBBYm91a2hhZGlqZWhcclxuXHJcbiAgICAgUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxyXG4gICAgIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcclxuICAgICBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXHJcbiAgICAgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxyXG4gICAgIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xyXG4gICAgIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XHJcblxyXG4gICAgIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXHJcbiAgICAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXHJcblxyXG4gICAgIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcclxuICAgICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcclxuICAgICBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcclxuICAgICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXHJcbiAgICAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcclxuICAgICBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXHJcbiAgICAgVEhFIFNPRlRXQVJFLlxyXG4gICAgKi9cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGFuIElFRUU3NTQgZmxvYXQgZnJvbSBhIGJ5dGUgYXJyYXkuXHJcbiAgICAgKiBAcGFyYW0geyFBcnJheX0gYnVmZmVyXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGlzTEVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtTGVuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbkJ5dGVzXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGllZWU3NTRfcmVhZChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XHJcbiAgICAgICAgdmFyIGUsIG0sXHJcbiAgICAgICAgICAgIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDEsXHJcbiAgICAgICAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXHJcbiAgICAgICAgICAgIGVCaWFzID0gZU1heCA+PiAxLFxyXG4gICAgICAgICAgICBuQml0cyA9IC03LFxyXG4gICAgICAgICAgICBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDAsXHJcbiAgICAgICAgICAgIGQgPSBpc0xFID8gLTEgOiAxLFxyXG4gICAgICAgICAgICBzID0gYnVmZmVyW29mZnNldCArIGldO1xyXG5cclxuICAgICAgICBpICs9IGQ7XHJcblxyXG4gICAgICAgIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpO1xyXG4gICAgICAgIHMgPj49ICgtbkJpdHMpO1xyXG4gICAgICAgIG5CaXRzICs9IGVMZW47XHJcbiAgICAgICAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cclxuXHJcbiAgICAgICAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSk7XHJcbiAgICAgICAgZSA+Pj0gKC1uQml0cyk7XHJcbiAgICAgICAgbkJpdHMgKz0gbUxlbjtcclxuICAgICAgICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxyXG5cclxuICAgICAgICBpZiAoZSA9PT0gMCkge1xyXG4gICAgICAgICAgICBlID0gMSAtIGVCaWFzO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKTtcclxuICAgICAgICAgICAgZSA9IGUgLSBlQmlhcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYW4gSUVFRTc1NCBmbG9hdCB0byBhIGJ5dGUgYXJyYXkuXHJcbiAgICAgKiBAcGFyYW0geyFBcnJheX0gYnVmZmVyXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNMRVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1MZW5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuQnl0ZXNcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBpZWVlNzU0X3dyaXRlKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XHJcbiAgICAgICAgdmFyIGUsIG0sIGMsXHJcbiAgICAgICAgICAgIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDEsXHJcbiAgICAgICAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXHJcbiAgICAgICAgICAgIGVCaWFzID0gZU1heCA+PiAxLFxyXG4gICAgICAgICAgICBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMCksXHJcbiAgICAgICAgICAgIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKSxcclxuICAgICAgICAgICAgZCA9IGlzTEUgPyAxIDogLTEsXHJcbiAgICAgICAgICAgIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDA7XHJcblxyXG4gICAgICAgIHZhbHVlID0gTWF0aC5hYnModmFsdWUpO1xyXG5cclxuICAgICAgICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xyXG4gICAgICAgICAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDA7XHJcbiAgICAgICAgICAgIGUgPSBlTWF4O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKTtcclxuICAgICAgICAgICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgZS0tO1xyXG4gICAgICAgICAgICAgICAgYyAqPSAyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gcnQgLyBjO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xyXG4gICAgICAgICAgICAgICAgZSsrO1xyXG4gICAgICAgICAgICAgICAgYyAvPSAyO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcclxuICAgICAgICAgICAgICAgIG0gPSAwO1xyXG4gICAgICAgICAgICAgICAgZSA9IGVNYXg7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcclxuICAgICAgICAgICAgICAgIG0gPSAodmFsdWUgKiBjIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKTtcclxuICAgICAgICAgICAgICAgIGUgPSBlICsgZUJpYXM7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XHJcbiAgICAgICAgICAgICAgICBlID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cclxuXHJcbiAgICAgICAgZSA9IChlIDw8IG1MZW4pIHwgbTtcclxuICAgICAgICBlTGVuICs9IG1MZW47XHJcbiAgICAgICAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxyXG5cclxuICAgICAgICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjg7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAzMmJpdCBmbG9hdC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRmxvYXQzMiA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhIG51bWJlcilcIik7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gNDtcbiAgICAgICAgdmFyIGNhcGFjaXR5OCA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTgpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHk4ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHk4IDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDQ7XG4gICAgICAgIGllZWU3NTRfd3JpdGUodGhpcy52aWV3LCB2YWx1ZSwgb2Zmc2V0LCB0aGlzLmxpdHRsZUVuZGlhbiwgMjMsIDQpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gNDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMzJiaXQgZmxvYXQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVGbG9hdDMyfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVGbG9hdCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVGbG9hdDMyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCBmbG9hdC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkRmxvYXQzMiA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIis0K1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IGllZWU3NTRfcmVhZCh0aGlzLnZpZXcsIG9mZnNldCwgdGhpcy5saXR0bGVFbmRpYW4sIDIzLCA0KTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDMyYml0IGZsb2F0LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRGbG9hdDMyfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRGbG9hdCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEZsb2F0MzI7XHJcblxyXG4gICAgLy8gdHlwZXMvZmxvYXRzL2Zsb2F0NjRcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDY0Yml0IGZsb2F0LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVGbG9hdDY0ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGEgbnVtYmVyKVwiKTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSA4O1xuICAgICAgICB2YXIgY2FwYWNpdHk5ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5OSlcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTkgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTkgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gODtcbiAgICAgICAgaWVlZTc1NF93cml0ZSh0aGlzLnZpZXcsIHZhbHVlLCBvZmZzZXQsIHRoaXMubGl0dGxlRW5kaWFuLCA1MiwgOCk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA4O1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSA2NGJpdCBmbG9hdC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZUZsb2F0NjR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZURvdWJsZSA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVGbG9hdDY0O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSA2NGJpdCBmbG9hdC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkRmxvYXQ2NCA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDggPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIis4K1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IGllZWU3NTRfcmVhZCh0aGlzLnZpZXcsIG9mZnNldCwgdGhpcy5saXR0bGVFbmRpYW4sIDUyLCA4KTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDg7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDY0Yml0IGZsb2F0LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRGbG9hdDY0fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWREb3VibGUgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRGbG9hdDY0O1xyXG5cclxuXHJcbiAgICAvLyB0eXBlcy92YXJpbnRzL3ZhcmludDMyXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYXhpbXVtIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBzdG9yZSBhIDMyYml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLk1BWF9WQVJJTlQzMl9CWVRFUyA9IDU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIGEgMzJiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gZW5jb2RlXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQuIENhcHBlZCB0byB7QGxpbmsgQnl0ZUJ1ZmZlci5NQVhfVkFSSU5UMzJfQllURVN9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuY2FsY3VsYXRlVmFyaW50MzIgPSBmdW5jdGlvbih2YWx1ZSkge1xyXG4gICAgICAgIC8vIHJlZjogc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2NcclxuICAgICAgICB2YWx1ZSA9IHZhbHVlID4+PiAwO1xyXG4gICAgICAgICAgICAgaWYgKHZhbHVlIDwgMSA8PCA3ICkgcmV0dXJuIDE7XHJcbiAgICAgICAgZWxzZSBpZiAodmFsdWUgPCAxIDw8IDE0KSByZXR1cm4gMjtcclxuICAgICAgICBlbHNlIGlmICh2YWx1ZSA8IDEgPDwgMjEpIHJldHVybiAzO1xyXG4gICAgICAgIGVsc2UgaWYgKHZhbHVlIDwgMSA8PCAyOCkgcmV0dXJuIDQ7XHJcbiAgICAgICAgZWxzZSAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gNTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBaaWd6YWcgZW5jb2RlcyBhIHNpZ25lZCAzMmJpdCBpbnRlZ2VyIHNvIHRoYXQgaXQgY2FuIGJlIGVmZmVjdGl2ZWx5IHVzZWQgd2l0aCB2YXJpbnQgZW5jb2RpbmcuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBTaWduZWQgMzJiaXQgaW50ZWdlclxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgemlnemFnIGVuY29kZWQgMzJiaXQgaW50ZWdlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLnppZ1phZ0VuY29kZTMyID0gZnVuY3Rpb24obikge1xyXG4gICAgICAgIHJldHVybiAoKChuIHw9IDApIDw8IDEpIF4gKG4gPj4gMzEpKSA+Pj4gMDsgLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaFxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY29kZXMgYSB6aWd6YWcgZW5jb2RlZCBzaWduZWQgMzJiaXQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFVuc2lnbmVkIHppZ3phZyBlbmNvZGVkIDMyYml0IGludGVnZXJcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFNpZ25lZCAzMmJpdCBpbnRlZ2VyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuemlnWmFnRGVjb2RlMzIgPSBmdW5jdGlvbihuKSB7XHJcbiAgICAgICAgcmV0dXJuICgobiA+Pj4gMSkgXiAtKG4gJiAxKSkgfCAwOyAvLyAvLyByZWY6IHNyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMzJiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IHRoaXMgaWYgYG9mZnNldGAgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVWYXJpbnQzMiA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgfD0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc2l6ZSA9IEJ5dGVCdWZmZXIuY2FsY3VsYXRlVmFyaW50MzIodmFsdWUpLFxyXG4gICAgICAgICAgICBiO1xyXG4gICAgICAgIG9mZnNldCArPSBzaXplO1xuICAgICAgICB2YXIgY2FwYWNpdHkxMCA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTEwKVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MTAgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTEwIDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IHNpemU7XG4gICAgICAgIHZhbHVlID4+Pj0gMDtcclxuICAgICAgICB3aGlsZSAodmFsdWUgPj0gMHg4MCkge1xyXG4gICAgICAgICAgICBiID0gKHZhbHVlICYgMHg3ZikgfCAweDgwO1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KytdID0gYjtcclxuICAgICAgICAgICAgdmFsdWUgPj4+PSA3O1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KytdID0gdmFsdWU7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNpemU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgemlnLXphZyBlbmNvZGVkIChzaWduZWQpIDMyYml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSB0aGlzIGlmIGBvZmZzZXRgIGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVmFyaW50MzJaaWdaYWcgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMud3JpdGVWYXJpbnQzMihCeXRlQnVmZmVyLnppZ1phZ0VuY29kZTMyKHZhbHVlKSwgb2Zmc2V0KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDMyYml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ8IXt2YWx1ZTogbnVtYmVyLCBsZW5ndGg6IG51bWJlcn19IFRoZSB2YWx1ZSByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSB2YWx1ZSByZWFkXHJcbiAgICAgKiAgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgaXQncyBub3QgYSB2YWxpZCB2YXJpbnQuIEhhcyBhIHByb3BlcnR5IGB0cnVuY2F0ZWQgPSB0cnVlYCBpZiB0aGVyZSBpcyBub3QgZW5vdWdoIGRhdGEgYXZhaWxhYmxlXHJcbiAgICAgKiAgdG8gZnVsbHkgZGVjb2RlIHRoZSB2YXJpbnQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFZhcmludDMyID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMSA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzErXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGMgPSAwLFxyXG4gICAgICAgICAgICB2YWx1ZSA9IDAgPj4+IDAsXHJcbiAgICAgICAgICAgIGI7XHJcbiAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQgJiYgb2Zmc2V0ID4gdGhpcy5saW1pdCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGVyciA9IEVycm9yKFwiVHJ1bmNhdGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgZXJyWyd0cnVuY2F0ZWQnXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107XHJcbiAgICAgICAgICAgIGlmIChjIDwgNSlcclxuICAgICAgICAgICAgICAgIHZhbHVlIHw9IChiICYgMHg3ZikgPDwgKDcqYyk7XHJcbiAgICAgICAgICAgICsrYztcclxuICAgICAgICB9IHdoaWxlICgoYiAmIDB4ODApICE9PSAwKTtcclxuICAgICAgICB2YWx1ZSB8PSAwO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBcInZhbHVlXCI6IHZhbHVlLFxyXG4gICAgICAgICAgICBcImxlbmd0aFwiOiBjXHJcbiAgICAgICAgfTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIHppZy16YWcgZW5jb2RlZCAoc2lnbmVkKSAzMmJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfCF7dmFsdWU6IG51bWJlciwgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgdmFsdWUgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgdmFsdWUgcmVhZFxyXG4gICAgICogIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIGl0J3Mgbm90IGEgdmFsaWQgdmFyaW50XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFZhcmludDMyWmlnWmFnID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHZhbCA9IHRoaXMucmVhZFZhcmludDMyKG9mZnNldCk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdvYmplY3QnKVxyXG4gICAgICAgICAgICB2YWxbXCJ2YWx1ZVwiXSA9IEJ5dGVCdWZmZXIuemlnWmFnRGVjb2RlMzIodmFsW1widmFsdWVcIl0pO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgdmFsID0gQnl0ZUJ1ZmZlci56aWdaYWdEZWNvZGUzMih2YWwpO1xyXG4gICAgICAgIHJldHVybiB2YWw7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIHR5cGVzL3ZhcmludHMvdmFyaW50NjRcclxuXHJcbiAgICBpZiAoTG9uZykge1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBNYXhpbXVtIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBzdG9yZSBhIDY0Yml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICogQGNvbnN0XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXIuTUFYX1ZBUklOVDY0X0JZVEVTID0gMTA7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENhbGN1bGF0ZXMgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgYSA2NGJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gdmFsdWUgVmFsdWUgdG8gZW5jb2RlXHJcbiAgICAgICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkLiBDYXBwZWQgdG8ge0BsaW5rIEJ5dGVCdWZmZXIuTUFYX1ZBUklOVDY0X0JZVEVTfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyLmNhbGN1bGF0ZVZhcmludDY0ID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICAvLyByZWY6IHNyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmNjXHJcbiAgICAgICAgICAgIHZhciBwYXJ0MCA9IHZhbHVlLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgICAgICBwYXJ0MSA9IHZhbHVlLnNoaWZ0UmlnaHRVbnNpZ25lZCgyOCkudG9JbnQoKSA+Pj4gMCxcclxuICAgICAgICAgICAgICAgIHBhcnQyID0gdmFsdWUuc2hpZnRSaWdodFVuc2lnbmVkKDU2KS50b0ludCgpID4+PiAwO1xyXG4gICAgICAgICAgICBpZiAocGFydDIgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHBhcnQxID09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocGFydDAgPCAxIDw8IDE0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFydDAgPCAxIDw8IDcgPyAxIDogMjtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0MCA8IDEgPDwgMjEgPyAzIDogNDtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnQxIDwgMSA8PCAxNClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnQxIDwgMSA8PCA3ID8gNSA6IDY7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFydDEgPCAxIDw8IDIxID8gNyA6IDg7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnQyIDwgMSA8PCA3ID8gOSA6IDEwO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFppZ3phZyBlbmNvZGVzIGEgc2lnbmVkIDY0Yml0IGludGVnZXIgc28gdGhhdCBpdCBjYW4gYmUgZWZmZWN0aXZlbHkgdXNlZCB3aXRoIHZhcmludCBlbmNvZGluZy5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gdmFsdWUgU2lnbmVkIGxvbmdcclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFVuc2lnbmVkIHppZ3phZyBlbmNvZGVkIGxvbmdcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlci56aWdaYWdFbmNvZGU2NCA9IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlLCBmYWxzZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlLCBmYWxzZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZS51bnNpZ25lZCAhPT0gZmFsc2UpIHZhbHVlID0gdmFsdWUudG9TaWduZWQoKTtcbiAgICAgICAgICAgIC8vIHJlZjogc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmhcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnNoaWZ0TGVmdCgxKS54b3IodmFsdWUuc2hpZnRSaWdodCg2MykpLnRvVW5zaWduZWQoKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWNvZGVzIGEgemlnemFnIGVuY29kZWQgc2lnbmVkIDY0Yml0IGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ9IHZhbHVlIFVuc2lnbmVkIHppZ3phZyBlbmNvZGVkIGxvbmcgb3IgSmF2YVNjcmlwdCBudW1iZXJcclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNpZ25lZCBsb25nXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXIuemlnWmFnRGVjb2RlNjQgPSBmdW5jdGlvbih2YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUudW5zaWduZWQgIT09IGZhbHNlKSB2YWx1ZSA9IHZhbHVlLnRvU2lnbmVkKCk7XG4gICAgICAgICAgICAvLyByZWY6IHNyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oXHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zaGlmdFJpZ2h0VW5zaWduZWQoMSkueG9yKHZhbHVlLmFuZChMb25nLk9ORSkudG9TaWduZWQoKS5uZWdhdGUoKSkudG9TaWduZWQoKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXcml0ZXMgYSA2NGJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcnxMb25nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gYHRoaXNgIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4uXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVWYXJpbnQ2NCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUpO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghKHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgTG9uZykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlciBvciBMb25nKVwiKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUsIGZhbHNlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUsIGZhbHNlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLnVuc2lnbmVkICE9PSBmYWxzZSkgdmFsdWUgPSB2YWx1ZS50b1NpZ25lZCgpO1xuICAgICAgICAgICAgdmFyIHNpemUgPSBCeXRlQnVmZmVyLmNhbGN1bGF0ZVZhcmludDY0KHZhbHVlKSxcclxuICAgICAgICAgICAgICAgIHBhcnQwID0gdmFsdWUudG9JbnQoKSA+Pj4gMCxcclxuICAgICAgICAgICAgICAgIHBhcnQxID0gdmFsdWUuc2hpZnRSaWdodFVuc2lnbmVkKDI4KS50b0ludCgpID4+PiAwLFxyXG4gICAgICAgICAgICAgICAgcGFydDIgPSB2YWx1ZS5zaGlmdFJpZ2h0VW5zaWduZWQoNTYpLnRvSW50KCkgPj4+IDA7XHJcbiAgICAgICAgICAgIG9mZnNldCArPSBzaXplO1xuICAgICAgICAgICAgdmFyIGNhcGFjaXR5MTEgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MTEpXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MTEgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTExIDogb2Zmc2V0KTtcbiAgICAgICAgICAgIG9mZnNldCAtPSBzaXplO1xuICAgICAgICAgICAgc3dpdGNoIChzaXplKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDEwOiB0aGlzLnZpZXdbb2Zmc2V0KzldID0gKHBhcnQyID4+PiAgNykgJiAweDAxO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA5IDogdGhpcy52aWV3W29mZnNldCs4XSA9IHNpemUgIT09IDkgPyAocGFydDIgICAgICAgKSB8IDB4ODAgOiAocGFydDIgICAgICAgKSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDggOiB0aGlzLnZpZXdbb2Zmc2V0KzddID0gc2l6ZSAhPT0gOCA/IChwYXJ0MSA+Pj4gMjEpIHwgMHg4MCA6IChwYXJ0MSA+Pj4gMjEpICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgNyA6IHRoaXMudmlld1tvZmZzZXQrNl0gPSBzaXplICE9PSA3ID8gKHBhcnQxID4+PiAxNCkgfCAweDgwIDogKHBhcnQxID4+PiAxNCkgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA2IDogdGhpcy52aWV3W29mZnNldCs1XSA9IHNpemUgIT09IDYgPyAocGFydDEgPj4+ICA3KSB8IDB4ODAgOiAocGFydDEgPj4+ICA3KSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDUgOiB0aGlzLnZpZXdbb2Zmc2V0KzRdID0gc2l6ZSAhPT0gNSA/IChwYXJ0MSAgICAgICApIHwgMHg4MCA6IChwYXJ0MSAgICAgICApICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgNCA6IHRoaXMudmlld1tvZmZzZXQrM10gPSBzaXplICE9PSA0ID8gKHBhcnQwID4+PiAyMSkgfCAweDgwIDogKHBhcnQwID4+PiAyMSkgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAzIDogdGhpcy52aWV3W29mZnNldCsyXSA9IHNpemUgIT09IDMgPyAocGFydDAgPj4+IDE0KSB8IDB4ODAgOiAocGFydDAgPj4+IDE0KSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDIgOiB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gc2l6ZSAhPT0gMiA/IChwYXJ0MCA+Pj4gIDcpIHwgMHg4MCA6IChwYXJ0MCA+Pj4gIDcpICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgMSA6IHRoaXMudmlld1tvZmZzZXQgIF0gPSBzaXplICE9PSAxID8gKHBhcnQwICAgICAgICkgfCAweDgwIDogKHBhcnQwICAgICAgICkgJiAweDdGO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgKz0gc2l6ZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNpemU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXcml0ZXMgYSB6aWctemFnIGVuY29kZWQgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8TG9uZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IGB0aGlzYCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuLlxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVmFyaW50NjRaaWdaYWcgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndyaXRlVmFyaW50NjQoQnl0ZUJ1ZmZlci56aWdaYWdFbmNvZGU2NCh2YWx1ZSksIG9mZnNldCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVhZHMgYSA2NGJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci4gUmVxdWlyZXMgTG9uZy5qcy5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd8IXt2YWx1ZTogTG9uZywgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgdmFsdWUgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgdmFsdWUgcmVhZCBhbmRcclxuICAgICAgICAgKiAgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgaXQncyBub3QgYSB2YWxpZCB2YXJpbnRcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVmFyaW50NjQgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMSA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisxK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5jY1xyXG4gICAgICAgICAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgICAgICAgICBwYXJ0MCA9IDAsXHJcbiAgICAgICAgICAgICAgICBwYXJ0MSA9IDAsXHJcbiAgICAgICAgICAgICAgICBwYXJ0MiA9IDAsXHJcbiAgICAgICAgICAgICAgICBiICA9IDA7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MCAgPSAoYiAmIDB4N0YpICAgICAgOyBpZiAoIGIgJiAweDgwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MCB8PSAoYiAmIDB4N0YpIDw8ICA3OyBpZiAoKGIgJiAweDgwKSB8fCAodGhpcy5ub0Fzc2VydCAmJiB0eXBlb2YgYiA9PT0gJ3VuZGVmaW5lZCcpKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MCB8PSAoYiAmIDB4N0YpIDw8IDE0OyBpZiAoKGIgJiAweDgwKSB8fCAodGhpcy5ub0Fzc2VydCAmJiB0eXBlb2YgYiA9PT0gJ3VuZGVmaW5lZCcpKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MCB8PSAoYiAmIDB4N0YpIDw8IDIxOyBpZiAoKGIgJiAweDgwKSB8fCAodGhpcy5ub0Fzc2VydCAmJiB0eXBlb2YgYiA9PT0gJ3VuZGVmaW5lZCcpKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MSAgPSAoYiAmIDB4N0YpICAgICAgOyBpZiAoKGIgJiAweDgwKSB8fCAodGhpcy5ub0Fzc2VydCAmJiB0eXBlb2YgYiA9PT0gJ3VuZGVmaW5lZCcpKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MSB8PSAoYiAmIDB4N0YpIDw8ICA3OyBpZiAoKGIgJiAweDgwKSB8fCAodGhpcy5ub0Fzc2VydCAmJiB0eXBlb2YgYiA9PT0gJ3VuZGVmaW5lZCcpKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MSB8PSAoYiAmIDB4N0YpIDw8IDE0OyBpZiAoKGIgJiAweDgwKSB8fCAodGhpcy5ub0Fzc2VydCAmJiB0eXBlb2YgYiA9PT0gJ3VuZGVmaW5lZCcpKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MSB8PSAoYiAmIDB4N0YpIDw8IDIxOyBpZiAoKGIgJiAweDgwKSB8fCAodGhpcy5ub0Fzc2VydCAmJiB0eXBlb2YgYiA9PT0gJ3VuZGVmaW5lZCcpKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MiAgPSAoYiAmIDB4N0YpICAgICAgOyBpZiAoKGIgJiAweDgwKSB8fCAodGhpcy5ub0Fzc2VydCAmJiB0eXBlb2YgYiA9PT0gJ3VuZGVmaW5lZCcpKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdOyBwYXJ0MiB8PSAoYiAmIDB4N0YpIDw8ICA3OyBpZiAoKGIgJiAweDgwKSB8fCAodGhpcy5ub0Fzc2VydCAmJiB0eXBlb2YgYiA9PT0gJ3VuZGVmaW5lZCcpKSB7XHJcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwiQnVmZmVyIG92ZXJydW5cIik7IH19fX19fX19fX1cclxuICAgICAgICAgICAgdmFyIHZhbHVlID0gTG9uZy5mcm9tQml0cyhwYXJ0MCB8IChwYXJ0MSA8PCAyOCksIChwYXJ0MSA+Pj4gNCkgfCAocGFydDIpIDw8IDI0LCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICd2YWx1ZSc6IHZhbHVlLFxyXG4gICAgICAgICAgICAgICAgICAgICdsZW5ndGgnOiBvZmZzZXQtc3RhcnRcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZWFkcyBhIHppZy16YWcgZW5jb2RlZCA2NGJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci4gUmVxdWlyZXMgTG9uZy5qcy5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd8IXt2YWx1ZTogTG9uZywgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgdmFsdWUgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgdmFsdWUgcmVhZCBhbmRcclxuICAgICAgICAgKiAgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgaXQncyBub3QgYSB2YWxpZCB2YXJpbnRcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVmFyaW50NjRaaWdaYWcgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICAgICAgdmFyIHZhbCA9IHRoaXMucmVhZFZhcmludDY0KG9mZnNldCk7XHJcbiAgICAgICAgICAgIGlmICh2YWwgJiYgdmFsWyd2YWx1ZSddIGluc3RhbmNlb2YgTG9uZylcclxuICAgICAgICAgICAgICAgIHZhbFtcInZhbHVlXCJdID0gQnl0ZUJ1ZmZlci56aWdaYWdEZWNvZGU2NCh2YWxbXCJ2YWx1ZVwiXSk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHZhbCA9IEJ5dGVCdWZmZXIuemlnWmFnRGVjb2RlNjQodmFsKTtcclxuICAgICAgICAgICAgcmV0dXJuIHZhbDtcclxuICAgICAgICB9O1xyXG5cclxuICAgIH0gLy8gTG9uZ1xyXG5cclxuXHJcbiAgICAvLyB0eXBlcy9zdHJpbmdzL2NzdHJpbmdcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIE5VTEwtdGVybWluYXRlZCBVVEY4IGVuY29kZWQgc3RyaW5nLiBGb3IgdGhpcyB0byB3b3JrIHRoZSBzcGVjaWZpZWQgc3RyaW5nIG11c3Qgbm90IGNvbnRhaW4gYW55IE5VTExcclxuICAgICAqICBjaGFyYWN0ZXJzIGl0c2VsZi5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICBjb250YWluZWQgaW4gYHN0cmAgKyAxIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSB0aGlzIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUNTdHJpbmcgPSBmdW5jdGlvbihzdHIsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICB2YXIgaSxcclxuICAgICAgICAgICAgayA9IHN0ci5sZW5ndGg7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBOb3QgYSBzdHJpbmdcIik7XHJcbiAgICAgICAgICAgIGZvciAoaT0wOyBpPGs7ICsraSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHN0ci5jaGFyQ29kZUF0KGkpID09PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHN0cjogQ29udGFpbnMgTlVMTC1jaGFyYWN0ZXJzXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICAvLyBVVEY4IHN0cmluZ3MgZG8gbm90IGNvbnRhaW4gemVybyBieXRlcyBpbiBiZXR3ZWVuIGV4Y2VwdCBmb3IgdGhlIHplcm8gY2hhcmFjdGVyLCBzbzpcclxuICAgICAgICBrID0gdXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSlbMV07XHJcbiAgICAgICAgb2Zmc2V0ICs9IGsrMTtcbiAgICAgICAgdmFyIGNhcGFjaXR5MTIgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxMilcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTEyICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxMiA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSBrKzE7XG4gICAgICAgIHV0ZnguZW5jb2RlVVRGMTZ0b1VURjgoc3RyaW5nU291cmNlKHN0ciksIGZ1bmN0aW9uKGIpIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IGI7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KytdID0gMDtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIE5VTEwtdGVybWluYXRlZCBVVEY4IGVuY29kZWQgc3RyaW5nLiBGb3IgdGhpcyB0byB3b3JrIHRoZSBzdHJpbmcgcmVhZCBtdXN0IG5vdCBjb250YWluIGFueSBOVUxMIGNoYXJhY3RlcnNcclxuICAgICAqICBpdHNlbGYuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcmVhZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ3whe3N0cmluZzogc3RyaW5nLCBsZW5ndGg6IG51bWJlcn19IFRoZSBzdHJpbmcgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgc3RyaW5nXHJcbiAgICAgKiAgcmVhZCBhbmQgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkQ1N0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDEgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisxK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzdGFydCA9IG9mZnNldCxcclxuICAgICAgICAgICAgdGVtcDtcclxuICAgICAgICAvLyBVVEY4IHN0cmluZ3MgZG8gbm90IGNvbnRhaW4gemVybyBieXRlcyBpbiBiZXR3ZWVuIGV4Y2VwdCBmb3IgdGhlIHplcm8gY2hhcmFjdGVyIGl0c2VsZiwgc286XHJcbiAgICAgICAgdmFyIHNkLCBiID0gLTE7XHJcbiAgICAgICAgdXRmeC5kZWNvZGVVVEY4dG9VVEYxNihmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgaWYgKGIgPT09IDApIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0ID49IHRoaXMubGltaXQpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogVHJ1bmNhdGVkIGRhdGEsIFwiK29mZnNldCtcIiA8IFwiK3RoaXMubGltaXQpO1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTtcclxuICAgICAgICAgICAgcmV0dXJuIGIgPT09IDAgPyBudWxsIDogYjtcclxuICAgICAgICB9LmJpbmQodGhpcyksIHNkID0gc3RyaW5nRGVzdGluYXRpb24oKSwgdHJ1ZSk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gc2QoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgXCJzdHJpbmdcIjogc2QoKSxcclxuICAgICAgICAgICAgICAgIFwibGVuZ3RoXCI6IG9mZnNldCAtIHN0YXJ0XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyB0eXBlcy9zdHJpbmdzL2lzdHJpbmdcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIGxlbmd0aCBhcyB1aW50MzIgcHJlZml4ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSBgdGhpc2AgaWYgYG9mZnNldGAgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjd3JpdGVWYXJpbnQzMlxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSVN0cmluZyA9IGZ1bmN0aW9uKHN0ciwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgc3RyaW5nXCIpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgICAgICBrO1xyXG4gICAgICAgIGsgPSB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpLCB0aGlzLm5vQXNzZXJ0KVsxXTtcclxuICAgICAgICBvZmZzZXQgKz0gNCtrO1xuICAgICAgICB2YXIgY2FwYWNpdHkxMyA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTEzKVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MTMgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTEzIDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDQraztcbiAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKGsgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGsgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGsgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIGsgICAgICAgICAmIDB4RkY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gKGsgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGsgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGsgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gIGsgICAgICAgICAmIDB4RkY7XG4gICAgICAgIH1cbiAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgdXRmeC5lbmNvZGVVVEYxNnRvVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgZnVuY3Rpb24oYikge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KytdID0gYjtcclxuICAgICAgICB9LmJpbmQodGhpcykpO1xyXG4gICAgICAgIGlmIChvZmZzZXQgIT09IHN0YXJ0ICsgNCArIGspXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiBUcnVuY2F0ZWQgZGF0YSwgXCIrb2Zmc2V0K1wiID09IFwiKyhvZmZzZXQrNCtrKSk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgbGVuZ3RoIGFzIHVpbnQzMiBwcmVmaXhlZCBVVEY4IGVuY29kZWQgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8IXtzdHJpbmc6IHN0cmluZywgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgc3RyaW5nIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHN0cmluZ1xyXG4gICAgICogIHJlYWQgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjcmVhZFZhcmludDMyXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZElTdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA0ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrNCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc3RhcnQgPSBvZmZzZXQ7XHJcbiAgICAgICAgdmFyIGxlbiA9IHRoaXMucmVhZFVpbnQzMihvZmZzZXQpO1xyXG4gICAgICAgIHZhciBzdHIgPSB0aGlzLnJlYWRVVEY4U3RyaW5nKGxlbiwgQnl0ZUJ1ZmZlci5NRVRSSUNTX0JZVEVTLCBvZmZzZXQgKz0gNCk7XHJcbiAgICAgICAgb2Zmc2V0ICs9IHN0clsnbGVuZ3RoJ107XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gc3RyWydzdHJpbmcnXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgJ3N0cmluZyc6IHN0clsnc3RyaW5nJ10sXHJcbiAgICAgICAgICAgICAgICAnbGVuZ3RoJzogb2Zmc2V0IC0gc3RhcnRcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIHR5cGVzL3N0cmluZ3MvdXRmOHN0cmluZ1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0cmljcyByZXByZXNlbnRpbmcgbnVtYmVyIG9mIFVURjggY2hhcmFjdGVycy4gRXZhbHVhdGVzIHRvIGBjYC5cclxuICAgICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5NRVRSSUNTX0NIQVJTID0gJ2MnO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWV0cmljcyByZXByZXNlbnRpbmcgbnVtYmVyIG9mIGJ5dGVzLiBFdmFsdWF0ZXMgdG8gYGJgLlxyXG4gICAgICogQHR5cGUge3N0cmluZ31cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLk1FVFJJQ1NfQllURVMgPSAnYic7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYW4gVVRGOCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSB0aGlzIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4uXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVVEY4U3RyaW5nID0gZnVuY3Rpb24oc3RyLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaztcclxuICAgICAgICB2YXIgc3RhcnQgPSBvZmZzZXQ7XHJcbiAgICAgICAgayA9IHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjgoc3RyaW5nU291cmNlKHN0cikpWzFdO1xyXG4gICAgICAgIG9mZnNldCArPSBrO1xuICAgICAgICB2YXIgY2FwYWNpdHkxNCA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTE0KVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MTQgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTE0IDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IGs7XG4gICAgICAgIHV0ZnguZW5jb2RlVVRGMTZ0b1VURjgoc3RyaW5nU291cmNlKHN0ciksIGZ1bmN0aW9uKGIpIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsrXSA9IGI7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb2Zmc2V0IC0gc3RhcnQ7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGFuIFVURjggZW5jb2RlZCBzdHJpbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVVVEY4U3RyaW5nfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IHRoaXMgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbi5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVN0cmluZyA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVVEY4U3RyaW5nO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIFVURjggY2hhcmFjdGVycyBvZiBhIHN0cmluZy4gSmF2YVNjcmlwdCBpdHNlbGYgdXNlcyBVVEYtMTYsIHNvIHRoYXQgYSBzdHJpbmcnc1xyXG4gICAgICogIGBsZW5ndGhgIHByb3BlcnR5IGRvZXMgbm90IHJlZmxlY3QgaXRzIGFjdHVhbCBVVEY4IHNpemUgaWYgaXQgY29udGFpbnMgY29kZSBwb2ludHMgbGFyZ2VyIHRoYW4gMHhGRkZGLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gY2FsY3VsYXRlXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgVVRGOCBjaGFyYWN0ZXJzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuY2FsY3VsYXRlVVRGOENoYXJzID0gZnVuY3Rpb24oc3RyKSB7XHJcbiAgICAgICAgcmV0dXJuIHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjgoc3RyaW5nU291cmNlKHN0cikpWzBdO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgdGhlIG51bWJlciBvZiBVVEY4IGJ5dGVzIG9mIGEgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gY2FsY3VsYXRlXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgVVRGOCBieXRlc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmNhbGN1bGF0ZVVURjhCeXRlcyA9IGZ1bmN0aW9uKHN0cikge1xyXG4gICAgICAgIHJldHVybiB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpKVsxXTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBudW1iZXIgb2YgVVRGOCBieXRlcyBvZiBhIHN0cmluZy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlci5jYWxjdWxhdGVVVEY4Qnl0ZXN9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBjYWxjdWxhdGVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBVVEY4IGJ5dGVzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuY2FsY3VsYXRlU3RyaW5nID0gQnl0ZUJ1ZmZlci5jYWxjdWxhdGVVVEY4Qnl0ZXM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhbiBVVEY4IGVuY29kZWQgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgY2hhcmFjdGVycyBvciBieXRlcyB0byByZWFkLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmc9fSBtZXRyaWNzIE1ldHJpY3Mgc3BlY2lmeWluZyB3aGF0IGBsZW5ndGhgIGlzIG1lYW50IHRvIGNvdW50LiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLk1FVFJJQ1NfQ0hBUlN9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8IXtzdHJpbmc6IHN0cmluZywgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgc3RyaW5nIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHN0cmluZ1xyXG4gICAgICogIHJlYWQgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVURjhTdHJpbmcgPSBmdW5jdGlvbihsZW5ndGgsIG1ldHJpY3MsIG9mZnNldCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgbWV0cmljcyA9PT0gJ251bWJlcicpIHtcclxuICAgICAgICAgICAgb2Zmc2V0ID0gbWV0cmljcztcclxuICAgICAgICAgICAgbWV0cmljcyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICh0eXBlb2YgbWV0cmljcyA9PT0gJ3VuZGVmaW5lZCcpIG1ldHJpY3MgPSBCeXRlQnVmZmVyLk1FVFJJQ1NfQ0hBUlM7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBsZW5ndGggJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgbGVuZ3RoOiBcIitsZW5ndGgrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIGxlbmd0aCB8PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBpID0gMCxcclxuICAgICAgICAgICAgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgICAgIHNkO1xyXG4gICAgICAgIGlmIChtZXRyaWNzID09PSBCeXRlQnVmZmVyLk1FVFJJQ1NfQ0hBUlMpIHsgLy8gVGhlIHNhbWUgZm9yIG5vZGUgYW5kIHRoZSBicm93c2VyXHJcbiAgICAgICAgICAgIHNkID0gc3RyaW5nRGVzdGluYXRpb24oKTtcclxuICAgICAgICAgICAgdXRmeC5kZWNvZGVVVEY4KGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGkgPCBsZW5ndGggJiYgb2Zmc2V0IDwgdGhpcy5saW1pdCA/IHRoaXMudmlld1tvZmZzZXQrK10gOiBudWxsO1xyXG4gICAgICAgICAgICB9LmJpbmQodGhpcyksIGZ1bmN0aW9uKGNwKSB7XHJcbiAgICAgICAgICAgICAgICArK2k7IHV0ZnguVVRGOHRvVVRGMTYoY3AsIHNkKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIGlmIChpICE9PSBsZW5ndGgpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogVHJ1bmNhdGVkIGRhdGEsIFwiK2krXCIgPT0gXCIrbGVuZ3RoKTtcclxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzZCgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBcInN0cmluZ1wiOiBzZCgpLFxyXG4gICAgICAgICAgICAgICAgICAgIFwibGVuZ3RoXCI6IG9mZnNldCAtIHN0YXJ0XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChtZXRyaWNzID09PSBCeXRlQnVmZmVyLk1FVFJJQ1NfQllURVMpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgbGVuZ3RoID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiK2xlbmd0aCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBrID0gb2Zmc2V0ICsgbGVuZ3RoO1xyXG4gICAgICAgICAgICB1dGZ4LmRlY29kZVVURjh0b1VURjE2KGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9mZnNldCA8IGsgPyB0aGlzLnZpZXdbb2Zmc2V0KytdIDogbnVsbDtcclxuICAgICAgICAgICAgfS5iaW5kKHRoaXMpLCBzZCA9IHN0cmluZ0Rlc3RpbmF0aW9uKCksIHRoaXMubm9Bc3NlcnQpO1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0ICE9PSBrKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IFRydW5jYXRlZCBkYXRhLCBcIitvZmZzZXQrXCIgPT0gXCIrayk7XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc2QoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgJ3N0cmluZyc6IHNkKCksXHJcbiAgICAgICAgICAgICAgICAgICAgJ2xlbmd0aCc6IG9mZnNldCAtIHN0YXJ0XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIlVuc3VwcG9ydGVkIG1ldHJpY3M6IFwiK21ldHJpY3MpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGFuIFVURjggZW5jb2RlZCBzdHJpbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZFVURjhTdHJpbmd9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBjaGFyYWN0ZXJzIG9yIGJ5dGVzIHRvIHJlYWRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gbWV0cmljcyBNZXRyaWNzIHNwZWNpZnlpbmcgd2hhdCBgbmAgaXMgbWVhbnQgdG8gY291bnQuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuTUVUUklDU19DSEFSU30uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcmVhZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ3whe3N0cmluZzogc3RyaW5nLCBsZW5ndGg6IG51bWJlcn19IFRoZSBzdHJpbmcgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgc3RyaW5nXHJcbiAgICAgKiAgcmVhZCBhbmQgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkU3RyaW5nID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVVRGOFN0cmluZztcclxuXHJcbiAgICAvLyB0eXBlcy9zdHJpbmdzL3ZzdHJpbmdcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIGxlbmd0aCBhcyB2YXJpbnQzMiBwcmVmaXhlZCBVVEY4IGVuY29kZWQgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IGB0aGlzYCBpZiBgb2Zmc2V0YCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciN3cml0ZVZhcmludDMyXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVWU3RyaW5nID0gZnVuY3Rpb24oc3RyLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBOb3QgYSBzdHJpbmdcIik7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgICAgIGssIGw7XHJcbiAgICAgICAgayA9IHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjgoc3RyaW5nU291cmNlKHN0ciksIHRoaXMubm9Bc3NlcnQpWzFdO1xyXG4gICAgICAgIGwgPSBCeXRlQnVmZmVyLmNhbGN1bGF0ZVZhcmludDMyKGspO1xyXG4gICAgICAgIG9mZnNldCArPSBsK2s7XG4gICAgICAgIHZhciBjYXBhY2l0eTE1ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MTUpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxNSAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MTUgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gbCtrO1xuICAgICAgICBvZmZzZXQgKz0gdGhpcy53cml0ZVZhcmludDMyKGssIG9mZnNldCk7XHJcbiAgICAgICAgdXRmeC5lbmNvZGVVVEYxNnRvVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgZnVuY3Rpb24oYikge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KytdID0gYjtcclxuICAgICAgICB9LmJpbmQodGhpcykpO1xyXG4gICAgICAgIGlmIChvZmZzZXQgIT09IHN0YXJ0K2srbClcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IFRydW5jYXRlZCBkYXRhLCBcIitvZmZzZXQrXCIgPT0gXCIrKG9mZnNldCtrK2wpKTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb2Zmc2V0IC0gc3RhcnQ7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSBsZW5ndGggYXMgdmFyaW50MzIgcHJlZml4ZWQgVVRGOCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfCF7c3RyaW5nOiBzdHJpbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHN0cmluZyByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBzdHJpbmdcclxuICAgICAqICByZWFkIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3JlYWRWYXJpbnQzMlxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRWU3RyaW5nID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMSA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzErXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0O1xyXG4gICAgICAgIHZhciBsZW4gPSB0aGlzLnJlYWRWYXJpbnQzMihvZmZzZXQpO1xyXG4gICAgICAgIHZhciBzdHIgPSB0aGlzLnJlYWRVVEY4U3RyaW5nKGxlblsndmFsdWUnXSwgQnl0ZUJ1ZmZlci5NRVRSSUNTX0JZVEVTLCBvZmZzZXQgKz0gbGVuWydsZW5ndGgnXSk7XHJcbiAgICAgICAgb2Zmc2V0ICs9IHN0clsnbGVuZ3RoJ107XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gc3RyWydzdHJpbmcnXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgJ3N0cmluZyc6IHN0clsnc3RyaW5nJ10sXHJcbiAgICAgICAgICAgICAgICAnbGVuZ3RoJzogb2Zmc2V0IC0gc3RhcnRcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGVuZHMgc29tZSBkYXRhIHRvIHRoaXMgQnl0ZUJ1ZmZlci4gVGhpcyB3aWxsIG92ZXJ3cml0ZSBhbnkgY29udGVudHMgYmVoaW5kIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IHVwIHRvIHRoZSBhcHBlbmRlZFxyXG4gICAgICogIGRhdGEncyBsZW5ndGguXHJcbiAgICAgKiBAcGFyYW0geyFCeXRlQnVmZmVyfCFBcnJheUJ1ZmZlcnwhVWludDhBcnJheXxzdHJpbmd9IHNvdXJjZSBEYXRhIHRvIGFwcGVuZC4gSWYgYHNvdXJjZWAgaXMgYSBCeXRlQnVmZmVyLCBpdHMgb2Zmc2V0c1xyXG4gICAgICogIHdpbGwgYmUgbW9kaWZpZWQgYWNjb3JkaW5nIHRvIHRoZSBwZXJmb3JtZWQgcmVhZCBvcGVyYXRpb24uXHJcbiAgICAgKiBAcGFyYW0geyhzdHJpbmd8bnVtYmVyKT19IGVuY29kaW5nIEVuY29kaW5nIGlmIGBkYXRhYCBpcyBhIHN0cmluZyAoXCJiYXNlNjRcIiwgXCJoZXhcIiwgXCJiaW5hcnlcIiwgZGVmYXVsdHMgdG8gXCJ1dGY4XCIpXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gYXBwZW5kIGF0LiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAZXhhbXBsZSBBIHJlbGF0aXZlIGA8MDEgMDI+MDMuYXBwZW5kKDwwNCAwNT4pYCB3aWxsIHJlc3VsdCBpbiBgPDAxIDAyIDA0IDA1PiwgMDQgMDV8YFxyXG4gICAgICogQGV4YW1wbGUgQW4gYWJzb2x1dGUgYDwwMSAwMj4wMy5hcHBlbmQoMDQgMDU+LCAxKWAgd2lsbCByZXN1bHQgaW4gYDwwMSAwND4wNSwgMDQgMDV8YFxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uKHNvdXJjZSwgZW5jb2RpbmcsIG9mZnNldCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdudW1iZXInIHx8IHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgb2Zmc2V0ID0gZW5jb2Rpbmc7XHJcbiAgICAgICAgICAgIGVuY29kaW5nID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIShzb3VyY2UgaW5zdGFuY2VvZiBCeXRlQnVmZmVyKSlcclxuICAgICAgICAgICAgc291cmNlID0gQnl0ZUJ1ZmZlci53cmFwKHNvdXJjZSwgZW5jb2RpbmcpO1xyXG4gICAgICAgIHZhciBsZW5ndGggPSBzb3VyY2UubGltaXQgLSBzb3VyY2Uub2Zmc2V0O1xyXG4gICAgICAgIGlmIChsZW5ndGggPD0gMCkgcmV0dXJuIHRoaXM7IC8vIE5vdGhpbmcgdG8gYXBwZW5kXHJcbiAgICAgICAgb2Zmc2V0ICs9IGxlbmd0aDtcbiAgICAgICAgdmFyIGNhcGFjaXR5MTYgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxNilcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTE2ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxNiA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSBsZW5ndGg7XG4gICAgICAgIHRoaXMudmlldy5zZXQoc291cmNlLnZpZXcuc3ViYXJyYXkoc291cmNlLm9mZnNldCwgc291cmNlLmxpbWl0KSwgb2Zmc2V0KTtcclxuICAgICAgICBzb3VyY2Uub2Zmc2V0ICs9IGxlbmd0aDtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IGxlbmd0aDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXBwZW5kcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cyB0byBhbm90aGVyIEJ5dGVCdWZmZXIuIFRoaXMgd2lsbCBvdmVyd3JpdGUgYW55IGNvbnRlbnRzIGF0IGFuZCBhZnRlciB0aGVcclxuICAgICAgICBzcGVjaWZpZWQgb2Zmc2V0IHVwIHRvIHRoZSBsZW5ndGggb2YgdGhpcyBCeXRlQnVmZmVyJ3MgZGF0YS5cclxuICAgICAqIEBwYXJhbSB7IUJ5dGVCdWZmZXJ9IHRhcmdldCBUYXJnZXQgQnl0ZUJ1ZmZlclxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIGFwcGVuZCB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI2FwcGVuZFxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmFwcGVuZFRvID0gZnVuY3Rpb24odGFyZ2V0LCBvZmZzZXQpIHtcclxuICAgICAgICB0YXJnZXQuYXBwZW5kKHRoaXMsIG9mZnNldCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5hYmxlcyBvciBkaXNhYmxlcyBhc3NlcnRpb25zIG9mIGFyZ3VtZW50IHR5cGVzIGFuZCBvZmZzZXRzLiBBc3NlcnRpb25zIGFyZSBlbmFibGVkIGJ5IGRlZmF1bHQgYnV0IHlvdSBjYW4gb3B0IHRvXHJcbiAgICAgKiAgZGlzYWJsZSB0aGVtIGlmIHlvdXIgY29kZSBhbHJlYWR5IG1ha2VzIHN1cmUgdGhhdCBldmVyeXRoaW5nIGlzIHZhbGlkLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBhc3NlcnQgYHRydWVgIHRvIGVuYWJsZSBhc3NlcnRpb25zLCBvdGhlcndpc2UgYGZhbHNlYFxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuYXNzZXJ0ID0gZnVuY3Rpb24oYXNzZXJ0KSB7XHJcbiAgICAgICAgdGhpcy5ub0Fzc2VydCA9ICFhc3NlcnQ7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgY2FwYWNpdHkgb2YgdGhpcyBCeXRlQnVmZmVyJ3MgYmFja2luZyBidWZmZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBDYXBhY2l0eSBvZiB0aGUgYmFja2luZyBidWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5jYXBhY2l0eSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2xlYXJzIHRoaXMgQnl0ZUJ1ZmZlcidzIG9mZnNldHMgYnkgc2V0dGluZyB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IHRvIGAwYCBhbmQge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9IHRvIHRoZVxyXG4gICAgICogIGJhY2tpbmcgYnVmZmVyJ3MgY2FwYWNpdHkuIERpc2NhcmRzIHtAbGluayBCeXRlQnVmZmVyI21hcmtlZE9mZnNldH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gMDtcclxuICAgICAgICB0aGlzLmxpbWl0ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcclxuICAgICAgICB0aGlzLm1hcmtlZE9mZnNldCA9IC0xO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBjbG9uZWQgaW5zdGFuY2Ugb2YgdGhpcyBCeXRlQnVmZmVyLCBwcmVzZXQgd2l0aCB0aGlzIEJ5dGVCdWZmZXIncyB2YWx1ZXMgZm9yIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0sXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjbWFya2VkT2Zmc2V0fSBhbmQge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gY29weSBXaGV0aGVyIHRvIGNvcHkgdGhlIGJhY2tpbmcgYnVmZmVyIG9yIHRvIHJldHVybiBhbm90aGVyIHZpZXcgb24gdGhlIHNhbWUsIGRlZmF1bHRzIHRvIGBmYWxzZWBcclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQ2xvbmVkIGluc3RhbmNlXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbihjb3B5KSB7XHJcbiAgICAgICAgdmFyIGJiID0gbmV3IEJ5dGVCdWZmZXIoMCwgdGhpcy5saXR0bGVFbmRpYW4sIHRoaXMubm9Bc3NlcnQpO1xyXG4gICAgICAgIGlmIChjb3B5KSB7XHJcbiAgICAgICAgICAgIGJiLmJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcih0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcclxuICAgICAgICAgICAgYmIudmlldyA9IG5ldyBVaW50OEFycmF5KGJiLmJ1ZmZlcik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYmIuYnVmZmVyID0gdGhpcy5idWZmZXI7XHJcbiAgICAgICAgICAgIGJiLnZpZXcgPSB0aGlzLnZpZXc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJiLm9mZnNldCA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGJiLm1hcmtlZE9mZnNldCA9IHRoaXMubWFya2VkT2Zmc2V0O1xyXG4gICAgICAgIGJiLmxpbWl0ID0gdGhpcy5saW1pdDtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcGFjdHMgdGhpcyBCeXRlQnVmZmVyIHRvIGJlIGJhY2tlZCBieSBhIHtAbGluayBCeXRlQnVmZmVyI2J1ZmZlcn0gb2YgaXRzIGNvbnRlbnRzJyBsZW5ndGguIENvbnRlbnRzIGFyZSB0aGUgYnl0ZXNcclxuICAgICAqICBiZXR3ZWVuIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS4gV2lsbCBzZXQgYG9mZnNldCA9IDBgIGFuZCBgbGltaXQgPSBjYXBhY2l0eWAgYW5kXHJcbiAgICAgKiAgYWRhcHQge0BsaW5rIEJ5dGVCdWZmZXIjbWFya2VkT2Zmc2V0fSB0byB0aGUgc2FtZSByZWxhdGl2ZSBwb3NpdGlvbiBpZiBzZXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIE9mZnNldCB0byBzdGFydCBhdCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgT2Zmc2V0IHRvIGVuZCBhdCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9XHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5jb21wYWN0ID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKSBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYmVnaW4gPT09IDAgJiYgZW5kID09PSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpczsgLy8gQWxyZWFkeSBjb21wYWN0ZWRcclxuICAgICAgICB2YXIgbGVuID0gZW5kIC0gYmVnaW47XHJcbiAgICAgICAgaWYgKGxlbiA9PT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IEVNUFRZX0JVRkZFUjtcclxuICAgICAgICAgICAgdGhpcy52aWV3ID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKHRoaXMubWFya2VkT2Zmc2V0ID49IDApIHRoaXMubWFya2VkT2Zmc2V0IC09IGJlZ2luO1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgIHRoaXMubGltaXQgPSAwO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihsZW4pO1xyXG4gICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcclxuICAgICAgICB2aWV3LnNldCh0aGlzLnZpZXcuc3ViYXJyYXkoYmVnaW4sIGVuZCkpO1xyXG4gICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyO1xyXG4gICAgICAgIHRoaXMudmlldyA9IHZpZXc7XHJcbiAgICAgICAgaWYgKHRoaXMubWFya2VkT2Zmc2V0ID49IDApIHRoaXMubWFya2VkT2Zmc2V0IC09IGJlZ2luO1xyXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gMDtcclxuICAgICAgICB0aGlzLmxpbWl0ID0gbGVuO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzIGJldHdlZW4ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmRcclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIEJlZ2luIG9mZnNldCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIEVuZCBvZmZzZXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQ29weVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKSBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGJlZ2luICE9PSAnbnVtYmVyJyB8fCBiZWdpbiAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBiZWdpbjogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBiZWdpbiA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuZCAhPT0gJ251bWJlcicgfHwgZW5kICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGVuZDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBlbmQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBiZWdpbiA+IGVuZCB8fCBlbmQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK2JlZ2luK1wiIDw9IFwiK2VuZCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChiZWdpbiA9PT0gZW5kKVxyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ5dGVCdWZmZXIoMCwgdGhpcy5saXR0bGVFbmRpYW4sIHRoaXMubm9Bc3NlcnQpO1xyXG4gICAgICAgIHZhciBjYXBhY2l0eSA9IGVuZCAtIGJlZ2luLFxyXG4gICAgICAgICAgICBiYiA9IG5ldyBCeXRlQnVmZmVyKGNhcGFjaXR5LCB0aGlzLmxpdHRsZUVuZGlhbiwgdGhpcy5ub0Fzc2VydCk7XHJcbiAgICAgICAgYmIub2Zmc2V0ID0gMDtcclxuICAgICAgICBiYi5saW1pdCA9IGNhcGFjaXR5O1xyXG4gICAgICAgIGlmIChiYi5tYXJrZWRPZmZzZXQgPj0gMCkgYmIubWFya2VkT2Zmc2V0IC09IGJlZ2luO1xyXG4gICAgICAgIHRoaXMuY29weVRvKGJiLCAwLCBiZWdpbiwgZW5kKTtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29waWVzIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzIHRvIGFub3RoZXIgQnl0ZUJ1ZmZlci4gQ29udGVudHMgYXJlIHRoZSBieXRlcyBiZXR3ZWVuIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcn0gdGFyZ2V0IFRhcmdldCBCeXRlQnVmZmVyXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IHRhcmdldE9mZnNldCBPZmZzZXQgdG8gY29weSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHRoZSB0YXJnZXQncyB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9XHJcbiAgICAgKiAgYnkgdGhlIG51bWJlciBvZiBieXRlcyBjb3BpZWQgaWYgb21pdHRlZC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gc291cmNlT2Zmc2V0IE9mZnNldCB0byBzdGFydCBjb3B5aW5nIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZVxyXG4gICAgICogIG51bWJlciBvZiBieXRlcyBjb3BpZWQgaWYgb21pdHRlZC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gc291cmNlTGltaXQgT2Zmc2V0IHRvIGVuZCBjb3B5aW5nIGZyb20sIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fVxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuY29weVRvID0gZnVuY3Rpb24odGFyZ2V0LCB0YXJnZXRPZmZzZXQsIHNvdXJjZU9mZnNldCwgc291cmNlTGltaXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUsXHJcbiAgICAgICAgICAgIHRhcmdldFJlbGF0aXZlO1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAoIUJ5dGVCdWZmZXIuaXNCeXRlQnVmZmVyKHRhcmdldCkpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHRhcmdldDogTm90IGEgQnl0ZUJ1ZmZlclwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGFyZ2V0T2Zmc2V0ID0gKHRhcmdldFJlbGF0aXZlID0gdHlwZW9mIHRhcmdldE9mZnNldCA9PT0gJ3VuZGVmaW5lZCcpID8gdGFyZ2V0Lm9mZnNldCA6IHRhcmdldE9mZnNldCB8IDA7XHJcbiAgICAgICAgc291cmNlT2Zmc2V0ID0gKHJlbGF0aXZlID0gdHlwZW9mIHNvdXJjZU9mZnNldCA9PT0gJ3VuZGVmaW5lZCcpID8gdGhpcy5vZmZzZXQgOiBzb3VyY2VPZmZzZXQgfCAwO1xyXG4gICAgICAgIHNvdXJjZUxpbWl0ID0gdHlwZW9mIHNvdXJjZUxpbWl0ID09PSAndW5kZWZpbmVkJyA/IHRoaXMubGltaXQgOiBzb3VyY2VMaW1pdCB8IDA7XHJcblxyXG4gICAgICAgIGlmICh0YXJnZXRPZmZzZXQgPCAwIHx8IHRhcmdldE9mZnNldCA+IHRhcmdldC5idWZmZXIuYnl0ZUxlbmd0aClcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgdGFyZ2V0IHJhbmdlOiAwIDw9IFwiK3RhcmdldE9mZnNldCtcIiA8PSBcIit0YXJnZXQuYnVmZmVyLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgIGlmIChzb3VyY2VPZmZzZXQgPCAwIHx8IHNvdXJjZUxpbWl0ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgc291cmNlIHJhbmdlOiAwIDw9IFwiK3NvdXJjZU9mZnNldCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcclxuXHJcbiAgICAgICAgdmFyIGxlbiA9IHNvdXJjZUxpbWl0IC0gc291cmNlT2Zmc2V0O1xyXG4gICAgICAgIGlmIChsZW4gPT09IDApXHJcbiAgICAgICAgICAgIHJldHVybiB0YXJnZXQ7IC8vIE5vdGhpbmcgdG8gY29weVxyXG5cclxuICAgICAgICB0YXJnZXQuZW5zdXJlQ2FwYWNpdHkodGFyZ2V0T2Zmc2V0ICsgbGVuKTtcclxuXHJcbiAgICAgICAgdGFyZ2V0LnZpZXcuc2V0KHRoaXMudmlldy5zdWJhcnJheShzb3VyY2VPZmZzZXQsIHNvdXJjZUxpbWl0KSwgdGFyZ2V0T2Zmc2V0KTtcclxuXHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSBsZW47XHJcbiAgICAgICAgaWYgKHRhcmdldFJlbGF0aXZlKSB0YXJnZXQub2Zmc2V0ICs9IGxlbjtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWFrZXMgc3VyZSB0aGF0IHRoaXMgQnl0ZUJ1ZmZlciBpcyBiYWNrZWQgYnkgYSB7QGxpbmsgQnl0ZUJ1ZmZlciNidWZmZXJ9IG9mIGF0IGxlYXN0IHRoZSBzcGVjaWZpZWQgY2FwYWNpdHkuIElmIHRoZVxyXG4gICAgICogIGN1cnJlbnQgY2FwYWNpdHkgaXMgZXhjZWVkZWQsIGl0IHdpbGwgYmUgZG91YmxlZC4gSWYgZG91YmxlIHRoZSBjdXJyZW50IGNhcGFjaXR5IGlzIGxlc3MgdGhhbiB0aGUgcmVxdWlyZWQgY2FwYWNpdHksXHJcbiAgICAgKiAgdGhlIHJlcXVpcmVkIGNhcGFjaXR5IHdpbGwgYmUgdXNlZCBpbnN0ZWFkLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNhcGFjaXR5IFJlcXVpcmVkIGNhcGFjaXR5XHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5lbnN1cmVDYXBhY2l0eSA9IGZ1bmN0aW9uKGNhcGFjaXR5KSB7XHJcbiAgICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xyXG4gICAgICAgIGlmIChjdXJyZW50IDwgY2FwYWNpdHkpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlc2l6ZSgoY3VycmVudCAqPSAyKSA+IGNhcGFjaXR5ID8gY3VycmVudCA6IGNhcGFjaXR5KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPdmVyd3JpdGVzIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZS4gQ29udGVudHMgYXJlIHRoZSBieXRlcyBiZXR3ZWVuXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmQge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ8c3RyaW5nfSB2YWx1ZSBCeXRlIHZhbHVlIHRvIGZpbGwgd2l0aC4gSWYgZ2l2ZW4gYXMgYSBzdHJpbmcsIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaXMgdXNlZC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gQmVnaW4gb2Zmc2V0LiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLiBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgRW5kIG9mZnNldCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAZXhhbXBsZSBgc29tZUJ5dGVCdWZmZXIuY2xlYXIoKS5maWxsKDApYCBmaWxscyB0aGUgZW50aXJlIGJhY2tpbmcgYnVmZmVyIHdpdGggemVyb2VzXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uKHZhbHVlLCBiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBiZWdpbiA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS5sZW5ndGggPiAwKVxyXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmNoYXJDb2RlQXQoMCk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKSBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGJlZ2luICE9PSAnbnVtYmVyJyB8fCBiZWdpbiAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBiZWdpbjogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBiZWdpbiA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuZCAhPT0gJ251bWJlcicgfHwgZW5kICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGVuZDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBlbmQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBiZWdpbiA+IGVuZCB8fCBlbmQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK2JlZ2luK1wiIDw9IFwiK2VuZCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChiZWdpbiA+PSBlbmQpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzOyAvLyBOb3RoaW5nIHRvIGZpbGxcclxuICAgICAgICB3aGlsZSAoYmVnaW4gPCBlbmQpIHRoaXMudmlld1tiZWdpbisrXSA9IHZhbHVlO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgPSBiZWdpbjtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYWtlcyB0aGlzIEJ5dGVCdWZmZXIgcmVhZHkgZm9yIGEgbmV3IHNlcXVlbmNlIG9mIHdyaXRlIG9yIHJlbGF0aXZlIHJlYWQgb3BlcmF0aW9ucy4gU2V0cyBgbGltaXQgPSBvZmZzZXRgIGFuZFxyXG4gICAgICogIGBvZmZzZXQgPSAwYC4gTWFrZSBzdXJlIGFsd2F5cyB0byBmbGlwIGEgQnl0ZUJ1ZmZlciB3aGVuIGFsbCByZWxhdGl2ZSByZWFkIG9yIHdyaXRlIG9wZXJhdGlvbnMgYXJlIGNvbXBsZXRlLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuZmxpcCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHRoaXMubGltaXQgPSB0aGlzLm9mZnNldDtcclxuICAgICAgICB0aGlzLm9mZnNldCA9IDA7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBNYXJrcyBhbiBvZmZzZXQgb24gdGhpcyBCeXRlQnVmZmVyIHRvIGJlIHVzZWQgbGF0ZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gbWFyay4gRGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNyZXNldFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLm1hcmsgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICBvZmZzZXQgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJyA/IHRoaXMub2Zmc2V0IDogb2Zmc2V0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5tYXJrZWRPZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBieXRlIG9yZGVyLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBsaXR0bGVFbmRpYW4gYHRydWVgIGZvciBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIsIGBmYWxzZWAgZm9yIGJpZyBlbmRpYW5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLm9yZGVyID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGl0dGxlRW5kaWFuICE9PSAnYm9vbGVhbicpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGxpdHRsZUVuZGlhbjogTm90IGEgYm9vbGVhblwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5saXR0bGVFbmRpYW4gPSAhIWxpdHRsZUVuZGlhbjtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTd2l0Y2hlcyAodG8pIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBEZWZhdWx0cyB0byBgdHJ1ZWAsIG90aGVyd2lzZSB1c2VzIGJpZyBlbmRpYW5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLkxFID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgdGhpcy5saXR0bGVFbmRpYW4gPSB0eXBlb2YgbGl0dGxlRW5kaWFuICE9PSAndW5kZWZpbmVkJyA/ICEhbGl0dGxlRW5kaWFuIDogdHJ1ZTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTd2l0Y2hlcyAodG8pIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGJpZ0VuZGlhbiBEZWZhdWx0cyB0byBgdHJ1ZWAsIG90aGVyd2lzZSB1c2VzIGxpdHRsZSBlbmRpYW5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLkJFID0gZnVuY3Rpb24oYmlnRW5kaWFuKSB7XHJcbiAgICAgICAgdGhpcy5saXR0bGVFbmRpYW4gPSB0eXBlb2YgYmlnRW5kaWFuICE9PSAndW5kZWZpbmVkJyA/ICFiaWdFbmRpYW4gOiBmYWxzZTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFByZXBlbmRzIHNvbWUgZGF0YSB0byB0aGlzIEJ5dGVCdWZmZXIuIFRoaXMgd2lsbCBvdmVyd3JpdGUgYW55IGNvbnRlbnRzIGJlZm9yZSB0aGUgc3BlY2lmaWVkIG9mZnNldCB1cCB0byB0aGVcclxuICAgICAqICBwcmVwZW5kZWQgZGF0YSdzIGxlbmd0aC4gSWYgdGhlcmUgaXMgbm90IGVub3VnaCBzcGFjZSBhdmFpbGFibGUgYmVmb3JlIHRoZSBzcGVjaWZpZWQgYG9mZnNldGAsIHRoZSBiYWNraW5nIGJ1ZmZlclxyXG4gICAgICogIHdpbGwgYmUgcmVzaXplZCBhbmQgaXRzIGNvbnRlbnRzIG1vdmVkIGFjY29yZGluZ2x5LlxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcnxzdHJpbmd8IUFycmF5QnVmZmVyfSBzb3VyY2UgRGF0YSB0byBwcmVwZW5kLiBJZiBgc291cmNlYCBpcyBhIEJ5dGVCdWZmZXIsIGl0cyBvZmZzZXQgd2lsbCBiZVxyXG4gICAgICogIG1vZGlmaWVkIGFjY29yZGluZyB0byB0aGUgcGVyZm9ybWVkIHJlYWQgb3BlcmF0aW9uLlxyXG4gICAgICogQHBhcmFtIHsoc3RyaW5nfG51bWJlcik9fSBlbmNvZGluZyBFbmNvZGluZyBpZiBgZGF0YWAgaXMgYSBzdHJpbmcgKFwiYmFzZTY0XCIsIFwiaGV4XCIsIFwiYmluYXJ5XCIsIGRlZmF1bHRzIHRvIFwidXRmOFwiKVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHByZXBlbmQgYXQuIFdpbGwgdXNlIGFuZCBkZWNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICBwcmVwZW5kZWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQGV4YW1wbGUgQSByZWxhdGl2ZSBgMDA8MDEgMDIgMDM+LnByZXBlbmQoPDA0IDA1PilgIHJlc3VsdHMgaW4gYDwwNCAwNSAwMSAwMiAwMz4sIDA0IDA1fGBcclxuICAgICAqIEBleGFtcGxlIEFuIGFic29sdXRlIGAwMDwwMSAwMiAwMz4ucHJlcGVuZCg8MDQgMDU+LCAyKWAgcmVzdWx0cyBpbiBgMDQ8MDUgMDIgMDM+LCAwNCAwNXxgXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucHJlcGVuZCA9IGZ1bmN0aW9uKHNvdXJjZSwgZW5jb2RpbmcsIG9mZnNldCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdudW1iZXInIHx8IHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgb2Zmc2V0ID0gZW5jb2Rpbmc7XHJcbiAgICAgICAgICAgIGVuY29kaW5nID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIShzb3VyY2UgaW5zdGFuY2VvZiBCeXRlQnVmZmVyKSlcclxuICAgICAgICAgICAgc291cmNlID0gQnl0ZUJ1ZmZlci53cmFwKHNvdXJjZSwgZW5jb2RpbmcpO1xyXG4gICAgICAgIHZhciBsZW4gPSBzb3VyY2UubGltaXQgLSBzb3VyY2Uub2Zmc2V0O1xyXG4gICAgICAgIGlmIChsZW4gPD0gMCkgcmV0dXJuIHRoaXM7IC8vIE5vdGhpbmcgdG8gcHJlcGVuZFxyXG4gICAgICAgIHZhciBkaWZmID0gbGVuIC0gb2Zmc2V0O1xyXG4gICAgICAgIGlmIChkaWZmID4gMCkgeyAvLyBOb3QgZW5vdWdoIHNwYWNlIGJlZm9yZSBvZmZzZXQsIHNvIHJlc2l6ZSArIG1vdmVcclxuICAgICAgICAgICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcih0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoICsgZGlmZik7XHJcbiAgICAgICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcclxuICAgICAgICAgICAgdmlldy5zZXQodGhpcy52aWV3LnN1YmFycmF5KG9mZnNldCwgdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCksIGxlbik7XHJcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyO1xyXG4gICAgICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCArPSBkaWZmO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5tYXJrZWRPZmZzZXQgPj0gMCkgdGhpcy5tYXJrZWRPZmZzZXQgKz0gZGlmZjtcclxuICAgICAgICAgICAgdGhpcy5saW1pdCArPSBkaWZmO1xyXG4gICAgICAgICAgICBvZmZzZXQgKz0gZGlmZjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgYXJyYXlWaWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5idWZmZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnZpZXcuc2V0KHNvdXJjZS52aWV3LnN1YmFycmF5KHNvdXJjZS5vZmZzZXQsIHNvdXJjZS5saW1pdCksIG9mZnNldCAtIGxlbik7XHJcblxyXG4gICAgICAgIHNvdXJjZS5vZmZzZXQgPSBzb3VyY2UubGltaXQ7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKVxyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCAtPSBsZW47XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUHJlcGVuZHMgdGhpcyBCeXRlQnVmZmVyIHRvIGFub3RoZXIgQnl0ZUJ1ZmZlci4gVGhpcyB3aWxsIG92ZXJ3cml0ZSBhbnkgY29udGVudHMgYmVmb3JlIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IHVwIHRvIHRoZVxyXG4gICAgICogIHByZXBlbmRlZCBkYXRhJ3MgbGVuZ3RoLiBJZiB0aGVyZSBpcyBub3QgZW5vdWdoIHNwYWNlIGF2YWlsYWJsZSBiZWZvcmUgdGhlIHNwZWNpZmllZCBgb2Zmc2V0YCwgdGhlIGJhY2tpbmcgYnVmZmVyXHJcbiAgICAgKiAgd2lsbCBiZSByZXNpemVkIGFuZCBpdHMgY29udGVudHMgbW92ZWQgYWNjb3JkaW5nbHkuXHJcbiAgICAgKiBAcGFyYW0geyFCeXRlQnVmZmVyfSB0YXJnZXQgVGFyZ2V0IEJ5dGVCdWZmZXJcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byBwcmVwZW5kIGF0LiBXaWxsIHVzZSBhbmQgZGVjcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcHJlcGVuZGVkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNwcmVwZW5kXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucHJlcGVuZFRvID0gZnVuY3Rpb24odGFyZ2V0LCBvZmZzZXQpIHtcclxuICAgICAgICB0YXJnZXQucHJlcGVuZCh0aGlzLCBvZmZzZXQpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUHJpbnRzIGRlYnVnIGluZm9ybWF0aW9uIGFib3V0IHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzLlxyXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbihzdHJpbmcpPX0gb3V0IE91dHB1dCBmdW5jdGlvbiB0byBjYWxsLCBkZWZhdWx0cyB0byBjb25zb2xlLmxvZ1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnByaW50RGVidWcgPSBmdW5jdGlvbihvdXQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIG91dCAhPT0gJ2Z1bmN0aW9uJykgb3V0ID0gY29uc29sZS5sb2cuYmluZChjb25zb2xlKTtcclxuICAgICAgICBvdXQoXHJcbiAgICAgICAgICAgIHRoaXMudG9TdHJpbmcoKStcIlxcblwiK1xyXG4gICAgICAgICAgICBcIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cXG5cIitcclxuICAgICAgICAgICAgdGhpcy50b0RlYnVnKC8qIGNvbHVtbnMgKi8gdHJ1ZSlcclxuICAgICAgICApO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIG51bWJlciBvZiByZW1haW5pbmcgcmVhZGFibGUgYnl0ZXMuIENvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYmV0d2VlbiB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZFxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fSwgc28gdGhpcyByZXR1cm5zIGBsaW1pdCAtIG9mZnNldGAuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZW1haW5pbmcgcmVhZGFibGUgYnl0ZXMuIE1heSBiZSBuZWdhdGl2ZSBpZiBgb2Zmc2V0ID4gbGltaXRgLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlbWFpbmluZyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxpbWl0IC0gdGhpcy5vZmZzZXQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXNldHMgdGhpcyBCeXRlQnVmZmVyJ3Mge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS4gSWYgYW4gb2Zmc2V0IGhhcyBiZWVuIG1hcmtlZCB0aHJvdWdoIHtAbGluayBCeXRlQnVmZmVyI21hcmt9XHJcbiAgICAgKiAgYmVmb3JlLCBgb2Zmc2V0YCB3aWxsIGJlIHNldCB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNtYXJrZWRPZmZzZXR9LCB3aGljaCB3aWxsIHRoZW4gYmUgZGlzY2FyZGVkLiBJZiBubyBvZmZzZXQgaGFzIGJlZW5cclxuICAgICAqICBtYXJrZWQsIHNldHMgYG9mZnNldCA9IDBgLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjbWFya1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgaWYgKHRoaXMubWFya2VkT2Zmc2V0ID49IDApIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSB0aGlzLm1hcmtlZE9mZnNldDtcclxuICAgICAgICAgICAgdGhpcy5tYXJrZWRPZmZzZXQgPSAtMTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVzaXplcyB0aGlzIEJ5dGVCdWZmZXIgdG8gYmUgYmFja2VkIGJ5IGEgYnVmZmVyIG9mIGF0IGxlYXN0IHRoZSBnaXZlbiBjYXBhY2l0eS4gV2lsbCBkbyBub3RoaW5nIGlmIGFscmVhZHkgdGhhdFxyXG4gICAgICogIGxhcmdlIG9yIGxhcmdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjYXBhY2l0eSBDYXBhY2l0eSByZXF1aXJlZFxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBjYXBhY2l0eWAgaXMgbm90IGEgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgY2FwYWNpdHkgPCAwYFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlc2l6ZSA9IGZ1bmN0aW9uKGNhcGFjaXR5KSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY2FwYWNpdHkgIT09ICdudW1iZXInIHx8IGNhcGFjaXR5ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGNhcGFjaXR5OiBcIitjYXBhY2l0eStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgY2FwYWNpdHkgfD0gMDtcbiAgICAgICAgICAgIGlmIChjYXBhY2l0eSA8IDApXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBjYXBhY2l0eTogMCA8PSBcIitjYXBhY2l0eSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoIDwgY2FwYWNpdHkpIHtcclxuICAgICAgICAgICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihjYXBhY2l0eSk7XHJcbiAgICAgICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcclxuICAgICAgICAgICAgdmlldy5zZXQodGhpcy52aWV3KTtcclxuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBidWZmZXI7XHJcbiAgICAgICAgICAgIHRoaXMudmlldyA9IHZpZXc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV2ZXJzZXMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIE9mZnNldCB0byBzdGFydCBhdCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgT2Zmc2V0IHRvIGVuZCBhdCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9XHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZXZlcnNlID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKSBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYmVnaW4gPT09IGVuZClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7IC8vIE5vdGhpbmcgdG8gcmV2ZXJzZVxyXG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5yZXZlcnNlLmNhbGwodGhpcy52aWV3LnN1YmFycmF5KGJlZ2luLCBlbmQpKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNraXBzIHRoZSBuZXh0IGBsZW5ndGhgIGJ5dGVzLiBUaGlzIHdpbGwganVzdCBhZHZhbmNlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBieXRlcyB0byBza2lwLiBNYXkgYWxzbyBiZSBuZWdhdGl2ZSB0byBtb3ZlIHRoZSBvZmZzZXQgYmFjay5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnNraXAgPSBmdW5jdGlvbihsZW5ndGgpIHtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBsZW5ndGggIT09ICdudW1iZXInIHx8IGxlbmd0aCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBsZW5ndGg6IFwiK2xlbmd0aCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgbGVuZ3RoIHw9IDA7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5vZmZzZXQgKyBsZW5ndGg7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBsZW5ndGg6IDAgPD0gXCIrdGhpcy5vZmZzZXQrXCIgKyBcIitsZW5ndGgrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNsaWNlcyB0aGlzIEJ5dGVCdWZmZXIgYnkgY3JlYXRpbmcgYSBjbG9uZWQgaW5zdGFuY2Ugd2l0aCBgb2Zmc2V0ID0gYmVnaW5gIGFuZCBgbGltaXQgPSBlbmRgLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBCZWdpbiBvZmZzZXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBFbmQgb2Zmc2V0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IENsb25lIG9mIHRoaXMgQnl0ZUJ1ZmZlciB3aXRoIHNsaWNpbmcgYXBwbGllZCwgYmFja2VkIGJ5IHRoZSBzYW1lIHtAbGluayBCeXRlQnVmZmVyI2J1ZmZlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJykgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmVnaW4gIT09ICdudW1iZXInIHx8IGJlZ2luICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJlZ2luOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGJlZ2luID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kICE9PSAnbnVtYmVyJyB8fCBlbmQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgZW5kOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGVuZCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGJlZ2luID4gZW5kIHx8IGVuZCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrYmVnaW4rXCIgPD0gXCIrZW5kK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGJiID0gdGhpcy5jbG9uZSgpO1xyXG4gICAgICAgIGJiLm9mZnNldCA9IGJlZ2luO1xyXG4gICAgICAgIGJiLmxpbWl0ID0gZW5kO1xyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSBjb3B5IG9mIHRoZSBiYWNraW5nIGJ1ZmZlciB0aGF0IGNvbnRhaW5zIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzIGJldHdlZW5cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBmb3JjZUNvcHkgSWYgYHRydWVgIHJldHVybnMgYSBjb3B5LCBvdGhlcndpc2UgcmV0dXJucyBhIHZpZXcgcmVmZXJlbmNpbmcgdGhlIHNhbWUgbWVtb3J5IGlmXHJcbiAgICAgKiAgcG9zc2libGUuIERlZmF1bHRzIHRvIGBmYWxzZWBcclxuICAgICAqIEByZXR1cm5zIHshQXJyYXlCdWZmZXJ9IENvbnRlbnRzIGFzIGFuIEFycmF5QnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbihmb3JjZUNvcHkpIHtcclxuICAgICAgICB2YXIgb2Zmc2V0ID0gdGhpcy5vZmZzZXQsXHJcbiAgICAgICAgICAgIGxpbWl0ID0gdGhpcy5saW1pdDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGltaXQgIT09ICdudW1iZXInIHx8IGxpbWl0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGxpbWl0OiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGxpbWl0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCA+IGxpbWl0IHx8IGxpbWl0ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitvZmZzZXQrXCIgPD0gXCIrbGltaXQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICAvLyBOT1RFOiBJdCdzIG5vdCBwb3NzaWJsZSB0byBoYXZlIGFub3RoZXIgQXJyYXlCdWZmZXIgcmVmZXJlbmNlIHRoZSBzYW1lIG1lbW9yeSBhcyB0aGUgYmFja2luZyBidWZmZXIuIFRoaXMgaXNcclxuICAgICAgICAvLyBwb3NzaWJsZSB3aXRoIFVpbnQ4QXJyYXkjc3ViYXJyYXkgb25seSwgYnV0IHdlIGhhdmUgdG8gcmV0dXJuIGFuIEFycmF5QnVmZmVyIGJ5IGNvbnRyYWN0LiBTbzpcclxuICAgICAgICBpZiAoIWZvcmNlQ29weSAmJiBvZmZzZXQgPT09IDAgJiYgbGltaXQgPT09IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlcjtcclxuICAgICAgICBpZiAob2Zmc2V0ID09PSBsaW1pdClcclxuICAgICAgICAgICAgcmV0dXJuIEVNUFRZX0JVRkZFUjtcclxuICAgICAgICB2YXIgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGxpbWl0IC0gb2Zmc2V0KTtcclxuICAgICAgICBuZXcgVWludDhBcnJheShidWZmZXIpLnNldChuZXcgVWludDhBcnJheSh0aGlzLmJ1ZmZlcikuc3ViYXJyYXkob2Zmc2V0LCBsaW1pdCksIDApO1xyXG4gICAgICAgIHJldHVybiBidWZmZXI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIHJhdyBidWZmZXIgY29tcGFjdGVkIHRvIGNvbnRhaW4gdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMuIENvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYmV0d2VlblxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN0b0J1ZmZlcn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGZvcmNlQ29weSBJZiBgdHJ1ZWAgcmV0dXJucyBhIGNvcHksIG90aGVyd2lzZSByZXR1cm5zIGEgdmlldyByZWZlcmVuY2luZyB0aGUgc2FtZSBtZW1vcnkuXHJcbiAgICAgKiAgRGVmYXVsdHMgdG8gYGZhbHNlYFxyXG4gICAgICogQHJldHVybnMgeyFBcnJheUJ1ZmZlcn0gQ29udGVudHMgYXMgYW4gQXJyYXlCdWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0J1ZmZlcjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBCeXRlQnVmZmVyJ3MgY29udGVudHMgdG8gYSBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZz19IGVuY29kaW5nIE91dHB1dCBlbmNvZGluZy4gUmV0dXJucyBhbiBpbmZvcm1hdGl2ZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gaWYgb21pdHRlZCBidXQgYWxzbyBhbGxvd3NcclxuICAgICAqICBkaXJlY3QgY29udmVyc2lvbiB0byBcInV0ZjhcIiwgXCJoZXhcIiwgXCJiYXNlNjRcIiBhbmQgXCJiaW5hcnlcIiBlbmNvZGluZy4gXCJkZWJ1Z1wiIHJldHVybnMgYSBoZXggcmVwcmVzZW50YXRpb24gd2l0aFxyXG4gICAgICogIGhpZ2hsaWdodGVkIG9mZnNldHMuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIE9mZnNldCB0byBiZWdpbiBhdCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgT2Zmc2V0IHRvIGVuZCBhdCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9XHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBTdHJpbmcgcmVwcmVzZW50YXRpb25cclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBgZW5jb2RpbmdgIGlzIGludmFsaWRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKGVuY29kaW5nLCBiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIHJldHVybiBcIkJ5dGVCdWZmZXJBQihvZmZzZXQ9XCIrdGhpcy5vZmZzZXQrXCIsbWFya2VkT2Zmc2V0PVwiK3RoaXMubWFya2VkT2Zmc2V0K1wiLGxpbWl0PVwiK3RoaXMubGltaXQrXCIsY2FwYWNpdHk9XCIrdGhpcy5jYXBhY2l0eSgpK1wiKVwiO1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICBlbmNvZGluZyA9IFwidXRmOFwiLFxyXG4gICAgICAgICAgICBiZWdpbiA9IGVuY29kaW5nLFxyXG4gICAgICAgICAgICBlbmQgPSBiZWdpbjtcclxuICAgICAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJ1dGY4XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b1VURjgoYmVnaW4sIGVuZCk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJiYXNlNjRcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQmFzZTY0KGJlZ2luLCBlbmQpO1xyXG4gICAgICAgICAgICBjYXNlIFwiaGV4XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0hleChiZWdpbiwgZW5kKTtcclxuICAgICAgICAgICAgY2FzZSBcImJpbmFyeVwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9CaW5hcnkoYmVnaW4sIGVuZCk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJkZWJ1Z1wiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9EZWJ1ZygpO1xyXG4gICAgICAgICAgICBjYXNlIFwiY29sdW1uc1wiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9Db2x1bW5zKCk7XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcIlVuc3VwcG9ydGVkIGVuY29kaW5nOiBcIitlbmNvZGluZyk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBseGl2LWVtYmVkZGFibGVcclxuXHJcbiAgICAvKipcclxuICAgICAqIGx4aXYtZW1iZWRkYWJsZSAoYykgMjAxNCBEYW5pZWwgV2lydHogPGRjb2RlQGRjb2RlLmlvPlxyXG4gICAgICogUmVsZWFzZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMFxyXG4gICAgICogc2VlOiBodHRwczovL2dpdGh1Yi5jb20vZGNvZGVJTy9seGl2IGZvciBkZXRhaWxzXHJcbiAgICAgKi9cclxuICAgIHZhciBseGl2ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIGx4aXYgbmFtZXNwYWNlLlxyXG4gICAgICAgICAqIEB0eXBlIHshT2JqZWN0LjxzdHJpbmcsKj59XHJcbiAgICAgICAgICogQGV4cG9ydHMgbHhpdlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHZhciBseGl2ID0ge307XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENoYXJhY3RlciBjb2RlcyBmb3Igb3V0cHV0LlxyXG4gICAgICAgICAqIEB0eXBlIHshQXJyYXkuPG51bWJlcj59XHJcbiAgICAgICAgICogQGlubmVyXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmFyIGFvdXQgPSBbXHJcbiAgICAgICAgICAgIDY1LCA2NiwgNjcsIDY4LCA2OSwgNzAsIDcxLCA3MiwgNzMsIDc0LCA3NSwgNzYsIDc3LCA3OCwgNzksIDgwLFxyXG4gICAgICAgICAgICA4MSwgODIsIDgzLCA4NCwgODUsIDg2LCA4NywgODgsIDg5LCA5MCwgOTcsIDk4LCA5OSwgMTAwLCAxMDEsIDEwMixcclxuICAgICAgICAgICAgMTAzLCAxMDQsIDEwNSwgMTA2LCAxMDcsIDEwOCwgMTA5LCAxMTAsIDExMSwgMTEyLCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LFxyXG4gICAgICAgICAgICAxMTksIDEyMCwgMTIxLCAxMjIsIDQ4LCA0OSwgNTAsIDUxLCA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA0MywgNDdcclxuICAgICAgICBdO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDaGFyYWN0ZXIgY29kZXMgZm9yIGlucHV0LlxyXG4gICAgICAgICAqIEB0eXBlIHshQXJyYXkuPG51bWJlcj59XHJcbiAgICAgICAgICogQGlubmVyXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmFyIGFpbiA9IFtdO1xyXG4gICAgICAgIGZvciAodmFyIGk9MCwgaz1hb3V0Lmxlbmd0aDsgaTxrOyArK2kpXHJcbiAgICAgICAgICAgIGFpblthb3V0W2ldXSA9IGk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEVuY29kZXMgYnl0ZXMgdG8gYmFzZTY0IGNoYXIgY29kZXMuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24oKTpudW1iZXJ8bnVsbH0gc3JjIEJ5dGVzIHNvdXJjZSBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBieXRlIHJlc3BlY3RpdmVseSBgbnVsbGAgaWZcclxuICAgICAgICAgKiAgdGhlcmUgYXJlIG5vIG1vcmUgYnl0ZXMgbGVmdC5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbihudW1iZXIpfSBkc3QgQ2hhcmFjdGVycyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCBlYWNoIGVuY29kZWQgY2hhclxyXG4gICAgICAgICAqICBjb2RlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGx4aXYuZW5jb2RlID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdmFyIGIsIHQ7XHJcbiAgICAgICAgICAgIHdoaWxlICgoYiA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgZHN0KGFvdXRbKGI+PjIpJjB4M2ZdKTtcclxuICAgICAgICAgICAgICAgIHQgPSAoYiYweDMpPDw0O1xyXG4gICAgICAgICAgICAgICAgaWYgKChiID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdCB8PSAoYj4+NCkmMHhmO1xyXG4gICAgICAgICAgICAgICAgICAgIGRzdChhb3V0Wyh0fCgoYj4+NCkmMHhmKSkmMHgzZl0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHQgPSAoYiYweGYpPDwyO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgoYiA9IHNyYygpKSAhPT0gbnVsbClcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHN0KGFvdXRbKHR8KChiPj42KSYweDMpKSYweDNmXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRzdChhb3V0W2ImMHgzZl0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHN0KGFvdXRbdCYweDNmXSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRzdCg2MSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBkc3QoYW91dFt0JjB4M2ZdKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoNjEpLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCg2MSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWNvZGVzIGJhc2U2NCBjaGFyIGNvZGVzIHRvIGJ5dGVzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCk6bnVtYmVyfG51bGx9IHNyYyBDaGFyYWN0ZXJzIHNvdXJjZSBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjaGFyIGNvZGUgcmVzcGVjdGl2ZWx5XHJcbiAgICAgICAgICogIGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IEJ5dGVzIGRlc3RpbmF0aW9uIGFzIGEgZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIHRoZSBuZXh0IGJ5dGUuXHJcbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIGEgY2hhcmFjdGVyIGNvZGUgaXMgaW52YWxpZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGx4aXYuZGVjb2RlID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdmFyIGMsIHQxLCB0MjtcclxuICAgICAgICAgICAgZnVuY3Rpb24gZmFpbChjKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcIklsbGVnYWwgY2hhcmFjdGVyIGNvZGU6IFwiK2MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHdoaWxlICgoYyA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgdDEgPSBhaW5bY107XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHQxID09PSAndW5kZWZpbmVkJykgZmFpbChjKTtcclxuICAgICAgICAgICAgICAgIGlmICgoYyA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHQyID0gYWluW2NdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdDIgPT09ICd1bmRlZmluZWQnKSBmYWlsKGMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgodDE8PDIpPj4+MHwodDImMHgzMCk+PjQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgoYyA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0MSA9IGFpbltjXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0MSA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PT0gNjEpIGJyZWFrOyBlbHNlIGZhaWwoYyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRzdCgoKHQyJjB4Zik8PDQpPj4+MHwodDEmMHgzYyk+PjIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoKGMgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQyID0gYWluW2NdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0MiA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT09IDYxKSBicmVhazsgZWxzZSBmYWlsKGMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0KCgodDEmMHgzKTw8Nik+Pj4wfHQyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRlc3RzIGlmIGEgc3RyaW5nIGlzIHZhbGlkIGJhc2U2NC5cclxuICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byB0ZXN0XHJcbiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIGBmYWxzZWBcclxuICAgICAgICAgKi9cclxuICAgICAgICBseGl2LnRlc3QgPSBmdW5jdGlvbihzdHIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIC9eKD86W0EtWmEtejAtOSsvXXs0fSkqKD86W0EtWmEtejAtOSsvXXsyfT09fFtBLVphLXowLTkrL117M309KT8kLy50ZXN0KHN0cik7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGx4aXY7XHJcbiAgICB9KCk7XHJcblxyXG4gICAgLy8gZW5jb2RpbmdzL2Jhc2U2NFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cyB0byBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gT2Zmc2V0IHRvIGJlZ2luIGF0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgT2Zmc2V0IHRvIGVuZCBhdCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gQmFzZTY0IGVuY29kZWQgc3RyaW5nXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgYmVnaW5gIG9yIGBlbmRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0Jhc2U2NCA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgYmVnaW4gPSBiZWdpbiB8IDA7IGVuZCA9IGVuZCB8IDA7XHJcbiAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBlbmQgPiB0aGlzLmNhcGFjaXR5IHx8IGJlZ2luID4gZW5kKVxyXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiYmVnaW4sIGVuZFwiKTtcclxuICAgICAgICB2YXIgc2Q7IGx4aXYuZW5jb2RlKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gYmVnaW4gPCBlbmQgPyB0aGlzLnZpZXdbYmVnaW4rK10gOiBudWxsO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSwgc2QgPSBzdHJpbmdEZXN0aW5hdGlvbigpKTtcclxuICAgICAgICByZXR1cm4gc2QoKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nIHRvIGEgQnl0ZUJ1ZmZlci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGRlY29kZVxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBCeXRlQnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuZnJvbUJhc2U2NCA9IGZ1bmN0aW9uKHN0ciwgbGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxyXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJzdHJcIik7XHJcbiAgICAgICAgdmFyIGJiID0gbmV3IEJ5dGVCdWZmZXIoc3RyLmxlbmd0aC80KjMsIGxpdHRsZUVuZGlhbiksXHJcbiAgICAgICAgICAgIGkgPSAwO1xyXG4gICAgICAgIGx4aXYuZGVjb2RlKHN0cmluZ1NvdXJjZShzdHIpLCBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgIGJiLnZpZXdbaSsrXSA9IGI7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgYmIubGltaXQgPSBpO1xyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmNvZGVzIGEgYmluYXJ5IHN0cmluZyB0byBiYXNlNjQgbGlrZSBgd2luZG93LmJ0b2FgIGRvZXMuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIEJpbmFyeSBzdHJpbmdcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEJhc2U2NCBlbmNvZGVkIHN0cmluZ1xyXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2luZG93LmJ0b2FcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5idG9hID0gZnVuY3Rpb24oc3RyKSB7XHJcbiAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbUJpbmFyeShzdHIpLnRvQmFzZTY0KCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZyB0byBiaW5hcnkgbGlrZSBgd2luZG93LmF0b2JgIGRvZXMuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYjY0IEJhc2U2NCBlbmNvZGVkIHN0cmluZ1xyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gQmluYXJ5IHN0cmluZ1xyXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2luZG93LmF0b2JcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5hdG9iID0gZnVuY3Rpb24oYjY0KSB7XHJcbiAgICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuZnJvbUJhc2U2NChiNjQpLnRvQmluYXJ5KCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIGVuY29kaW5ncy9iaW5hcnlcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuY29kZXMgdGhpcyBCeXRlQnVmZmVyIHRvIGEgYmluYXJ5IGVuY29kZWQgc3RyaW5nLCB0aGF0IGlzIHVzaW5nIG9ubHkgY2hhcmFjdGVycyAweDAwLTB4RkYgYXMgYnl0ZXMuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIE9mZnNldCB0byBiZWdpbiBhdC4gRGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEJpbmFyeSBlbmNvZGVkIHN0cmluZ1xyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldCA+IGxpbWl0YFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnRvQmluYXJ5ID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBiZWdpbiB8PSAwOyBlbmQgfD0gMDtcclxuICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGVuZCA+IHRoaXMuY2FwYWNpdHkoKSB8fCBiZWdpbiA+IGVuZClcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcImJlZ2luLCBlbmRcIik7XHJcbiAgICAgICAgaWYgKGJlZ2luID09PSBlbmQpXHJcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgICAgIHZhciBjaGFycyA9IFtdLFxyXG4gICAgICAgICAgICBwYXJ0cyA9IFtdO1xyXG4gICAgICAgIHdoaWxlIChiZWdpbiA8IGVuZCkge1xyXG4gICAgICAgICAgICBjaGFycy5wdXNoKHRoaXMudmlld1tiZWdpbisrXSk7XHJcbiAgICAgICAgICAgIGlmIChjaGFycy5sZW5ndGggPj0gMTAyNClcclxuICAgICAgICAgICAgICAgIHBhcnRzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNoYXJzKSksXHJcbiAgICAgICAgICAgICAgICBjaGFycyA9IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcGFydHMuam9pbignJykgKyBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2hhcnMpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY29kZXMgYSBiaW5hcnkgZW5jb2RlZCBzdHJpbmcsIHRoYXQgaXMgdXNpbmcgb25seSBjaGFyYWN0ZXJzIDB4MDAtMHhGRiBhcyBieXRlcywgdG8gYSBCeXRlQnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gZGVjb2RlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IEJ5dGVCdWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5mcm9tQmluYXJ5ID0gZnVuY3Rpb24oc3RyLCBsaXR0bGVFbmRpYW4pIHtcclxuICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcInN0clwiKTtcclxuICAgICAgICB2YXIgaSA9IDAsXHJcbiAgICAgICAgICAgIGsgPSBzdHIubGVuZ3RoLFxyXG4gICAgICAgICAgICBjaGFyQ29kZSxcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcihrLCBsaXR0bGVFbmRpYW4pO1xyXG4gICAgICAgIHdoaWxlIChpPGspIHtcclxuICAgICAgICAgICAgY2hhckNvZGUgPSBzdHIuY2hhckNvZGVBdChpKTtcclxuICAgICAgICAgICAgaWYgKGNoYXJDb2RlID4gMHhmZilcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJpbGxlZ2FsIGNoYXIgY29kZTogXCIrY2hhckNvZGUpO1xyXG4gICAgICAgICAgICBiYi52aWV3W2krK10gPSBjaGFyQ29kZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYmIubGltaXQgPSBrO1xyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgLy8gZW5jb2RpbmdzL2RlYnVnXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmNvZGVzIHRoaXMgQnl0ZUJ1ZmZlciB0byBhIGhleCBlbmNvZGVkIHN0cmluZyB3aXRoIG1hcmtlZCBvZmZzZXRzLiBPZmZzZXQgc3ltYm9scyBhcmU6XHJcbiAgICAgKiAqIGA8YCA6IG9mZnNldCxcclxuICAgICAqICogYCdgIDogbWFya2VkT2Zmc2V0LFxyXG4gICAgICogKiBgPmAgOiBsaW1pdCxcclxuICAgICAqICogYHxgIDogb2Zmc2V0IGFuZCBsaW1pdCxcclxuICAgICAqICogYFtgIDogb2Zmc2V0IGFuZCBtYXJrZWRPZmZzZXQsXHJcbiAgICAgKiAqIGBdYCA6IG1hcmtlZE9mZnNldCBhbmQgbGltaXQsXHJcbiAgICAgKiAqIGAhYCA6IG9mZnNldCwgbWFya2VkT2Zmc2V0IGFuZCBsaW1pdFxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gY29sdW1ucyBJZiBgdHJ1ZWAgcmV0dXJucyB0d28gY29sdW1ucyBoZXggKyBhc2NpaSwgZGVmYXVsdHMgdG8gYGZhbHNlYFxyXG4gICAgICogQHJldHVybnMge3N0cmluZ3whQXJyYXkuPHN0cmluZz59IERlYnVnIHN0cmluZyBvciBhcnJheSBvZiBsaW5lcyBpZiBgYXNBcnJheSA9IHRydWVgXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAZXhhbXBsZSBgPjAwJzAxIDAyPDAzYCBjb250YWlucyBmb3VyIGJ5dGVzIHdpdGggYGxpbWl0PTAsIG1hcmtlZE9mZnNldD0xLCBvZmZzZXQ9M2BcclxuICAgICAqIEBleGFtcGxlIGAwMFswMSAwMiAwMz5gIGNvbnRhaW5zIGZvdXIgYnl0ZXMgd2l0aCBgb2Zmc2V0PW1hcmtlZE9mZnNldD0xLCBsaW1pdD00YFxyXG4gICAgICogQGV4YW1wbGUgYDAwfDAxIDAyIDAzYCBjb250YWlucyBmb3VyIGJ5dGVzIHdpdGggYG9mZnNldD1saW1pdD0xLCBtYXJrZWRPZmZzZXQ9LTFgXHJcbiAgICAgKiBAZXhhbXBsZSBgfGAgY29udGFpbnMgemVybyBieXRlcyB3aXRoIGBvZmZzZXQ9bGltaXQ9MCwgbWFya2VkT2Zmc2V0PS0xYFxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnRvRGVidWcgPSBmdW5jdGlvbihjb2x1bW5zKSB7XHJcbiAgICAgICAgdmFyIGkgPSAtMSxcclxuICAgICAgICAgICAgayA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgsXHJcbiAgICAgICAgICAgIGIsXHJcbiAgICAgICAgICAgIGhleCA9IFwiXCIsXHJcbiAgICAgICAgICAgIGFzYyA9IFwiXCIsXHJcbiAgICAgICAgICAgIG91dCA9IFwiXCI7XHJcbiAgICAgICAgd2hpbGUgKGk8aykge1xyXG4gICAgICAgICAgICBpZiAoaSAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoYiA8IDB4MTApIGhleCArPSBcIjBcIitiLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBoZXggKz0gYi50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgIGlmIChjb2x1bW5zKVxyXG4gICAgICAgICAgICAgICAgICAgIGFzYyArPSBiID4gMzIgJiYgYiA8IDEyNyA/IFN0cmluZy5mcm9tQ2hhckNvZGUoYikgOiAnLic7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKytpO1xyXG4gICAgICAgICAgICBpZiAoY29sdW1ucykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGkgPiAwICYmIGkgJSAxNiA9PT0gMCAmJiBpICE9PSBrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGhleC5sZW5ndGggPCAzKjE2KzMpIGhleCArPSBcIiBcIjtcclxuICAgICAgICAgICAgICAgICAgICBvdXQgKz0gaGV4K2FzYytcIlxcblwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGhleCA9IGFzYyA9IFwiXCI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGkgPT09IHRoaXMub2Zmc2V0ICYmIGkgPT09IHRoaXMubGltaXQpXHJcbiAgICAgICAgICAgICAgICBoZXggKz0gaSA9PT0gdGhpcy5tYXJrZWRPZmZzZXQgPyBcIiFcIiA6IFwifFwiO1xyXG4gICAgICAgICAgICBlbHNlIGlmIChpID09PSB0aGlzLm9mZnNldClcclxuICAgICAgICAgICAgICAgIGhleCArPSBpID09PSB0aGlzLm1hcmtlZE9mZnNldCA/IFwiW1wiIDogXCI8XCI7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGkgPT09IHRoaXMubGltaXQpXHJcbiAgICAgICAgICAgICAgICBoZXggKz0gaSA9PT0gdGhpcy5tYXJrZWRPZmZzZXQgPyBcIl1cIiA6IFwiPlwiO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICBoZXggKz0gaSA9PT0gdGhpcy5tYXJrZWRPZmZzZXQgPyBcIidcIiA6IChjb2x1bW5zIHx8IChpICE9PSAwICYmIGkgIT09IGspID8gXCIgXCIgOiBcIlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNvbHVtbnMgJiYgaGV4ICE9PSBcIiBcIikge1xyXG4gICAgICAgICAgICB3aGlsZSAoaGV4Lmxlbmd0aCA8IDMqMTYrMylcclxuICAgICAgICAgICAgICAgIGhleCArPSBcIiBcIjtcclxuICAgICAgICAgICAgb3V0ICs9IGhleCArIGFzYyArIFwiXFxuXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjb2x1bW5zID8gb3V0IDogaGV4O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY29kZXMgYSBoZXggZW5jb2RlZCBzdHJpbmcgd2l0aCBtYXJrZWQgb2Zmc2V0cyB0byBhIEJ5dGVCdWZmZXIuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIERlYnVnIHN0cmluZyB0byBkZWNvZGUgKG5vdCBiZSBnZW5lcmF0ZWQgd2l0aCBgY29sdW1ucyA9IHRydWVgKVxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbm9Bc3NlcnQgV2hldGhlciB0byBza2lwIGFzc2VydGlvbnMgb2Ygb2Zmc2V0cyBhbmQgdmFsdWVzLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBCeXRlQnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjdG9EZWJ1Z1xyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmZyb21EZWJ1ZyA9IGZ1bmN0aW9uKHN0ciwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xyXG4gICAgICAgIHZhciBrID0gc3RyLmxlbmd0aCxcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcigoKGsrMSkvMyl8MCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCk7XHJcbiAgICAgICAgdmFyIGkgPSAwLCBqID0gMCwgY2gsIGIsXHJcbiAgICAgICAgICAgIHJzID0gZmFsc2UsIC8vIFJlcXVpcmUgc3ltYm9sIG5leHRcclxuICAgICAgICAgICAgaG8gPSBmYWxzZSwgaG0gPSBmYWxzZSwgaGwgPSBmYWxzZSwgLy8gQWxyZWFkeSBoYXMgb2Zmc2V0IChobyksIG1hcmtlZE9mZnNldCAoaG0pLCBsaW1pdCAoaGwpP1xyXG4gICAgICAgICAgICBmYWlsID0gZmFsc2U7XHJcbiAgICAgICAgd2hpbGUgKGk8aykge1xyXG4gICAgICAgICAgICBzd2l0Y2ggKGNoID0gc3RyLmNoYXJBdChpKyspKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlICchJzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobyB8fCBobSB8fCBobCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobyA9IGhtID0gaGwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi5vZmZzZXQgPSBiYi5tYXJrZWRPZmZzZXQgPSBiYi5saW1pdCA9IGo7XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ3wnOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhvIHx8IGhsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvID0gaGwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi5vZmZzZXQgPSBiYi5saW1pdCA9IGo7XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ1snOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhvIHx8IGhtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvID0gaG0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi5vZmZzZXQgPSBiYi5tYXJrZWRPZmZzZXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICc8JzpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChobykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBobyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLm9mZnNldCA9IGo7XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJ10nOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhsIHx8IGhtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhsID0gaG0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi5saW1pdCA9IGJiLm1hcmtlZE9mZnNldCA9IGo7XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJz4nOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIubGltaXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiJ1wiOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhtID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIubWFya2VkT2Zmc2V0ID0gajtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnICc6XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYiA9IHBhcnNlSW50KGNoK3N0ci5jaGFyQXQoaSsrKSwgMTYpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmFOKGIpIHx8IGIgPCAwIHx8IGIgPiAyNTUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgZGVidWcgZW5jb2RlZCBzdHJpbmdcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLnZpZXdbaisrXSA9IGI7XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChmYWlsKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IEludmFsaWQgc3ltYm9sIGF0IFwiK2kpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICghaG8gfHwgIWhsKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE1pc3Npbmcgb2Zmc2V0IG9yIGxpbWl0XCIpO1xyXG4gICAgICAgICAgICBpZiAoajxiYi5idWZmZXIuYnl0ZUxlbmd0aClcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBOb3QgYSBkZWJ1ZyBlbmNvZGVkIHN0cmluZyAoaXMgaXQgaGV4PykgXCIraitcIiA8IFwiK2spO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIGVuY29kaW5ncy9oZXhcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuY29kZXMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMgdG8gYSBoZXggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIE9mZnNldCB0byBiZWdpbiBhdC4gRGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIE9mZnNldCB0byBlbmQgYXQuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEhleCBlbmNvZGVkIHN0cmluZ1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGJlZ2luID0gdHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJyA/IHRoaXMub2Zmc2V0IDogYmVnaW47XHJcbiAgICAgICAgZW5kID0gdHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLmxpbWl0IDogZW5kO1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGJlZ2luICE9PSAnbnVtYmVyJyB8fCBiZWdpbiAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBiZWdpbjogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBiZWdpbiA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuZCAhPT0gJ251bWJlcicgfHwgZW5kICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGVuZDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBlbmQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBiZWdpbiA+IGVuZCB8fCBlbmQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK2JlZ2luK1wiIDw9IFwiK2VuZCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBvdXQgPSBuZXcgQXJyYXkoZW5kIC0gYmVnaW4pLFxyXG4gICAgICAgICAgICBiO1xyXG4gICAgICAgIHdoaWxlIChiZWdpbiA8IGVuZCkge1xyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W2JlZ2luKytdO1xyXG4gICAgICAgICAgICBpZiAoYiA8IDB4MTApXHJcbiAgICAgICAgICAgICAgICBvdXQucHVzaChcIjBcIiwgYi50b1N0cmluZygxNikpO1xyXG4gICAgICAgICAgICBlbHNlIG91dC5wdXNoKGIudG9TdHJpbmcoMTYpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG91dC5qb2luKCcnKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGEgaGV4IGVuY29kZWQgc3RyaW5nIHRvIGEgQnl0ZUJ1ZmZlci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGRlY29kZVxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbm9Bc3NlcnQgV2hldGhlciB0byBza2lwIGFzc2VydGlvbnMgb2Ygb2Zmc2V0cyBhbmQgdmFsdWVzLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBCeXRlQnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuZnJvbUhleCA9IGZ1bmN0aW9uKHN0ciwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xyXG4gICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE5vdCBhIHN0cmluZ1wiKTtcclxuICAgICAgICAgICAgaWYgKHN0ci5sZW5ndGggJSAyICE9PSAwKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IExlbmd0aCBub3QgYSBtdWx0aXBsZSBvZiAyXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgayA9IHN0ci5sZW5ndGgsXHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoKGsgLyAyKSB8IDAsIGxpdHRsZUVuZGlhbiksXHJcbiAgICAgICAgICAgIGI7XHJcbiAgICAgICAgZm9yICh2YXIgaT0wLCBqPTA7IGk8azsgaSs9Mikge1xyXG4gICAgICAgICAgICBiID0gcGFyc2VJbnQoc3RyLnN1YnN0cmluZyhpLCBpKzIpLCAxNik7XHJcbiAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpXHJcbiAgICAgICAgICAgICAgICBpZiAoIWlzRmluaXRlKGIpIHx8IGIgPCAwIHx8IGIgPiAyNTUpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IENvbnRhaW5zIG5vbi1oZXggY2hhcmFjdGVyc1wiKTtcclxuICAgICAgICAgICAgYmIudmlld1tqKytdID0gYjtcclxuICAgICAgICB9XHJcbiAgICAgICAgYmIubGltaXQgPSBqO1xyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgLy8gdXRmeC1lbWJlZGRhYmxlXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiB1dGZ4LWVtYmVkZGFibGUgKGMpIDIwMTQgRGFuaWVsIFdpcnR6IDxkY29kZUBkY29kZS5pbz5cclxuICAgICAqIFJlbGVhc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjBcclxuICAgICAqIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vdXRmeCBmb3IgZGV0YWlsc1xyXG4gICAgICovXHJcbiAgICB2YXIgdXRmeCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIFwidXNlIHN0cmljdFwiO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiB1dGZ4IG5hbWVzcGFjZS5cclxuICAgICAgICAgKiBAaW5uZXJcclxuICAgICAgICAgKiBAdHlwZSB7IU9iamVjdC48c3RyaW5nLCo+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHZhciB1dGZ4ID0ge307XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE1heGltdW0gdmFsaWQgY29kZSBwb2ludC5cclxuICAgICAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICAgICAqIEBjb25zdFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguTUFYX0NPREVQT0lOVCA9IDB4MTBGRkZGO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBFbmNvZGVzIFVURjggY29kZSBwb2ludHMgdG8gVVRGOCBieXRlcy5cclxuICAgICAgICAgKiBAcGFyYW0geyghZnVuY3Rpb24oKTpudW1iZXJ8bnVsbCkgfCBudW1iZXJ9IHNyYyBDb2RlIHBvaW50cyBzb3VyY2UsIGVpdGhlciBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjb2RlIHBvaW50XHJcbiAgICAgICAgICogIHJlc3BlY3RpdmVseSBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY29kZSBwb2ludHMgbGVmdCBvciBhIHNpbmdsZSBudW1lcmljIGNvZGUgcG9pbnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IEJ5dGVzIGRlc3RpbmF0aW9uIGFzIGEgZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIHRoZSBuZXh0IGJ5dGVcclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LmVuY29kZVVURjggPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB2YXIgY3AgPSBudWxsO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHNyYyA9PT0gJ251bWJlcicpXHJcbiAgICAgICAgICAgICAgICBjcCA9IHNyYyxcclxuICAgICAgICAgICAgICAgIHNyYyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gbnVsbDsgfTtcclxuICAgICAgICAgICAgd2hpbGUgKGNwICE9PSBudWxsIHx8IChjcCA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNwIDwgMHg4MClcclxuICAgICAgICAgICAgICAgICAgICBkc3QoY3AmMHg3Rik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChjcCA8IDB4ODAwKVxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGNwPj42KSYweDFGKXwweEMwKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKGNwJjB4M0YpfDB4ODApO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY3AgPCAweDEwMDAwKVxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGNwPj4xMikmMHgwRil8MHhFMCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoY3A+PjYpJjB4M0YpfDB4ODApLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoY3AmMHgzRil8MHg4MCk7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoY3A+PjE4KSYweDA3KXwweEYwKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChjcD4+MTIpJjB4M0YpfDB4ODApLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGNwPj42KSYweDNGKXwweDgwKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKGNwJjB4M0YpfDB4ODApO1xyXG4gICAgICAgICAgICAgICAgY3AgPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRGVjb2RlcyBVVEY4IGJ5dGVzIHRvIFVURjggY29kZSBwb2ludHMuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24oKTpudW1iZXJ8bnVsbH0gc3JjIEJ5dGVzIHNvdXJjZSBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBieXRlIHJlc3BlY3RpdmVseSBgbnVsbGAgaWYgdGhlcmVcclxuICAgICAgICAgKiAgYXJlIG5vIG1vcmUgYnl0ZXMgbGVmdC5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbihudW1iZXIpfSBkc3QgQ29kZSBwb2ludHMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggZWFjaCBkZWNvZGVkIGNvZGUgcG9pbnQuXHJcbiAgICAgICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYSBzdGFydGluZyBieXRlIGlzIGludmFsaWQgaW4gVVRGOFxyXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgbGFzdCBzZXF1ZW5jZSBpcyB0cnVuY2F0ZWQuIEhhcyBhbiBhcnJheSBwcm9wZXJ0eSBgYnl0ZXNgIGhvbGRpbmcgdGhlXHJcbiAgICAgICAgICogIHJlbWFpbmluZyBieXRlcy5cclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LmRlY29kZVVURjggPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB2YXIgYSwgYiwgYywgZCwgZmFpbCA9IGZ1bmN0aW9uKGIpIHtcclxuICAgICAgICAgICAgICAgIGIgPSBiLnNsaWNlKDAsIGIuaW5kZXhPZihudWxsKSk7XHJcbiAgICAgICAgICAgICAgICB2YXIgZXJyID0gRXJyb3IoYi50b1N0cmluZygpKTtcclxuICAgICAgICAgICAgICAgIGVyci5uYW1lID0gXCJUcnVuY2F0ZWRFcnJvclwiO1xyXG4gICAgICAgICAgICAgICAgZXJyWydieXRlcyddID0gYjtcclxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgd2hpbGUgKChhID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoKGEmMHg4MCkgPT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KGEpO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKGEmMHhFMCkgPT09IDB4QzApXHJcbiAgICAgICAgICAgICAgICAgICAgKChiID0gc3JjKCkpID09PSBudWxsKSAmJiBmYWlsKFthLCBiXSksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoYSYweDFGKTw8NikgfCAoYiYweDNGKSk7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICgoYSYweEYwKSA9PT0gMHhFMClcclxuICAgICAgICAgICAgICAgICAgICAoKGI9c3JjKCkpID09PSBudWxsIHx8IChjPXNyYygpKSA9PT0gbnVsbCkgJiYgZmFpbChbYSwgYiwgY10pLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGEmMHgwRik8PDEyKSB8ICgoYiYweDNGKTw8NikgfCAoYyYweDNGKSk7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICgoYSYweEY4KSA9PT0gMHhGMClcclxuICAgICAgICAgICAgICAgICAgICAoKGI9c3JjKCkpID09PSBudWxsIHx8IChjPXNyYygpKSA9PT0gbnVsbCB8fCAoZD1zcmMoKSkgPT09IG51bGwpICYmIGZhaWwoW2EsIGIsIGMgLGRdKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChhJjB4MDcpPDwxOCkgfCAoKGImMHgzRik8PDEyKSB8ICgoYyYweDNGKTw8NikgfCAoZCYweDNGKSk7XHJcbiAgICAgICAgICAgICAgICBlbHNlIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHN0YXJ0aW5nIGJ5dGU6IFwiK2EpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ29udmVydHMgVVRGMTYgY2hhcmFjdGVycyB0byBVVEY4IGNvZGUgcG9pbnRzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCk6bnVtYmVyfG51bGx9IHNyYyBDaGFyYWN0ZXJzIHNvdXJjZSBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjaGFyIGNvZGUgcmVzcGVjdGl2ZWx5XHJcbiAgICAgICAgICogIGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IENvZGUgcG9pbnRzIGRlc3RpbmF0aW9uIGFzIGEgZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIGVhY2ggY29udmVydGVkIGNvZGVcclxuICAgICAgICAgKiAgcG9pbnQuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5VVEYxNnRvVVRGOCA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHZhciBjMSwgYzIgPSBudWxsO1xyXG4gICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKChjMSA9IGMyICE9PSBudWxsID8gYzIgOiBzcmMoKSkgPT09IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBpZiAoYzEgPj0gMHhEODAwICYmIGMxIDw9IDB4REZGRikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgoYzIgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMyID49IDB4REMwMCAmJiBjMiA8PSAweERGRkYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdCgoYzEtMHhEODAwKSoweDQwMCtjMi0weERDMDArMHgxMDAwMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjMiA9IG51bGw7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZHN0KGMxKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoYzIgIT09IG51bGwpIGRzdChjMik7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ29udmVydHMgVVRGOCBjb2RlIHBvaW50cyB0byBVVEYxNiBjaGFyYWN0ZXJzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7KCFmdW5jdGlvbigpOm51bWJlcnxudWxsKSB8IG51bWJlcn0gc3JjIENvZGUgcG9pbnRzIHNvdXJjZSwgZWl0aGVyIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGNvZGUgcG9pbnRcclxuICAgICAgICAgKiAgcmVzcGVjdGl2ZWx5IGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gbW9yZSBjb2RlIHBvaW50cyBsZWZ0IG9yIGEgc2luZ2xlIG51bWVyaWMgY29kZSBwb2ludC5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbihudW1iZXIpfSBkc3QgQ2hhcmFjdGVycyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCBlYWNoIGNvbnZlcnRlZCBjaGFyIGNvZGUuXHJcbiAgICAgICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYSBjb2RlIHBvaW50IGlzIG91dCBvZiByYW5nZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguVVRGOHRvVVRGMTYgPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB2YXIgY3AgPSBudWxsO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHNyYyA9PT0gJ251bWJlcicpXHJcbiAgICAgICAgICAgICAgICBjcCA9IHNyYywgc3JjID0gZnVuY3Rpb24oKSB7IHJldHVybiBudWxsOyB9O1xyXG4gICAgICAgICAgICB3aGlsZSAoY3AgIT09IG51bGwgfHwgKGNwID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY3AgPD0gMHhGRkZGKVxyXG4gICAgICAgICAgICAgICAgICAgIGRzdChjcCk7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgY3AgLT0gMHgxMDAwMCxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKGNwPj4xMCkrMHhEODAwKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKGNwJTB4NDAwKSsweERDMDApO1xyXG4gICAgICAgICAgICAgICAgY3AgPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ29udmVydHMgYW5kIGVuY29kZXMgVVRGMTYgY2hhcmFjdGVycyB0byBVVEY4IGJ5dGVzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKCk6bnVtYmVyfG51bGx9IHNyYyBDaGFyYWN0ZXJzIHNvdXJjZSBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjaGFyIGNvZGUgcmVzcGVjdGl2ZWx5IGBudWxsYFxyXG4gICAgICAgICAqICBpZiB0aGVyZSBhcmUgbm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24obnVtYmVyKX0gZHN0IEJ5dGVzIGRlc3RpbmF0aW9uIGFzIGEgZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIHRoZSBuZXh0IGJ5dGUuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5lbmNvZGVVVEYxNnRvVVRGOCA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHV0ZnguVVRGMTZ0b1VURjgoc3JjLCBmdW5jdGlvbihjcCkge1xyXG4gICAgICAgICAgICAgICAgdXRmeC5lbmNvZGVVVEY4KGNwLCBkc3QpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWNvZGVzIGFuZCBjb252ZXJ0cyBVVEY4IGJ5dGVzIHRvIFVURjE2IGNoYXJhY3RlcnMuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24oKTpudW1iZXJ8bnVsbH0gc3JjIEJ5dGVzIHNvdXJjZSBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBieXRlIHJlc3BlY3RpdmVseSBgbnVsbGAgaWYgdGhlcmVcclxuICAgICAgICAgKiAgYXJlIG5vIG1vcmUgYnl0ZXMgbGVmdC5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbihudW1iZXIpfSBkc3QgQ2hhcmFjdGVycyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCBlYWNoIGNvbnZlcnRlZCBjaGFyIGNvZGUuXHJcbiAgICAgICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYSBzdGFydGluZyBieXRlIGlzIGludmFsaWQgaW4gVVRGOFxyXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgbGFzdCBzZXF1ZW5jZSBpcyB0cnVuY2F0ZWQuIEhhcyBhbiBhcnJheSBwcm9wZXJ0eSBgYnl0ZXNgIGhvbGRpbmcgdGhlIHJlbWFpbmluZyBieXRlcy5cclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LmRlY29kZVVURjh0b1VURjE2ID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdXRmeC5kZWNvZGVVVEY4KHNyYywgZnVuY3Rpb24oY3ApIHtcclxuICAgICAgICAgICAgICAgIHV0ZnguVVRGOHRvVVRGMTYoY3AsIGRzdCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENhbGN1bGF0ZXMgdGhlIGJ5dGUgbGVuZ3RoIG9mIGFuIFVURjggY29kZSBwb2ludC5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gY3AgVVRGOCBjb2RlIHBvaW50XHJcbiAgICAgICAgICogQHJldHVybnMge251bWJlcn0gQnl0ZSBsZW5ndGhcclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LmNhbGN1bGF0ZUNvZGVQb2ludCA9IGZ1bmN0aW9uKGNwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAoY3AgPCAweDgwKSA/IDEgOiAoY3AgPCAweDgwMCkgPyAyIDogKGNwIDwgMHgxMDAwMCkgPyAzIDogNDtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDYWxjdWxhdGVzIHRoZSBudW1iZXIgb2YgVVRGOCBieXRlcyByZXF1aXJlZCB0byBzdG9yZSBVVEY4IGNvZGUgcG9pbnRzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7KCFmdW5jdGlvbigpOm51bWJlcnxudWxsKX0gc3JjIENvZGUgcG9pbnRzIHNvdXJjZSBhcyBhIGZ1bmN0aW9uIHJldHVybmluZyB0aGUgbmV4dCBjb2RlIHBvaW50IHJlc3BlY3RpdmVseVxyXG4gICAgICAgICAqICBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY29kZSBwb2ludHMgbGVmdC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIFVURjggYnl0ZXMgcmVxdWlyZWRcclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LmNhbGN1bGF0ZVVURjggPSBmdW5jdGlvbihzcmMpIHtcclxuICAgICAgICAgICAgdmFyIGNwLCBsPTA7XHJcbiAgICAgICAgICAgIHdoaWxlICgoY3AgPSBzcmMoKSkgIT09IG51bGwpXHJcbiAgICAgICAgICAgICAgICBsICs9IChjcCA8IDB4ODApID8gMSA6IChjcCA8IDB4ODAwKSA/IDIgOiAoY3AgPCAweDEwMDAwKSA/IDMgOiA0O1xyXG4gICAgICAgICAgICByZXR1cm4gbDtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDYWxjdWxhdGVzIHRoZSBudW1iZXIgb2YgVVRGOCBjb2RlIHBvaW50cyByZXNwZWN0aXZlbHkgVVRGOCBieXRlcyByZXF1aXJlZCB0byBzdG9yZSBVVEYxNiBjaGFyIGNvZGVzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7KCFmdW5jdGlvbigpOm51bWJlcnxudWxsKX0gc3JjIENoYXJhY3RlcnMgc291cmNlIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGNoYXIgY29kZSByZXNwZWN0aXZlbHlcclxuICAgICAgICAgKiAgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBtb3JlIGNoYXJhY3RlcnMgbGVmdC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBUaGUgbnVtYmVyIG9mIFVURjggY29kZSBwb2ludHMgYXQgaW5kZXggMCBhbmQgdGhlIG51bWJlciBvZiBVVEY4IGJ5dGVzIHJlcXVpcmVkIGF0IGluZGV4IDEuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOCA9IGZ1bmN0aW9uKHNyYykge1xyXG4gICAgICAgICAgICB2YXIgbj0wLCBsPTA7XHJcbiAgICAgICAgICAgIHV0ZnguVVRGMTZ0b1VURjgoc3JjLCBmdW5jdGlvbihjcCkge1xyXG4gICAgICAgICAgICAgICAgKytuOyBsICs9IChjcCA8IDB4ODApID8gMSA6IChjcCA8IDB4ODAwKSA/IDIgOiAoY3AgPCAweDEwMDAwKSA/IDMgOiA0O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIFtuLGxdO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiB1dGZ4O1xyXG4gICAgfSgpO1xyXG5cclxuICAgIC8vIGVuY29kaW5ncy91dGY4XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmNvZGVzIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzIGJldHdlZW4ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmQge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9IHRvIGFuIFVURjggZW5jb2RlZFxyXG4gICAgICogIHN0cmluZy5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEhleCBlbmNvZGVkIHN0cmluZ1xyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldCA+IGxpbWl0YFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnRvVVRGOCA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJykgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmVnaW4gIT09ICdudW1iZXInIHx8IGJlZ2luICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJlZ2luOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGJlZ2luID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kICE9PSAnbnVtYmVyJyB8fCBlbmQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgZW5kOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGVuZCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGJlZ2luID4gZW5kIHx8IGVuZCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrYmVnaW4rXCIgPD0gXCIrZW5kK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHNkOyB0cnkge1xyXG4gICAgICAgICAgICB1dGZ4LmRlY29kZVVURjh0b1VURjE2KGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJlZ2luIDwgZW5kID8gdGhpcy52aWV3W2JlZ2luKytdIDogbnVsbDtcclxuICAgICAgICAgICAgfS5iaW5kKHRoaXMpLCBzZCA9IHN0cmluZ0Rlc3RpbmF0aW9uKCkpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgaWYgKGJlZ2luICE9PSBlbmQpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogVHJ1bmNhdGVkIGRhdGEsIFwiK2JlZ2luK1wiICE9IFwiK2VuZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzZCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY29kZXMgYW4gVVRGOCBlbmNvZGVkIHN0cmluZyB0byBhIEJ5dGVCdWZmZXIuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBkZWNvZGVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcy4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmZyb21VVEY4ID0gZnVuY3Rpb24oc3RyLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XHJcbiAgICAgICAgaWYgKCFub0Fzc2VydClcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE5vdCBhIHN0cmluZ1wiKTtcclxuICAgICAgICB2YXIgYmIgPSBuZXcgQnl0ZUJ1ZmZlcih1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpLCB0cnVlKVsxXSwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCksXHJcbiAgICAgICAgICAgIGkgPSAwO1xyXG4gICAgICAgIHV0ZnguZW5jb2RlVVRGMTZ0b1VURjgoc3RyaW5nU291cmNlKHN0ciksIGZ1bmN0aW9uKGIpIHtcclxuICAgICAgICAgICAgYmIudmlld1tpKytdID0gYjtcclxuICAgICAgICB9KTtcclxuICAgICAgICBiYi5saW1pdCA9IGk7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gQnl0ZUJ1ZmZlcjtcclxufSk7XHJcbiIsInZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcblxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIGlmICh0aGlzLl9maW5hbCkge1xuICAgIHRoaXMuX19maW5hbCA9IHRoaXMuX2ZpbmFsXG4gICAgdGhpcy5fZmluYWwgPSBudWxsXG4gIH1cbiAgdGhpcy5fZGVjb2RlciA9IG51bGxcbiAgdGhpcy5fZW5jb2RpbmcgPSBudWxsXG59XG5pbmhlcml0cyhDaXBoZXJCYXNlLCBUcmFuc2Zvcm0pXG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBpbnB1dEVuYywgb3V0cHV0RW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBkYXRhID0gQnVmZmVyLmZyb20oZGF0YSwgaW5wdXRFbmMpXG4gIH1cblxuICB2YXIgb3V0RGF0YSA9IHRoaXMuX3VwZGF0ZShkYXRhKVxuICBpZiAodGhpcy5oYXNoTW9kZSkgcmV0dXJuIHRoaXNcblxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuXG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKCkge31cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9fZmluYWwoKSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfVxuXG4gIGRvbmUoZXJyKVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZpbmFsT3JEaWdlc3QgPSBmdW5jdGlvbiAob3V0cHV0RW5jKSB7XG4gIHZhciBvdXREYXRhID0gdGhpcy5fX2ZpbmFsKCkgfHwgQnVmZmVyLmFsbG9jKDApXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW4pIHtcbiAgaWYgKCF0aGlzLl9kZWNvZGVyKSB7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYylcbiAgICB0aGlzLl9lbmNvZGluZyA9IGVuY1xuICB9XG5cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHRocm93IG5ldyBFcnJvcignY2FuXFwndCBzd2l0Y2ggZW5jb2RpbmdzJylcblxuICB2YXIgb3V0ID0gdGhpcy5fZGVjb2Rlci53cml0ZSh2YWx1ZSlcbiAgaWYgKGZpbikge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cblxuICByZXR1cm4gb3V0XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5cbmZ1bmN0aW9uIGlzQXJyYXkoYXJnKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXJnKTtcbiAgfVxuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcoYXJnKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIChvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyB8fCBlIGluc3RhbmNlb2YgRXJyb3IpO1xufVxuZXhwb3J0cy5pc0Vycm9yID0gaXNFcnJvcjtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnIHx8ICAvLyBFUzYgc3ltYm9sXG4gICAgICAgICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcbn1cbmV4cG9ydHMuaXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZTtcblxuZXhwb3J0cy5pc0J1ZmZlciA9IEJ1ZmZlci5pc0J1ZmZlcjtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuIiwiJ3VzZSBzdHJpY3QnXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgTUQ1ID0gcmVxdWlyZSgnbWQ1LmpzJylcbnZhciBSSVBFTUQxNjAgPSByZXF1aXJlKCdyaXBlbWQxNjAnKVxudmFyIHNoYSA9IHJlcXVpcmUoJ3NoYS5qcycpXG52YXIgQmFzZSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcblxuZnVuY3Rpb24gSGFzaCAoaGFzaCkge1xuICBCYXNlLmNhbGwodGhpcywgJ2RpZ2VzdCcpXG5cbiAgdGhpcy5faGFzaCA9IGhhc2hcbn1cblxuaW5oZXJpdHMoSGFzaCwgQmFzZSlcblxuSGFzaC5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG59XG5cbkhhc2gucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuX2hhc2guZGlnZXN0KClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVIYXNoIChhbGcpIHtcbiAgYWxnID0gYWxnLnRvTG93ZXJDYXNlKClcbiAgaWYgKGFsZyA9PT0gJ21kNScpIHJldHVybiBuZXcgTUQ1KClcbiAgaWYgKGFsZyA9PT0gJ3JtZDE2MCcgfHwgYWxnID09PSAncmlwZW1kMTYwJykgcmV0dXJuIG5ldyBSSVBFTUQxNjAoKVxuXG4gIHJldHVybiBuZXcgSGFzaChzaGEoYWxnKSlcbn1cbiIsInZhciBNRDUgPSByZXF1aXJlKCdtZDUuanMnKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChidWZmZXIpIHtcbiAgcmV0dXJuIG5ldyBNRDUoKS51cGRhdGUoYnVmZmVyKS5kaWdlc3QoKVxufVxuIiwiJ3VzZSBzdHJpY3QnXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgTGVnYWN5ID0gcmVxdWlyZSgnLi9sZWdhY3knKVxudmFyIEJhc2UgPSByZXF1aXJlKCdjaXBoZXItYmFzZScpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcbnZhciBtZDUgPSByZXF1aXJlKCdjcmVhdGUtaGFzaC9tZDUnKVxudmFyIFJJUEVNRDE2MCA9IHJlcXVpcmUoJ3JpcGVtZDE2MCcpXG5cbnZhciBzaGEgPSByZXF1aXJlKCdzaGEuanMnKVxuXG52YXIgWkVST1MgPSBCdWZmZXIuYWxsb2MoMTI4KVxuXG5mdW5jdGlvbiBIbWFjIChhbGcsIGtleSkge1xuICBCYXNlLmNhbGwodGhpcywgJ2RpZ2VzdCcpXG4gIGlmICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykge1xuICAgIGtleSA9IEJ1ZmZlci5mcm9tKGtleSlcbiAgfVxuXG4gIHZhciBibG9ja3NpemUgPSAoYWxnID09PSAnc2hhNTEyJyB8fCBhbGcgPT09ICdzaGEzODQnKSA/IDEyOCA6IDY0XG5cbiAgdGhpcy5fYWxnID0gYWxnXG4gIHRoaXMuX2tleSA9IGtleVxuICBpZiAoa2V5Lmxlbmd0aCA+IGJsb2Nrc2l6ZSkge1xuICAgIHZhciBoYXNoID0gYWxnID09PSAncm1kMTYwJyA/IG5ldyBSSVBFTUQxNjAoKSA6IHNoYShhbGcpXG4gICAga2V5ID0gaGFzaC51cGRhdGUoa2V5KS5kaWdlc3QoKVxuICB9IGVsc2UgaWYgKGtleS5sZW5ndGggPCBibG9ja3NpemUpIHtcbiAgICBrZXkgPSBCdWZmZXIuY29uY2F0KFtrZXksIFpFUk9TXSwgYmxvY2tzaXplKVxuICB9XG5cbiAgdmFyIGlwYWQgPSB0aGlzLl9pcGFkID0gQnVmZmVyLmFsbG9jVW5zYWZlKGJsb2Nrc2l6ZSlcbiAgdmFyIG9wYWQgPSB0aGlzLl9vcGFkID0gQnVmZmVyLmFsbG9jVW5zYWZlKGJsb2Nrc2l6ZSlcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2Nrc2l6ZTsgaSsrKSB7XG4gICAgaXBhZFtpXSA9IGtleVtpXSBeIDB4MzZcbiAgICBvcGFkW2ldID0ga2V5W2ldIF4gMHg1Q1xuICB9XG4gIHRoaXMuX2hhc2ggPSBhbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKGFsZylcbiAgdGhpcy5faGFzaC51cGRhdGUoaXBhZClcbn1cblxuaW5oZXJpdHMoSG1hYywgQmFzZSlcblxuSG1hYy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG59XG5cbkhtYWMucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGggPSB0aGlzLl9oYXNoLmRpZ2VzdCgpXG4gIHZhciBoYXNoID0gdGhpcy5fYWxnID09PSAncm1kMTYwJyA/IG5ldyBSSVBFTUQxNjAoKSA6IHNoYSh0aGlzLl9hbGcpXG4gIHJldHVybiBoYXNoLnVwZGF0ZSh0aGlzLl9vcGFkKS51cGRhdGUoaCkuZGlnZXN0KClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVIbWFjIChhbGcsIGtleSkge1xuICBhbGcgPSBhbGcudG9Mb3dlckNhc2UoKVxuICBpZiAoYWxnID09PSAncm1kMTYwJyB8fCBhbGcgPT09ICdyaXBlbWQxNjAnKSB7XG4gICAgcmV0dXJuIG5ldyBIbWFjKCdybWQxNjAnLCBrZXkpXG4gIH1cbiAgaWYgKGFsZyA9PT0gJ21kNScpIHtcbiAgICByZXR1cm4gbmV3IExlZ2FjeShtZDUsIGtleSlcbiAgfVxuICByZXR1cm4gbmV3IEhtYWMoYWxnLCBrZXkpXG59XG4iLCIndXNlIHN0cmljdCdcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgQmFzZSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcblxudmFyIFpFUk9TID0gQnVmZmVyLmFsbG9jKDEyOClcbnZhciBibG9ja3NpemUgPSA2NFxuXG5mdW5jdGlvbiBIbWFjIChhbGcsIGtleSkge1xuICBCYXNlLmNhbGwodGhpcywgJ2RpZ2VzdCcpXG4gIGlmICh0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykge1xuICAgIGtleSA9IEJ1ZmZlci5mcm9tKGtleSlcbiAgfVxuXG4gIHRoaXMuX2FsZyA9IGFsZ1xuICB0aGlzLl9rZXkgPSBrZXlcblxuICBpZiAoa2V5Lmxlbmd0aCA+IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IGFsZyhrZXkpXG4gIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgWkVST1NdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IHRoaXMuX2lwYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuICB2YXIgb3BhZCA9IHRoaXMuX29wYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tzaXplOyBpKyspIHtcbiAgICBpcGFkW2ldID0ga2V5W2ldIF4gMHgzNlxuICAgIG9wYWRbaV0gPSBrZXlbaV0gXiAweDVDXG4gIH1cblxuICB0aGlzLl9oYXNoID0gW2lwYWRdXG59XG5cbmluaGVyaXRzKEhtYWMsIEJhc2UpXG5cbkhtYWMucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLl9oYXNoLnB1c2goZGF0YSlcbn1cblxuSG1hYy5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaCA9IHRoaXMuX2FsZyhCdWZmZXIuY29uY2F0KHRoaXMuX2hhc2gpKVxuICByZXR1cm4gdGhpcy5fYWxnKEJ1ZmZlci5jb25jYXQoW3RoaXMuX29wYWQsIGhdKSlcbn1cbm1vZHVsZS5leHBvcnRzID0gSG1hY1xuIiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2VuYy1iYXNlNjRcIiksIHJlcXVpcmUoXCIuL21kNVwiKSwgcmVxdWlyZShcIi4vZXZwa2RmXCIpLCByZXF1aXJlKFwiLi9jaXBoZXItY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9lbmMtYmFzZTY0XCIsIFwiLi9tZDVcIiwgXCIuL2V2cGtkZlwiLCBcIi4vY2lwaGVyLWNvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdChmdW5jdGlvbiAoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBCbG9ja0NpcGhlciA9IENfbGliLkJsb2NrQ2lwaGVyO1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblxuXHQgICAgLy8gTG9va3VwIHRhYmxlc1xuXHQgICAgdmFyIFNCT1ggPSBbXTtcblx0ICAgIHZhciBJTlZfU0JPWCA9IFtdO1xuXHQgICAgdmFyIFNVQl9NSVhfMCA9IFtdO1xuXHQgICAgdmFyIFNVQl9NSVhfMSA9IFtdO1xuXHQgICAgdmFyIFNVQl9NSVhfMiA9IFtdO1xuXHQgICAgdmFyIFNVQl9NSVhfMyA9IFtdO1xuXHQgICAgdmFyIElOVl9TVUJfTUlYXzAgPSBbXTtcblx0ICAgIHZhciBJTlZfU1VCX01JWF8xID0gW107XG5cdCAgICB2YXIgSU5WX1NVQl9NSVhfMiA9IFtdO1xuXHQgICAgdmFyIElOVl9TVUJfTUlYXzMgPSBbXTtcblxuXHQgICAgLy8gQ29tcHV0ZSBsb29rdXAgdGFibGVzXG5cdCAgICAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIC8vIENvbXB1dGUgZG91YmxlIHRhYmxlXG5cdCAgICAgICAgdmFyIGQgPSBbXTtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG5cdCAgICAgICAgICAgIGlmIChpIDwgMTI4KSB7XG5cdCAgICAgICAgICAgICAgICBkW2ldID0gaSA8PCAxO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgZFtpXSA9IChpIDw8IDEpIF4gMHgxMWI7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBXYWxrIEdGKDJeOClcblx0ICAgICAgICB2YXIgeCA9IDA7XG5cdCAgICAgICAgdmFyIHhpID0gMDtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgc2JveFxuXHQgICAgICAgICAgICB2YXIgc3ggPSB4aSBeICh4aSA8PCAxKSBeICh4aSA8PCAyKSBeICh4aSA8PCAzKSBeICh4aSA8PCA0KTtcblx0ICAgICAgICAgICAgc3ggPSAoc3ggPj4+IDgpIF4gKHN4ICYgMHhmZikgXiAweDYzO1xuXHQgICAgICAgICAgICBTQk9YW3hdID0gc3g7XG5cdCAgICAgICAgICAgIElOVl9TQk9YW3N4XSA9IHg7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBtdWx0aXBsaWNhdGlvblxuXHQgICAgICAgICAgICB2YXIgeDIgPSBkW3hdO1xuXHQgICAgICAgICAgICB2YXIgeDQgPSBkW3gyXTtcblx0ICAgICAgICAgICAgdmFyIHg4ID0gZFt4NF07XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBzdWIgYnl0ZXMsIG1peCBjb2x1bW5zIHRhYmxlc1xuXHQgICAgICAgICAgICB2YXIgdCA9IChkW3N4XSAqIDB4MTAxKSBeIChzeCAqIDB4MTAxMDEwMCk7XG5cdCAgICAgICAgICAgIFNVQl9NSVhfMFt4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KTtcblx0ICAgICAgICAgICAgU1VCX01JWF8xW3hdID0gKHQgPDwgMTYpIHwgKHQgPj4+IDE2KTtcblx0ICAgICAgICAgICAgU1VCX01JWF8yW3hdID0gKHQgPDwgOCkgIHwgKHQgPj4+IDI0KTtcblx0ICAgICAgICAgICAgU1VCX01JWF8zW3hdID0gdDtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIGludiBzdWIgYnl0ZXMsIGludiBtaXggY29sdW1ucyB0YWJsZXNcblx0ICAgICAgICAgICAgdmFyIHQgPSAoeDggKiAweDEwMTAxMDEpIF4gKHg0ICogMHgxMDAwMSkgXiAoeDIgKiAweDEwMSkgXiAoeCAqIDB4MTAxMDEwMCk7XG5cdCAgICAgICAgICAgIElOVl9TVUJfTUlYXzBbc3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpO1xuXHQgICAgICAgICAgICBJTlZfU1VCX01JWF8xW3N4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNik7XG5cdCAgICAgICAgICAgIElOVl9TVUJfTUlYXzJbc3hdID0gKHQgPDwgOCkgIHwgKHQgPj4+IDI0KTtcblx0ICAgICAgICAgICAgSU5WX1NVQl9NSVhfM1tzeF0gPSB0O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgbmV4dCBjb3VudGVyXG5cdCAgICAgICAgICAgIGlmICgheCkge1xuXHQgICAgICAgICAgICAgICAgeCA9IHhpID0gMTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHggPSB4MiBeIGRbZFtkW3g4IF4geDJdXV07XG5cdCAgICAgICAgICAgICAgICB4aSBePSBkW2RbeGldXTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0oKSk7XG5cblx0ICAgIC8vIFByZWNvbXB1dGVkIFJjb24gbG9va3VwXG5cdCAgICB2YXIgUkNPTiA9IFsweDAwLCAweDAxLCAweDAyLCAweDA0LCAweDA4LCAweDEwLCAweDIwLCAweDQwLCAweDgwLCAweDFiLCAweDM2XTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBRVMgYmxvY2sgY2lwaGVyIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEFFUyA9IENfYWxnby5BRVMgPSBCbG9ja0NpcGhlci5leHRlbmQoe1xuXHQgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNraXAgcmVzZXQgb2YgblJvdW5kcyBoYXMgYmVlbiBzZXQgYmVmb3JlIGFuZCBrZXkgZGlkIG5vdCBjaGFuZ2Vcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX25Sb3VuZHMgJiYgdGhpcy5fa2V5UHJpb3JSZXNldCA9PT0gdGhpcy5fa2V5KSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm47XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuX2tleVByaW9yUmVzZXQgPSB0aGlzLl9rZXk7XG5cdCAgICAgICAgICAgIHZhciBrZXlXb3JkcyA9IGtleS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIGtleVNpemUgPSBrZXkuc2lnQnl0ZXMgLyA0O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgbnVtYmVyIG9mIHJvdW5kc1xuXHQgICAgICAgICAgICB2YXIgblJvdW5kcyA9IHRoaXMuX25Sb3VuZHMgPSBrZXlTaXplICsgNjtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIG51bWJlciBvZiBrZXkgc2NoZWR1bGUgcm93c1xuXHQgICAgICAgICAgICB2YXIga3NSb3dzID0gKG5Sb3VuZHMgKyAxKSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBrZXkgc2NoZWR1bGVcblx0ICAgICAgICAgICAgdmFyIGtleVNjaGVkdWxlID0gdGhpcy5fa2V5U2NoZWR1bGUgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIga3NSb3cgPSAwOyBrc1JvdyA8IGtzUm93czsga3NSb3crKykge1xuXHQgICAgICAgICAgICAgICAgaWYgKGtzUm93IDwga2V5U2l6ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGtleVNjaGVkdWxlW2tzUm93XSA9IGtleVdvcmRzW2tzUm93XTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSBrZXlTY2hlZHVsZVtrc1JvdyAtIDFdO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKCEoa3NSb3cgJSBrZXlTaXplKSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBSb3Qgd29yZFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB0ID0gKHQgPDwgOCkgfCAodCA+Pj4gMjQpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1YiB3b3JkXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAoU0JPWFt0ID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFt0ICYgMHhmZl07XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWl4IFJjb25cblx0ICAgICAgICAgICAgICAgICAgICAgICAgdCBePSBSQ09OWyhrc1JvdyAvIGtleVNpemUpIHwgMF0gPDwgMjQ7XG5cdCAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChrZXlTaXplID4gNiAmJiBrc1JvdyAlIGtleVNpemUgPT0gNCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBTdWIgd29yZFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB0ID0gKFNCT1hbdCA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsodCA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbdCAmIDB4ZmZdO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgIGtleVNjaGVkdWxlW2tzUm93XSA9IGtleVNjaGVkdWxlW2tzUm93IC0ga2V5U2l6ZV0gXiB0O1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBpbnYga2V5IHNjaGVkdWxlXG5cdCAgICAgICAgICAgIHZhciBpbnZLZXlTY2hlZHVsZSA9IHRoaXMuX2ludktleVNjaGVkdWxlID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBrc1JvdyA9IGtzUm93cyAtIGludktzUm93O1xuXG5cdCAgICAgICAgICAgICAgICBpZiAoaW52S3NSb3cgJSA0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSBrZXlTY2hlZHVsZVtrc1Jvd107XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciB0ID0ga2V5U2NoZWR1bGVba3NSb3cgLSA0XTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgaWYgKGludktzUm93IDwgNCB8fCBrc1JvdyA8PSA0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaW52S2V5U2NoZWR1bGVbaW52S3NSb3ddID0gdDtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaW52S2V5U2NoZWR1bGVbaW52S3NSb3ddID0gSU5WX1NVQl9NSVhfMFtTQk9YW3QgPj4+IDI0XV0gXiBJTlZfU1VCX01JWF8xW1NCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdXSBeXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5WX1NVQl9NSVhfMltTQk9YWyh0ID4+PiA4KSAmIDB4ZmZdXSBeIElOVl9TVUJfTUlYXzNbU0JPWFt0ICYgMHhmZl1dO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGVuY3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkge1xuXHQgICAgICAgICAgICB0aGlzLl9kb0NyeXB0QmxvY2soTSwgb2Zmc2V0LCB0aGlzLl9rZXlTY2hlZHVsZSwgU1VCX01JWF8wLCBTVUJfTUlYXzEsIFNVQl9NSVhfMiwgU1VCX01JWF8zLCBTQk9YKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgZGVjcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIC8vIFN3YXAgMm5kIGFuZCA0dGggcm93c1xuXHQgICAgICAgICAgICB2YXIgdCA9IE1bb2Zmc2V0ICsgMV07XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSBNW29mZnNldCArIDNdO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDNdID0gdDtcblxuXHQgICAgICAgICAgICB0aGlzLl9kb0NyeXB0QmxvY2soTSwgb2Zmc2V0LCB0aGlzLl9pbnZLZXlTY2hlZHVsZSwgSU5WX1NVQl9NSVhfMCwgSU5WX1NVQl9NSVhfMSwgSU5WX1NVQl9NSVhfMiwgSU5WX1NVQl9NSVhfMywgSU5WX1NCT1gpO1xuXG5cdCAgICAgICAgICAgIC8vIEludiBzd2FwIDJuZCBhbmQgNHRoIHJvd3Ncblx0ICAgICAgICAgICAgdmFyIHQgPSBNW29mZnNldCArIDFdO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDFdID0gTVtvZmZzZXQgKyAzXTtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAzXSA9IHQ7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb0NyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQsIGtleVNjaGVkdWxlLCBTVUJfTUlYXzAsIFNVQl9NSVhfMSwgU1VCX01JWF8yLCBTVUJfTUlYXzMsIFNCT1gpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIG5Sb3VuZHMgPSB0aGlzLl9uUm91bmRzO1xuXG5cdCAgICAgICAgICAgIC8vIEdldCBpbnB1dCwgYWRkIHJvdW5kIGtleVxuXHQgICAgICAgICAgICB2YXIgczAgPSBNW29mZnNldF0gICAgIF4ga2V5U2NoZWR1bGVbMF07XG5cdCAgICAgICAgICAgIHZhciBzMSA9IE1bb2Zmc2V0ICsgMV0gXiBrZXlTY2hlZHVsZVsxXTtcblx0ICAgICAgICAgICAgdmFyIHMyID0gTVtvZmZzZXQgKyAyXSBeIGtleVNjaGVkdWxlWzJdO1xuXHQgICAgICAgICAgICB2YXIgczMgPSBNW29mZnNldCArIDNdIF4ga2V5U2NoZWR1bGVbM107XG5cblx0ICAgICAgICAgICAgLy8gS2V5IHNjaGVkdWxlIHJvdyBjb3VudGVyXG5cdCAgICAgICAgICAgIHZhciBrc1JvdyA9IDQ7XG5cblx0ICAgICAgICAgICAgLy8gUm91bmRzXG5cdCAgICAgICAgICAgIGZvciAodmFyIHJvdW5kID0gMTsgcm91bmQgPCBuUm91bmRzOyByb3VuZCsrKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBTaGlmdCByb3dzLCBzdWIgYnl0ZXMsIG1peCBjb2x1bW5zLCBhZGQgcm91bmQga2V5XG5cdCAgICAgICAgICAgICAgICB2YXIgdDAgPSBTVUJfTUlYXzBbczAgPj4+IDI0XSBeIFNVQl9NSVhfMVsoczEgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWF8yWyhzMiA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhfM1tzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgICAgICB2YXIgdDEgPSBTVUJfTUlYXzBbczEgPj4+IDI0XSBeIFNVQl9NSVhfMVsoczIgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWF8yWyhzMyA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhfM1tzMCAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgICAgICB2YXIgdDIgPSBTVUJfTUlYXzBbczIgPj4+IDI0XSBeIFNVQl9NSVhfMVsoczMgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWF8yWyhzMCA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhfM1tzMSAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgICAgICB2YXIgdDMgPSBTVUJfTUlYXzBbczMgPj4+IDI0XSBeIFNVQl9NSVhfMVsoczAgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWF8yWyhzMSA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVhfM1tzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cblx0ICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBzdGF0ZVxuXHQgICAgICAgICAgICAgICAgczAgPSB0MDtcblx0ICAgICAgICAgICAgICAgIHMxID0gdDE7XG5cdCAgICAgICAgICAgICAgICBzMiA9IHQyO1xuXHQgICAgICAgICAgICAgICAgczMgPSB0Mztcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFNoaWZ0IHJvd3MsIHN1YiBieXRlcywgYWRkIHJvdW5kIGtleVxuXHQgICAgICAgICAgICB2YXIgdDAgPSAoKFNCT1hbczAgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczEgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMiA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgdmFyIHQxID0gKChTQk9YW3MxID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMyID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczMgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MwICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgIHZhciB0MiA9ICgoU0JPWFtzMiA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMyA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMwID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMSAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdO1xuXHQgICAgICAgICAgICB2YXIgdDMgPSAoKFNCT1hbczMgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczAgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMSA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblxuXHQgICAgICAgICAgICAvLyBTZXQgb3V0cHV0XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0XSAgICAgPSB0MDtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAxXSA9IHQxO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDJdID0gdDI7XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgM10gPSB0Mztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAga2V5U2l6ZTogMjU2LzMyXG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5BRVMuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7XG5cdCAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5BRVMuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7XG5cdCAgICAgKi9cblx0ICAgIEMuQUVTID0gQmxvY2tDaXBoZXIuX2NyZWF0ZUhlbHBlcihBRVMpO1xuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLkFFUztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0LyoqXG5cdCAqIENpcGhlciBjb3JlIGNvbXBvbmVudHMuXG5cdCAqL1xuXHRDcnlwdG9KUy5saWIuQ2lwaGVyIHx8IChmdW5jdGlvbiAodW5kZWZpbmVkKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBCYXNlID0gQ19saWIuQmFzZTtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgQnVmZmVyZWRCbG9ja0FsZ29yaXRobSA9IENfbGliLkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG07XG5cdCAgICB2YXIgQ19lbmMgPSBDLmVuYztcblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmODtcblx0ICAgIHZhciBCYXNlNjQgPSBDX2VuYy5CYXNlNjQ7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXHQgICAgdmFyIEV2cEtERiA9IENfYWxnby5FdnBLREY7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYmFzZSBjaXBoZXIgdGVtcGxhdGUuXG5cdCAgICAgKlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGtleVNpemUgVGhpcyBjaXBoZXIncyBrZXkgc2l6ZS4gRGVmYXVsdDogNCAoMTI4IGJpdHMpXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gaXZTaXplIFRoaXMgY2lwaGVyJ3MgSVYgc2l6ZS4gRGVmYXVsdDogNCAoMTI4IGJpdHMpXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX0VOQ19YRk9STV9NT0RFIEEgY29uc3RhbnQgcmVwcmVzZW50aW5nIGVuY3J5cHRpb24gbW9kZS5cblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBfREVDX1hGT1JNX01PREUgQSBjb25zdGFudCByZXByZXNlbnRpbmcgZGVjcnlwdGlvbiBtb2RlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ2lwaGVyID0gQ19saWIuQ2lwaGVyID0gQnVmZmVyZWRCbG9ja0FsZ29yaXRobS5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7V29yZEFycmF5fSBpdiBUaGUgSVYgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjZmc6IEJhc2UuZXh0ZW5kKCksXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIHRoaXMgY2lwaGVyIGluIGVuY3J5cHRpb24gbW9kZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyfSBBIGNpcGhlciBpbnN0YW5jZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlciA9IENyeXB0b0pTLmFsZ28uQUVTLmNyZWF0ZUVuY3J5cHRvcihrZXlXb3JkQXJyYXksIHsgaXY6IGl2V29yZEFycmF5IH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNyZWF0ZUVuY3J5cHRvcjogZnVuY3Rpb24gKGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZSh0aGlzLl9FTkNfWEZPUk1fTU9ERSwga2V5LCBjZmcpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIHRoaXMgY2lwaGVyIGluIGRlY3J5cHRpb24gbW9kZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyfSBBIGNpcGhlciBpbnN0YW5jZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlciA9IENyeXB0b0pTLmFsZ28uQUVTLmNyZWF0ZURlY3J5cHRvcihrZXlXb3JkQXJyYXksIHsgaXY6IGl2V29yZEFycmF5IH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNyZWF0ZURlY3J5cHRvcjogZnVuY3Rpb24gKGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZSh0aGlzLl9ERUNfWEZPUk1fTU9ERSwga2V5LCBjZmcpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgY2lwaGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHhmb3JtTW9kZSBFaXRoZXIgdGhlIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbiB0cmFuc29ybWF0aW9uIG1vZGUgY29uc3RhbnQuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGtleSBUaGUga2V5LlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXIgPSBDcnlwdG9KUy5hbGdvLkFFUy5jcmVhdGUoQ3J5cHRvSlMuYWxnby5BRVMuX0VOQ19YRk9STV9NT0RFLCBrZXlXb3JkQXJyYXksIHsgaXY6IGl2V29yZEFycmF5IH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uICh4Zm9ybU1vZGUsIGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICB0aGlzLmNmZyA9IHRoaXMuY2ZnLmV4dGVuZChjZmcpO1xuXG5cdCAgICAgICAgICAgIC8vIFN0b3JlIHRyYW5zZm9ybSBtb2RlIGFuZCBrZXlcblx0ICAgICAgICAgICAgdGhpcy5feGZvcm1Nb2RlID0geGZvcm1Nb2RlO1xuXHQgICAgICAgICAgICB0aGlzLl9rZXkgPSBrZXk7XG5cblx0ICAgICAgICAgICAgLy8gU2V0IGluaXRpYWwgdmFsdWVzXG5cdCAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVzZXRzIHRoaXMgY2lwaGVyIHRvIGl0cyBpbml0aWFsIHN0YXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBjaXBoZXIucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBSZXNldCBkYXRhIGJ1ZmZlclxuXHQgICAgICAgICAgICBCdWZmZXJlZEJsb2NrQWxnb3JpdGhtLnJlc2V0LmNhbGwodGhpcyk7XG5cblx0ICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1jaXBoZXIgbG9naWNcblx0ICAgICAgICAgICAgdGhpcy5fZG9SZXNldCgpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBZGRzIGRhdGEgdG8gYmUgZW5jcnlwdGVkIG9yIGRlY3J5cHRlZC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gZGF0YVVwZGF0ZSBUaGUgZGF0YSB0byBlbmNyeXB0IG9yIGRlY3J5cHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBkYXRhIGFmdGVyIHByb2Nlc3NpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIucHJvY2VzcygnZGF0YScpO1xuXHQgICAgICAgICAqICAgICB2YXIgZW5jcnlwdGVkID0gY2lwaGVyLnByb2Nlc3Mod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwcm9jZXNzOiBmdW5jdGlvbiAoZGF0YVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBBcHBlbmRcblx0ICAgICAgICAgICAgdGhpcy5fYXBwZW5kKGRhdGFVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIFByb2Nlc3MgYXZhaWxhYmxlIGJsb2Nrc1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJvY2VzcygpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbiBwcm9jZXNzLlxuXHQgICAgICAgICAqIE5vdGUgdGhhdCB0aGUgZmluYWxpemUgb3BlcmF0aW9uIGlzIGVmZmVjdGl2ZWx5IGEgZGVzdHJ1Y3RpdmUsIHJlYWQtb25jZSBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGRhdGFVcGRhdGUgVGhlIGZpbmFsIGRhdGEgdG8gZW5jcnlwdCBvciBkZWNyeXB0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGF0YSBhZnRlciBmaW5hbCBwcm9jZXNzaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgZW5jcnlwdGVkID0gY2lwaGVyLmZpbmFsaXplKCk7XG5cdCAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5maW5hbGl6ZSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAoZGF0YVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBGaW5hbCBkYXRhIHVwZGF0ZVxuXHQgICAgICAgICAgICBpZiAoZGF0YVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fYXBwZW5kKGRhdGFVcGRhdGUpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1jaXBoZXIgbG9naWNcblx0ICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkRGF0YSA9IHRoaXMuX2RvRmluYWxpemUoKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gZmluYWxQcm9jZXNzZWREYXRhO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBrZXlTaXplOiAxMjgvMzIsXG5cblx0ICAgICAgICBpdlNpemU6IDEyOC8zMixcblxuXHQgICAgICAgIF9FTkNfWEZPUk1fTU9ERTogMSxcblxuXHQgICAgICAgIF9ERUNfWEZPUk1fTU9ERTogMixcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENyZWF0ZXMgc2hvcnRjdXQgZnVuY3Rpb25zIHRvIGEgY2lwaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciB0byBjcmVhdGUgYSBoZWxwZXIgZm9yLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSBBbiBvYmplY3Qgd2l0aCBlbmNyeXB0IGFuZCBkZWNyeXB0IHNob3J0Y3V0IGZ1bmN0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIEFFUyA9IENyeXB0b0pTLmxpYi5DaXBoZXIuX2NyZWF0ZUhlbHBlcihDcnlwdG9KUy5hbGdvLkFFUyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2NyZWF0ZUhlbHBlcjogKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgZnVuY3Rpb24gc2VsZWN0Q2lwaGVyU3RyYXRlZ3koa2V5KSB7XG5cdCAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGtleSA9PSAnc3RyaW5nJykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBQYXNzd29yZEJhc2VkQ2lwaGVyO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gU2VyaWFsaXphYmxlQ2lwaGVyO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChjaXBoZXIpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgICAgICAgICAgZW5jcnlwdDogZnVuY3Rpb24gKG1lc3NhZ2UsIGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RDaXBoZXJTdHJhdGVneShrZXkpLmVuY3J5cHQoY2lwaGVyLCBtZXNzYWdlLCBrZXksIGNmZyk7XG5cdCAgICAgICAgICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXJ0ZXh0LCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0Q2lwaGVyU3RyYXRlZ3koa2V5KS5kZWNyeXB0KGNpcGhlciwgY2lwaGVydGV4dCwga2V5LCBjZmcpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfSgpKVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYmFzZSBzdHJlYW0gY2lwaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBjaXBoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDEgKDMyIGJpdHMpXG5cdCAgICAgKi9cblx0ICAgIHZhciBTdHJlYW1DaXBoZXIgPSBDX2xpYi5TdHJlYW1DaXBoZXIgPSBDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBQcm9jZXNzIHBhcnRpYWwgYmxvY2tzXG5cdCAgICAgICAgICAgIHZhciBmaW5hbFByb2Nlc3NlZEJsb2NrcyA9IHRoaXMuX3Byb2Nlc3MoISEnZmx1c2gnKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gZmluYWxQcm9jZXNzZWRCbG9ja3M7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogMVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogTW9kZSBuYW1lc3BhY2UuXG5cdCAgICAgKi9cblx0ICAgIHZhciBDX21vZGUgPSBDLm1vZGUgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBYnN0cmFjdCBiYXNlIGJsb2NrIGNpcGhlciBtb2RlIHRlbXBsYXRlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQmxvY2tDaXBoZXJNb2RlID0gQ19saWIuQmxvY2tDaXBoZXJNb2RlID0gQmFzZS5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENyZWF0ZXMgdGhpcyBtb2RlIGZvciBlbmNyeXB0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBBIGJsb2NrIGNpcGhlciBpbnN0YW5jZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBpdiBUaGUgSVYgd29yZHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBtb2RlID0gQ3J5cHRvSlMubW9kZS5DQkMuY3JlYXRlRW5jcnlwdG9yKGNpcGhlciwgaXYud29yZHMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNyZWF0ZUVuY3J5cHRvcjogZnVuY3Rpb24gKGNpcGhlciwgaXYpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuRW5jcnlwdG9yLmNyZWF0ZShjaXBoZXIsIGl2KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyB0aGlzIG1vZGUgZm9yIGRlY3J5cHRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIEEgYmxvY2sgY2lwaGVyIGluc3RhbmNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGl2IFRoZSBJViB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIG1vZGUgPSBDcnlwdG9KUy5tb2RlLkNCQy5jcmVhdGVEZWNyeXB0b3IoY2lwaGVyLCBpdi53b3Jkcyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY3JlYXRlRGVjcnlwdG9yOiBmdW5jdGlvbiAoY2lwaGVyLCBpdikge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5EZWNyeXB0b3IuY3JlYXRlKGNpcGhlciwgaXYpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgbW9kZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgQSBibG9jayBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtBcnJheX0gaXYgVGhlIElWIHdvcmRzLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgbW9kZSA9IENyeXB0b0pTLm1vZGUuQ0JDLkVuY3J5cHRvci5jcmVhdGUoY2lwaGVyLCBpdi53b3Jkcyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgaW5pdDogZnVuY3Rpb24gKGNpcGhlciwgaXYpIHtcblx0ICAgICAgICAgICAgdGhpcy5fY2lwaGVyID0gY2lwaGVyO1xuXHQgICAgICAgICAgICB0aGlzLl9pdiA9IGl2O1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIENpcGhlciBCbG9jayBDaGFpbmluZyBtb2RlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ0JDID0gQ19tb2RlLkNCQyA9IChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQWJzdHJhY3QgYmFzZSBDQkMgbW9kZS5cblx0ICAgICAgICAgKi9cblx0ICAgICAgICB2YXIgQ0JDID0gQmxvY2tDaXBoZXJNb2RlLmV4dGVuZCgpO1xuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ0JDIGVuY3J5cHRvci5cblx0ICAgICAgICAgKi9cblx0ICAgICAgICBDQkMuRW5jcnlwdG9yID0gQ0JDLmV4dGVuZCh7XG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBQcm9jZXNzZXMgdGhlIGRhdGEgYmxvY2sgYXQgb2Zmc2V0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyBUaGUgZGF0YSB3b3JkcyB0byBvcGVyYXRlIG9uLlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IFRoZSBvZmZzZXQgd2hlcmUgdGhlIGJsb2NrIHN0YXJ0cy5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIG1vZGUucHJvY2Vzc0Jsb2NrKGRhdGEud29yZHMsIG9mZnNldCk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgICAgIHZhciBjaXBoZXIgPSB0aGlzLl9jaXBoZXI7XG5cdCAgICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTtcblxuXHQgICAgICAgICAgICAgICAgLy8gWE9SIGFuZCBlbmNyeXB0XG5cdCAgICAgICAgICAgICAgICB4b3JCbG9jay5jYWxsKHRoaXMsIHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSk7XG5cdCAgICAgICAgICAgICAgICBjaXBoZXIuZW5jcnlwdEJsb2NrKHdvcmRzLCBvZmZzZXQpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1lbWJlciB0aGlzIGJsb2NrIHRvIHVzZSB3aXRoIG5leHQgYmxvY2tcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3ByZXZCbG9jayA9IHdvcmRzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmxvY2tTaXplKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ0JDIGRlY3J5cHRvci5cblx0ICAgICAgICAgKi9cblx0ICAgICAgICBDQkMuRGVjcnlwdG9yID0gQ0JDLmV4dGVuZCh7XG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBQcm9jZXNzZXMgdGhlIGRhdGEgYmxvY2sgYXQgb2Zmc2V0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyBUaGUgZGF0YSB3b3JkcyB0byBvcGVyYXRlIG9uLlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IFRoZSBvZmZzZXQgd2hlcmUgdGhlIGJsb2NrIHN0YXJ0cy5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIG1vZGUucHJvY2Vzc0Jsb2NrKGRhdGEud29yZHMsIG9mZnNldCk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgICAgIHZhciBjaXBoZXIgPSB0aGlzLl9jaXBoZXI7XG5cdCAgICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhpcyBibG9jayB0byB1c2Ugd2l0aCBuZXh0IGJsb2NrXG5cdCAgICAgICAgICAgICAgICB2YXIgdGhpc0Jsb2NrID0gd29yZHMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBibG9ja1NpemUpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBEZWNyeXB0IGFuZCBYT1Jcblx0ICAgICAgICAgICAgICAgIGNpcGhlci5kZWNyeXB0QmxvY2sod29yZHMsIG9mZnNldCk7XG5cdCAgICAgICAgICAgICAgICB4b3JCbG9jay5jYWxsKHRoaXMsIHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFRoaXMgYmxvY2sgYmVjb21lcyB0aGUgcHJldmlvdXMgYmxvY2tcblx0ICAgICAgICAgICAgICAgIHRoaXMuX3ByZXZCbG9jayA9IHRoaXNCbG9jaztcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXG5cdCAgICAgICAgZnVuY3Rpb24geG9yQmxvY2sod29yZHMsIG9mZnNldCwgYmxvY2tTaXplKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBpdiA9IHRoaXMuX2l2O1xuXG5cdCAgICAgICAgICAgIC8vIENob29zZSBtaXhpbmcgYmxvY2tcblx0ICAgICAgICAgICAgaWYgKGl2KSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgYmxvY2sgPSBpdjtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVtb3ZlIElWIGZvciBzdWJzZXF1ZW50IGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgdGhpcy5faXYgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgYmxvY2sgPSB0aGlzLl9wcmV2QmxvY2s7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBYT1IgYmxvY2tzXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tTaXplOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHdvcmRzW29mZnNldCArIGldIF49IGJsb2NrW2ldO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmV0dXJuIENCQztcblx0ICAgIH0oKSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogUGFkZGluZyBuYW1lc3BhY2UuXG5cdCAgICAgKi9cblx0ICAgIHZhciBDX3BhZCA9IEMucGFkID0ge307XG5cblx0ICAgIC8qKlxuXHQgICAgICogUEtDUyAjNS83IHBhZGRpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBQa2NzNyA9IENfcGFkLlBrY3M3ID0ge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFBhZHMgZGF0YSB1c2luZyB0aGUgYWxnb3JpdGhtIGRlZmluZWQgaW4gUEtDUyAjNS83LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGRhdGEgVGhlIGRhdGEgdG8gcGFkLlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG11bHRpcGxlIHRoYXQgdGhlIGRhdGEgc2hvdWxkIGJlIHBhZGRlZCB0by5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgQ3J5cHRvSlMucGFkLlBrY3M3LnBhZCh3b3JkQXJyYXksIDQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhZDogZnVuY3Rpb24gKGRhdGEsIGJsb2NrU2l6ZSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgYmxvY2tTaXplQnl0ZXMgPSBibG9ja1NpemUgKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIENvdW50IHBhZGRpbmcgYnl0ZXNcblx0ICAgICAgICAgICAgdmFyIG5QYWRkaW5nQnl0ZXMgPSBibG9ja1NpemVCeXRlcyAtIGRhdGEuc2lnQnl0ZXMgJSBibG9ja1NpemVCeXRlcztcblxuXHQgICAgICAgICAgICAvLyBDcmVhdGUgcGFkZGluZyB3b3JkXG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nV29yZCA9IChuUGFkZGluZ0J5dGVzIDw8IDI0KSB8IChuUGFkZGluZ0J5dGVzIDw8IDE2KSB8IChuUGFkZGluZ0J5dGVzIDw8IDgpIHwgblBhZGRpbmdCeXRlcztcblxuXHQgICAgICAgICAgICAvLyBDcmVhdGUgcGFkZGluZ1xuXHQgICAgICAgICAgICB2YXIgcGFkZGluZ1dvcmRzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgblBhZGRpbmdCeXRlczsgaSArPSA0KSB7XG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nV29yZHMucHVzaChwYWRkaW5nV29yZCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmcgPSBXb3JkQXJyYXkuY3JlYXRlKHBhZGRpbmdXb3JkcywgblBhZGRpbmdCeXRlcyk7XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgZGF0YS5jb25jYXQocGFkZGluZyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFVucGFkcyBkYXRhIHRoYXQgaGFkIGJlZW4gcGFkZGVkIHVzaW5nIHRoZSBhbGdvcml0aG0gZGVmaW5lZCBpbiBQS0NTICM1LzcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gZGF0YSBUaGUgZGF0YSB0byB1bnBhZC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgQ3J5cHRvSlMucGFkLlBrY3M3LnVucGFkKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdW5wYWQ6IGZ1bmN0aW9uIChkYXRhKSB7XG5cdCAgICAgICAgICAgIC8vIEdldCBudW1iZXIgb2YgcGFkZGluZyBieXRlcyBmcm9tIGxhc3QgYnl0ZVxuXHQgICAgICAgICAgICB2YXIgblBhZGRpbmdCeXRlcyA9IGRhdGEud29yZHNbKGRhdGEuc2lnQnl0ZXMgLSAxKSA+Pj4gMl0gJiAweGZmO1xuXG5cdCAgICAgICAgICAgIC8vIFJlbW92ZSBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgLT0gblBhZGRpbmdCeXRlcztcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFic3RyYWN0IGJhc2UgYmxvY2sgY2lwaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBjaXBoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDQgKDEyOCBiaXRzKVxuXHQgICAgICovXG5cdCAgICB2YXIgQmxvY2tDaXBoZXIgPSBDX2xpYi5CbG9ja0NpcGhlciA9IENpcGhlci5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7TW9kZX0gbW9kZSBUaGUgYmxvY2sgbW9kZSB0byB1c2UuIERlZmF1bHQ6IENCQ1xuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7UGFkZGluZ30gcGFkZGluZyBUaGUgcGFkZGluZyBzdHJhdGVneSB0byB1c2UuIERlZmF1bHQ6IFBrY3M3XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBDaXBoZXIuY2ZnLmV4dGVuZCh7XG5cdCAgICAgICAgICAgIG1vZGU6IENCQyxcblx0ICAgICAgICAgICAgcGFkZGluZzogUGtjczdcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGNpcGhlclxuXHQgICAgICAgICAgICBDaXBoZXIucmVzZXQuY2FsbCh0aGlzKTtcblxuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGNmZyA9IHRoaXMuY2ZnO1xuXHQgICAgICAgICAgICB2YXIgaXYgPSBjZmcuaXY7XG5cdCAgICAgICAgICAgIHZhciBtb2RlID0gY2ZnLm1vZGU7XG5cblx0ICAgICAgICAgICAgLy8gUmVzZXQgYmxvY2sgbW9kZVxuXHQgICAgICAgICAgICBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0VOQ19YRk9STV9NT0RFKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgbW9kZUNyZWF0b3IgPSBtb2RlLmNyZWF0ZUVuY3J5cHRvcjtcblx0ICAgICAgICAgICAgfSBlbHNlIC8qIGlmICh0aGlzLl94Zm9ybU1vZGUgPT0gdGhpcy5fREVDX1hGT1JNX01PREUpICovIHtcblx0ICAgICAgICAgICAgICAgIHZhciBtb2RlQ3JlYXRvciA9IG1vZGUuY3JlYXRlRGVjcnlwdG9yO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBLZWVwIGF0IGxlYXN0IG9uZSBibG9jayBpbiB0aGUgYnVmZmVyIGZvciB1bnBhZGRpbmdcblx0ICAgICAgICAgICAgICAgIHRoaXMuX21pbkJ1ZmZlclNpemUgPSAxO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuX21vZGUgPSBtb2RlQ3JlYXRvci5jYWxsKG1vZGUsIHRoaXMsIGl2ICYmIGl2LndvcmRzKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICB0aGlzLl9tb2RlLnByb2Nlc3NCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmcgPSB0aGlzLmNmZy5wYWRkaW5nO1xuXG5cdCAgICAgICAgICAgIC8vIEZpbmFsaXplXG5cdCAgICAgICAgICAgIGlmICh0aGlzLl94Zm9ybU1vZGUgPT0gdGhpcy5fRU5DX1hGT1JNX01PREUpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFBhZCBkYXRhXG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nLnBhZCh0aGlzLl9kYXRhLCB0aGlzLmJsb2NrU2l6ZSk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgICAgICB2YXIgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKCEhJ2ZsdXNoJyk7XG5cdCAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqLyB7XG5cdCAgICAgICAgICAgICAgICAvLyBQcm9jZXNzIGZpbmFsIGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkQmxvY2tzID0gdGhpcy5fcHJvY2VzcyghISdmbHVzaCcpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBVbnBhZCBkYXRhXG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nLnVucGFkKGZpbmFsUHJvY2Vzc2VkQmxvY2tzKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBmaW5hbFByb2Nlc3NlZEJsb2Nrcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgYmxvY2tTaXplOiAxMjgvMzJcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEEgY29sbGVjdGlvbiBvZiBjaXBoZXIgcGFyYW1ldGVycy5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gY2lwaGVydGV4dCBUaGUgcmF3IGNpcGhlcnRleHQuXG5cdCAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkgdG8gdGhpcyBjaXBoZXJ0ZXh0LlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IGl2IFRoZSBJViB1c2VkIGluIHRoZSBjaXBoZXJpbmcgb3BlcmF0aW9uLlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IHNhbHQgVGhlIHNhbHQgdXNlZCB3aXRoIGEga2V5IGRlcml2YXRpb24gZnVuY3Rpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge0NpcGhlcn0gYWxnb3JpdGhtIFRoZSBjaXBoZXIgYWxnb3JpdGhtLlxuXHQgICAgICogQHByb3BlcnR5IHtNb2RlfSBtb2RlIFRoZSBibG9jayBtb2RlIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge1BhZGRpbmd9IHBhZGRpbmcgVGhlIHBhZGRpbmcgc2NoZW1lIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBibG9jayBzaXplIG9mIHRoZSBjaXBoZXIuXG5cdCAgICAgKiBAcHJvcGVydHkge0Zvcm1hdH0gZm9ybWF0dGVyIFRoZSBkZWZhdWx0IGZvcm1hdHRpbmcgc3RyYXRlZ3kgdG8gY29udmVydCB0aGlzIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGEgc3RyaW5nLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ2lwaGVyUGFyYW1zID0gQ19saWIuQ2lwaGVyUGFyYW1zID0gQmFzZS5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjaXBoZXJQYXJhbXMgQW4gb2JqZWN0IHdpdGggYW55IG9mIHRoZSBwb3NzaWJsZSBjaXBoZXIgcGFyYW1ldGVycy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlclBhcmFtcyA9IENyeXB0b0pTLmxpYi5DaXBoZXJQYXJhbXMuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIGNpcGhlcnRleHQ6IGNpcGhlcnRleHRXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBrZXk6IGtleVdvcmRBcnJheSxcblx0ICAgICAgICAgKiAgICAgICAgIGl2OiBpdldvcmRBcnJheSxcblx0ICAgICAgICAgKiAgICAgICAgIHNhbHQ6IHNhbHRXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBhbGdvcml0aG06IENyeXB0b0pTLmFsZ28uQUVTLFxuXHQgICAgICAgICAqICAgICAgICAgbW9kZTogQ3J5cHRvSlMubW9kZS5DQkMsXG5cdCAgICAgICAgICogICAgICAgICBwYWRkaW5nOiBDcnlwdG9KUy5wYWQuUEtDUzcsXG5cdCAgICAgICAgICogICAgICAgICBibG9ja1NpemU6IDQsXG5cdCAgICAgICAgICogICAgICAgICBmb3JtYXR0ZXI6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMXG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjaXBoZXJQYXJhbXMpIHtcblx0ICAgICAgICAgICAgdGhpcy5taXhJbihjaXBoZXJQYXJhbXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtGb3JtYXR9IGZvcm1hdHRlciAoT3B0aW9uYWwpIFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIHVzZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIGNpcGhlciBwYXJhbXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAdGhyb3dzIEVycm9yIElmIG5laXRoZXIgdGhlIGZvcm1hdHRlciBub3IgdGhlIGRlZmF1bHQgZm9ybWF0dGVyIGlzIHNldC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IGNpcGhlclBhcmFtcyArICcnO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zLnRvU3RyaW5nKCk7XG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSBjaXBoZXJQYXJhbXMudG9TdHJpbmcoQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRvU3RyaW5nOiBmdW5jdGlvbiAoZm9ybWF0dGVyKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAoZm9ybWF0dGVyIHx8IHRoaXMuZm9ybWF0dGVyKS5zdHJpbmdpZnkodGhpcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogRm9ybWF0IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZm9ybWF0ID0gQy5mb3JtYXQgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBPcGVuU1NMIGZvcm1hdHRpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBPcGVuU1NMRm9ybWF0dGVyID0gQ19mb3JtYXQuT3BlblNTTCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc30gY2lwaGVyUGFyYW1zIFRoZSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBvcGVuU1NMU3RyaW5nID0gQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wuc3RyaW5naWZ5KGNpcGhlclBhcmFtcyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IGNpcGhlclBhcmFtcy5jaXBoZXJ0ZXh0O1xuXHQgICAgICAgICAgICB2YXIgc2FsdCA9IGNpcGhlclBhcmFtcy5zYWx0O1xuXG5cdCAgICAgICAgICAgIC8vIEZvcm1hdFxuXHQgICAgICAgICAgICBpZiAoc2FsdCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheSA9IFdvcmRBcnJheS5jcmVhdGUoWzB4NTM2MTZjNzQsIDB4NjU2NDVmNWZdKS5jb25jYXQoc2FsdCkuY29uY2F0KGNpcGhlcnRleHQpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheSA9IGNpcGhlcnRleHQ7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gd29yZEFycmF5LnRvU3RyaW5nKEJhc2U2NCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcgdG8gYSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVuU1NMU3RyIFRoZSBPcGVuU1NMLWNvbXBhdGlibGUgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgY2lwaGVyIHBhcmFtcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJQYXJhbXMgPSBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTC5wYXJzZShvcGVuU1NMU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKG9wZW5TU0xTdHIpIHtcblx0ICAgICAgICAgICAgLy8gUGFyc2UgYmFzZTY0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0ID0gQmFzZTY0LnBhcnNlKG9wZW5TU0xTdHIpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0V29yZHMgPSBjaXBoZXJ0ZXh0LndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFRlc3QgZm9yIHNhbHRcblx0ICAgICAgICAgICAgaWYgKGNpcGhlcnRleHRXb3Jkc1swXSA9PSAweDUzNjE2Yzc0ICYmIGNpcGhlcnRleHRXb3Jkc1sxXSA9PSAweDY1NjQ1ZjVmKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IHNhbHRcblx0ICAgICAgICAgICAgICAgIHZhciBzYWx0ID0gV29yZEFycmF5LmNyZWF0ZShjaXBoZXJ0ZXh0V29yZHMuc2xpY2UoMiwgNCkpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgc2FsdCBmcm9tIGNpcGhlcnRleHRcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHRXb3Jkcy5zcGxpY2UoMCwgNCk7XG5cdCAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0LnNpZ0J5dGVzIC09IDE2O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoeyBjaXBoZXJ0ZXh0OiBjaXBoZXJ0ZXh0LCBzYWx0OiBzYWx0IH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQSBjaXBoZXIgd3JhcHBlciB0aGF0IHJldHVybnMgY2lwaGVydGV4dCBhcyBhIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAqL1xuXHQgICAgdmFyIFNlcmlhbGl6YWJsZUNpcGhlciA9IENfbGliLlNlcmlhbGl6YWJsZUNpcGhlciA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0Zvcm1hdHRlcn0gZm9ybWF0IFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIGNvbnZlcnQgY2lwaGVyIHBhcmFtIG9iamVjdHMgdG8gYW5kIGZyb20gYSBzdHJpbmcuIERlZmF1bHQ6IE9wZW5TU0xcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjZmc6IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgZm9ybWF0OiBPcGVuU1NMRm9ybWF0dGVyXG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBFbmNyeXB0cyBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gZW5jcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gQSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuU2VyaWFsaXphYmxlQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsIGtleSk7XG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBtZXNzYWdlLCBrZXksIHsgaXY6IGl2IH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5TZXJpYWxpemFibGVDaXBoZXIuZW5jcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgbWVzc2FnZSwga2V5LCB7IGl2OiBpdiwgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgZW5jcnlwdG9yID0gY2lwaGVyLmNyZWF0ZUVuY3J5cHRvcihrZXksIGNmZyk7XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0ID0gZW5jcnlwdG9yLmZpbmFsaXplKG1lc3NhZ2UpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJDZmcgPSBlbmNyeXB0b3IuY2ZnO1xuXG5cdCAgICAgICAgICAgIC8vIENyZWF0ZSBhbmQgcmV0dXJuIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zXG5cdCAgICAgICAgICAgIHJldHVybiBDaXBoZXJQYXJhbXMuY3JlYXRlKHtcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHQ6IGNpcGhlcnRleHQsXG5cdCAgICAgICAgICAgICAgICBrZXk6IGtleSxcblx0ICAgICAgICAgICAgICAgIGl2OiBjaXBoZXJDZmcuaXYsXG5cdCAgICAgICAgICAgICAgICBhbGdvcml0aG06IGNpcGhlcixcblx0ICAgICAgICAgICAgICAgIG1vZGU6IGNpcGhlckNmZy5tb2RlLFxuXHQgICAgICAgICAgICAgICAgcGFkZGluZzogY2lwaGVyQ2ZnLnBhZGRpbmcsXG5cdCAgICAgICAgICAgICAgICBibG9ja1NpemU6IGNpcGhlci5ibG9ja1NpemUsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IGNmZy5mb3JtYXRcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlY3J5cHRzIHNlcmlhbGl6ZWQgY2lwaGVydGV4dC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfHN0cmluZ30gY2lwaGVydGV4dCBUaGUgY2lwaGVydGV4dCB0byBkZWNyeXB0LlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcGxhaW50ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0IHN0cmluZyB0byBDaXBoZXJQYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dCA9IHRoaXMuX3BhcnNlKGNpcGhlcnRleHQsIGNmZy5mb3JtYXQpO1xuXG5cdCAgICAgICAgICAgIC8vIERlY3J5cHRcblx0ICAgICAgICAgICAgdmFyIHBsYWludGV4dCA9IGNpcGhlci5jcmVhdGVEZWNyeXB0b3Ioa2V5LCBjZmcpLmZpbmFsaXplKGNpcGhlcnRleHQuY2lwaGVydGV4dCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHRvIENpcGhlclBhcmFtcyxcblx0ICAgICAgICAgKiBlbHNlIGFzc3VtZWQgQ2lwaGVyUGFyYW1zIGFscmVhZHkgYW5kIHJldHVybnMgY2lwaGVydGV4dCB1bmNoYW5nZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtGb3JtYXR0ZXJ9IGZvcm1hdCBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byB1c2UgdG8gcGFyc2Ugc2VyaWFsaXplZCBjaXBoZXJ0ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgdW5zZXJpYWxpemVkIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5fcGFyc2UoY2lwaGVydGV4dFN0cmluZ09yUGFyYW1zLCBmb3JtYXQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wYXJzZTogZnVuY3Rpb24gKGNpcGhlcnRleHQsIGZvcm1hdCkge1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXQucGFyc2UoY2lwaGVydGV4dCwgdGhpcyk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfa2RmID0gQy5rZGYgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBPcGVuU1NMIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uLlxuXHQgICAgICovXG5cdCAgICB2YXIgT3BlblNTTEtkZiA9IENfa2RmLk9wZW5TU0wgPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVyaXZlcyBhIGtleSBhbmQgSVYgZnJvbSBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZCB0byBkZXJpdmUgZnJvbS5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0ga2V5U2l6ZSBUaGUgc2l6ZSBpbiB3b3JkcyBvZiB0aGUga2V5IHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpdlNpemUgVGhlIHNpemUgaW4gd29yZHMgb2YgdGhlIElWIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gc2FsdCAoT3B0aW9uYWwpIEEgNjQtYml0IHNhbHQgdG8gdXNlLiBJZiBvbWl0dGVkLCBhIHNhbHQgd2lsbCBiZSBnZW5lcmF0ZWQgcmFuZG9tbHkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IEEgY2lwaGVyIHBhcmFtcyBvYmplY3Qgd2l0aCB0aGUga2V5LCBJViwgYW5kIHNhbHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMik7XG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMiwgJ3NhbHRzYWx0Jyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZXhlY3V0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBrZXlTaXplLCBpdlNpemUsIHNhbHQpIHtcblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUgcmFuZG9tIHNhbHRcblx0ICAgICAgICAgICAgaWYgKCFzYWx0KSB7XG5cdCAgICAgICAgICAgICAgICBzYWx0ID0gV29yZEFycmF5LnJhbmRvbSg2NC84KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIERlcml2ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBrZXkgPSBFdnBLREYuY3JlYXRlKHsga2V5U2l6ZToga2V5U2l6ZSArIGl2U2l6ZSB9KS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTtcblxuXHQgICAgICAgICAgICAvLyBTZXBhcmF0ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBpdiA9IFdvcmRBcnJheS5jcmVhdGUoa2V5LndvcmRzLnNsaWNlKGtleVNpemUpLCBpdlNpemUgKiA0KTtcblx0ICAgICAgICAgICAga2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gUmV0dXJuIHBhcmFtc1xuXHQgICAgICAgICAgICByZXR1cm4gQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7IGtleToga2V5LCBpdjogaXYsIHNhbHQ6IHNhbHQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBIHNlcmlhbGl6YWJsZSBjaXBoZXIgd3JhcHBlciB0aGF0IGRlcml2ZXMgdGhlIGtleSBmcm9tIGEgcGFzc3dvcmQsXG5cdCAgICAgKiBhbmQgcmV0dXJucyBjaXBoZXJ0ZXh0IGFzIGEgc2VyaWFsaXphYmxlIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICovXG5cdCAgICB2YXIgUGFzc3dvcmRCYXNlZENpcGhlciA9IENfbGliLlBhc3N3b3JkQmFzZWRDaXBoZXIgPSBTZXJpYWxpemFibGVDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0tERn0ga2RmIFRoZSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbiB0byB1c2UgdG8gZ2VuZXJhdGUgYSBrZXkgYW5kIElWIGZyb20gYSBwYXNzd29yZC4gRGVmYXVsdDogT3BlblNTTFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogU2VyaWFsaXphYmxlQ2lwaGVyLmNmZy5leHRlbmQoe1xuXHQgICAgICAgICAgICBrZGY6IE9wZW5TU0xLZGZcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEVuY3J5cHRzIGEgbWVzc2FnZSB1c2luZyBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBUaGUgY2lwaGVyIGFsZ29yaXRobSB0byB1c2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGVuY3J5cHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBBIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcpO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcsIHsgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBwYXNzd29yZCwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplKTtcblxuXHQgICAgICAgICAgICAvLyBBZGQgSVYgdG8gY29uZmlnXG5cdCAgICAgICAgICAgIGNmZy5pdiA9IGRlcml2ZWRQYXJhbXMuaXY7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IFNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0LmNhbGwodGhpcywgY2lwaGVyLCBtZXNzYWdlLCBkZXJpdmVkUGFyYW1zLmtleSwgY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBNaXggaW4gZGVyaXZlZCBwYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dC5taXhJbihkZXJpdmVkUGFyYW1zKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVjcnlwdHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHVzaW5nIGEgcGFzc3dvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQgdG8gZGVjcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmQgVGhlIHBhc3N3b3JkLlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwbGFpbnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZGVjcnlwdDogZnVuY3Rpb24gKGNpcGhlciwgY2lwaGVydGV4dCwgcGFzc3dvcmQsIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gQ2lwaGVyUGFyYW1zXG5cdCAgICAgICAgICAgIGNpcGhlcnRleHQgPSB0aGlzLl9wYXJzZShjaXBoZXJ0ZXh0LCBjZmcuZm9ybWF0KTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplLCBjaXBoZXJ0ZXh0LnNhbHQpO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBJViB0byBjb25maWdcblx0ICAgICAgICAgICAgY2ZnLml2ID0gZGVyaXZlZFBhcmFtcy5pdjtcblxuXHQgICAgICAgICAgICAvLyBEZWNyeXB0XG5cdCAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBTZXJpYWxpemFibGVDaXBoZXIuZGVjcnlwdC5jYWxsKHRoaXMsIGNpcGhlciwgY2lwaGVydGV4dCwgZGVyaXZlZFBhcmFtcy5rZXksIGNmZyk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0fSgpKTtcblxuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdHJvb3QuQ3J5cHRvSlMgPSBmYWN0b3J5KCk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuXG5cdC8qKlxuXHQgKiBDcnlwdG9KUyBjb3JlIGNvbXBvbmVudHMuXG5cdCAqL1xuXHR2YXIgQ3J5cHRvSlMgPSBDcnlwdG9KUyB8fCAoZnVuY3Rpb24gKE1hdGgsIHVuZGVmaW5lZCkge1xuXHQgICAgLypcblx0ICAgICAqIExvY2FsIHBvbHlmaWwgb2YgT2JqZWN0LmNyZWF0ZVxuXHQgICAgICovXG5cdCAgICB2YXIgY3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGZ1bmN0aW9uIEYoKSB7fTtcblxuXHQgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7XG5cdCAgICAgICAgICAgIHZhciBzdWJ0eXBlO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gb2JqO1xuXG5cdCAgICAgICAgICAgIHN1YnR5cGUgPSBuZXcgRigpO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gbnVsbDtcblxuXHQgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICB9O1xuXHQgICAgfSgpKVxuXG5cdCAgICAvKipcblx0ICAgICAqIENyeXB0b0pTIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBMaWJyYXJ5IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfbGliID0gQy5saWIgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBCYXNlIG9iamVjdCBmb3IgcHJvdG90eXBhbCBpbmhlcml0YW5jZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlID0gKGZ1bmN0aW9uICgpIHtcblxuXG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGlzIG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG92ZXJyaWRlcyBQcm9wZXJ0aWVzIHRvIGNvcHkgaW50byB0aGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiAgICAgdmFyIE15VHlwZSA9IENyeXB0b0pTLmxpYi5CYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgZmllbGQ6ICd2YWx1ZScsXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgfVxuXHQgICAgICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBleHRlbmQ6IGZ1bmN0aW9uIChvdmVycmlkZXMpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNwYXduXG5cdCAgICAgICAgICAgICAgICB2YXIgc3VidHlwZSA9IGNyZWF0ZSh0aGlzKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gQXVnbWVudFxuXHQgICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlcykge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1YnR5cGUubWl4SW4ob3ZlcnJpZGVzKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGRlZmF1bHQgaW5pdGlhbGl6ZXJcblx0ICAgICAgICAgICAgICAgIGlmICghc3VidHlwZS5oYXNPd25Qcm9wZXJ0eSgnaW5pdCcpIHx8IHRoaXMuaW5pdCA9PT0gc3VidHlwZS5pbml0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgc3VidHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlci5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZXIncyBwcm90b3R5cGUgaXMgdGhlIHN1YnR5cGUgb2JqZWN0XG5cdCAgICAgICAgICAgICAgICBzdWJ0eXBlLmluaXQucHJvdG90eXBlID0gc3VidHlwZTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVmZXJlbmNlIHN1cGVydHlwZVxuXHQgICAgICAgICAgICAgICAgc3VidHlwZS4kc3VwZXIgPSB0aGlzO1xuXG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogRXh0ZW5kcyB0aGlzIG9iamVjdCBhbmQgcnVucyB0aGUgaW5pdCBtZXRob2QuXG5cdCAgICAgICAgICAgICAqIEFyZ3VtZW50cyB0byBjcmVhdGUoKSB3aWxsIGJlIHBhc3NlZCB0byBpbml0KCkuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIG5ldyBvYmplY3QuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBpbnN0YW5jZSA9IE15VHlwZS5jcmVhdGUoKTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gdGhpcy5leHRlbmQoKTtcblx0ICAgICAgICAgICAgICAgIGluc3RhbmNlLmluaXQuYXBwbHkoaW5zdGFuY2UsIGFyZ3VtZW50cyk7XG5cblx0ICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG9iamVjdC5cblx0ICAgICAgICAgICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gYWRkIHNvbWUgbG9naWMgd2hlbiB5b3VyIG9iamVjdHMgYXJlIGNyZWF0ZWQuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICB2YXIgTXlUeXBlID0gQ3J5cHRvSlMubGliLkJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgICogICAgICAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgICAgIC8vIC4uLlxuXHQgICAgICAgICAgICAgKiAgICAgICAgIH1cblx0ICAgICAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB9LFxuXG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBDb3BpZXMgcHJvcGVydGllcyBpbnRvIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBUaGUgcHJvcGVydGllcyB0byBtaXggaW4uXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBNeVR5cGUubWl4SW4oe1xuXHQgICAgICAgICAgICAgKiAgICAgICAgIGZpZWxkOiAndmFsdWUnXG5cdCAgICAgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIG1peEluOiBmdW5jdGlvbiAocHJvcGVydGllcykge1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcGVydHlOYW1lIGluIHByb3BlcnRpZXMpIHtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcHJvcGVydHlOYW1lXSA9IHByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIC8vIElFIHdvbid0IGNvcHkgdG9TdHJpbmcgdXNpbmcgdGhlIGxvb3AgYWJvdmVcblx0ICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KCd0b1N0cmluZycpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy50b1N0cmluZyA9IHByb3BlcnRpZXMudG9TdHJpbmc7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0sXG5cblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IGluc3RhbmNlLmNsb25lKCk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5pdC5wcm90b3R5cGUuZXh0ZW5kKHRoaXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH0oKSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiAzMi1iaXQgd29yZHMuXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gc2lnQnl0ZXMgVGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBieXRlcyBpbiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgKi9cblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyAoT3B0aW9uYWwpIEFuIGFycmF5IG9mIDMyLWJpdCB3b3Jkcy5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gc2lnQnl0ZXMgKE9wdGlvbmFsKSBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoZSB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKCk7XG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbMHgwMDAxMDIwMywgMHgwNDA1MDYwN10pO1xuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoWzB4MDAwMTAyMDMsIDB4MDQwNTA2MDddLCA2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAod29yZHMsIHNpZ0J5dGVzKSB7XG5cdCAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdO1xuXG5cdCAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSBzaWdCeXRlcztcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSB3b3Jkcy5sZW5ndGggKiA0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIHRoaXMgd29yZCBhcnJheSB0byBhIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlciAoT3B0aW9uYWwpIFRoZSBlbmNvZGluZyBzdHJhdGVneSB0byB1c2UuIERlZmF1bHQ6IENyeXB0b0pTLmVuYy5IZXhcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkgKyAnJztcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IHdvcmRBcnJheS50b1N0cmluZygpO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gd29yZEFycmF5LnRvU3RyaW5nKENyeXB0b0pTLmVuYy5VdGY4KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0b1N0cmluZzogZnVuY3Rpb24gKGVuY29kZXIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIChlbmNvZGVyIHx8IEhleCkuc3RyaW5naWZ5KHRoaXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25jYXRlbmF0ZXMgYSB3b3JkIGFycmF5IHRvIHRoaXMgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheTEuY29uY2F0KHdvcmRBcnJheTIpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbmNhdDogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHRoaXNXb3JkcyA9IHRoaXMud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGF0V29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGlzU2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXHQgICAgICAgICAgICB2YXIgdGhhdFNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzXG5cdCAgICAgICAgICAgIHRoaXMuY2xhbXAoKTtcblxuXHQgICAgICAgICAgICAvLyBDb25jYXRcblx0ICAgICAgICAgICAgaWYgKHRoaXNTaWdCeXRlcyAlIDQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIENvcHkgb25lIGJ5dGUgYXQgYSB0aW1lXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoYXRTaWdCeXRlczsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHRoYXRCeXRlID0gKHRoYXRXb3Jkc1tpID4+PiAyXSA+Pj4gKDI0IC0gKGkgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpc1dvcmRzWyh0aGlzU2lnQnl0ZXMgKyBpKSA+Pj4gMl0gfD0gdGhhdEJ5dGUgPDwgKDI0IC0gKCh0aGlzU2lnQnl0ZXMgKyBpKSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBDb3B5IG9uZSB3b3JkIGF0IGEgdGltZVxuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGF0U2lnQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXNXb3Jkc1sodGhpc1NpZ0J5dGVzICsgaSkgPj4+IDJdID0gdGhhdFdvcmRzW2kgPj4+IDJdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgKz0gdGhhdFNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVtb3ZlcyBpbnNpZ25pZmljYW50IGJpdHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheS5jbGFtcCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsYW1wOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB0aGlzLndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wXG5cdCAgICAgICAgICAgIHdvcmRzW3NpZ0J5dGVzID4+PiAyXSAmPSAweGZmZmZmZmZmIDw8ICgzMiAtIChzaWdCeXRlcyAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIHdvcmRzLmxlbmd0aCA9IE1hdGguY2VpbChzaWdCeXRlcyAvIDQpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gd29yZEFycmF5LmNsb25lKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gQmFzZS5jbG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICBjbG9uZS53b3JkcyA9IHRoaXMud29yZHMuc2xpY2UoMCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgd29yZCBhcnJheSBmaWxsZWQgd2l0aCByYW5kb20gYnl0ZXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbkJ5dGVzIFRoZSBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcmFuZG9tIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSgxNik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcmFuZG9tOiBmdW5jdGlvbiAobkJ5dGVzKSB7XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXG5cdCAgICAgICAgICAgIHZhciByID0gKGZ1bmN0aW9uIChtX3cpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBtX3cgPSBtX3c7XG5cdCAgICAgICAgICAgICAgICB2YXIgbV96ID0gMHgzYWRlNjhiMTtcblx0ICAgICAgICAgICAgICAgIHZhciBtYXNrID0gMHhmZmZmZmZmZjtcblxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgICAgICBtX3ogPSAoMHg5MDY5ICogKG1feiAmIDB4RkZGRikgKyAobV96ID4+IDB4MTApKSAmIG1hc2s7XG5cdCAgICAgICAgICAgICAgICAgICAgbV93ID0gKDB4NDY1MCAqIChtX3cgJiAweEZGRkYpICsgKG1fdyA+PiAweDEwKSkgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSAoKG1feiA8PCAweDEwKSArIG1fdykgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAvPSAweDEwMDAwMDAwMDtcblx0ICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gMC41O1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgKiAoTWF0aC5yYW5kb20oKSA+IC41ID8gMSA6IC0xKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIHJjYWNoZTsgaSA8IG5CeXRlczsgaSArPSA0KSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgX3IgPSByKChyY2FjaGUgfHwgTWF0aC5yYW5kb20oKSkgKiAweDEwMDAwMDAwMCk7XG5cblx0ICAgICAgICAgICAgICAgIHJjYWNoZSA9IF9yKCkgKiAweDNhZGU2N2I3O1xuXHQgICAgICAgICAgICAgICAgd29yZHMucHVzaCgoX3IoKSAqIDB4MTAwMDAwMDAwKSB8IDApO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBXb3JkQXJyYXkuaW5pdCh3b3JkcywgbkJ5dGVzKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBFbmNvZGVyIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZW5jID0gQy5lbmMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBIZXggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBIZXggPSBDX2VuYy5IZXggPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBoZXggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGV4U3RyaW5nID0gQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IHdvcmRBcnJheS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgdmFyIGhleENoYXJzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJpdGUgPSAod29yZHNbaSA+Pj4gMl0gPj4+ICgyNCAtIChpICUgNCkgKiA4KSkgJiAweGZmO1xuXHQgICAgICAgICAgICAgICAgaGV4Q2hhcnMucHVzaCgoYml0ZSA+Pj4gNCkudG9TdHJpbmcoMTYpKTtcblx0ICAgICAgICAgICAgICAgIGhleENoYXJzLnB1c2goKGJpdGUgJiAweDBmKS50b1N0cmluZygxNikpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhleENoYXJzLmpvaW4oJycpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGhleFN0ciBUaGUgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGhleFN0cmluZyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChoZXhTdHIpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhleFN0ckxlbmd0aCA9IGhleFN0ci5sZW5ndGg7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXhTdHJMZW5ndGg7IGkgKz0gMikge1xuXHQgICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gM10gfD0gcGFyc2VJbnQoaGV4U3RyLnN1YnN0cihpLCAyKSwgMTYpIDw8ICgyNCAtIChpICUgOCkgKiA0KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQod29yZHMsIGhleFN0ckxlbmd0aCAvIDIpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogTGF0aW4xIGVuY29kaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgTGF0aW4xID0gQ19lbmMuTGF0aW4xID0ge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIExhdGluMSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgTGF0aW4xIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGxhdGluMVN0cmluZyA9IENyeXB0b0pTLmVuYy5MYXRpbjEuc3RyaW5naWZ5KHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlcztcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciBsYXRpbjFDaGFycyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBiaXRlID0gKHdvcmRzW2kgPj4+IDJdID4+PiAoMjQgLSAoaSAlIDQpICogOCkpICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIGxhdGluMUNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShiaXRlKSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbGF0aW4xQ2hhcnMuam9pbignJyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgTGF0aW4xIHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF0aW4xU3RyIFRoZSBMYXRpbjEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5MYXRpbjEucGFyc2UobGF0aW4xU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKGxhdGluMVN0cikge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgbGF0aW4xU3RyTGVuZ3RoID0gbGF0aW4xU3RyLmxlbmd0aDtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhdGluMVN0ckxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAyXSB8PSAobGF0aW4xU3RyLmNoYXJDb2RlQXQoaSkgJiAweGZmKSA8PCAoMjQgLSAoaSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBsYXRpbjFTdHJMZW5ndGgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogVVRGLTggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmOCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBVVEYtOCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgdXRmOFN0cmluZyA9IENyeXB0b0pTLmVuYy5VdGY4LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUoTGF0aW4xLnN0cmluZ2lmeSh3b3JkQXJyYXkpKSk7XG5cdCAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWFsZm9ybWVkIFVURi04IGRhdGEnKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi04IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXRmOFN0ciBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5VdGY4LnBhcnNlKHV0ZjhTdHJpbmcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmOFN0cikge1xuXHQgICAgICAgICAgICByZXR1cm4gTGF0aW4xLnBhcnNlKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudCh1dGY4U3RyKSkpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYnVmZmVyZWQgYmxvY2sgYWxnb3JpdGhtIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIFRoZSBwcm9wZXJ0eSBibG9ja1NpemUgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiBhIGNvbmNyZXRlIHN1YnR5cGUuXG5cdCAgICAgKlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9taW5CdWZmZXJTaXplIFRoZSBudW1iZXIgb2YgYmxvY2tzIHRoYXQgc2hvdWxkIGJlIGtlcHQgdW5wcm9jZXNzZWQgaW4gdGhlIGJ1ZmZlci4gRGVmYXVsdDogMFxuXHQgICAgICovXG5cdCAgICB2YXIgQnVmZmVyZWRCbG9ja0FsZ29yaXRobSA9IENfbGliLkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVzZXRzIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgZGF0YSBidWZmZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLl9kYXRhID0gbmV3IFdvcmRBcnJheS5pbml0KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX25EYXRhQnl0ZXMgPSAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBZGRzIG5ldyBkYXRhIHRvIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgYnVmZmVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGFwcGVuZC4gU3RyaW5ncyBhcmUgY29udmVydGVkIHRvIGEgV29yZEFycmF5IHVzaW5nIFVURi04LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9hcHBlbmQoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fYXBwZW5kKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2FwcGVuZDogZnVuY3Rpb24gKGRhdGEpIHtcblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIGRhdGEgPSBVdGY4LnBhcnNlKGRhdGEpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQXBwZW5kXG5cdCAgICAgICAgICAgIHRoaXMuX2RhdGEuY29uY2F0KGRhdGEpO1xuXHQgICAgICAgICAgICB0aGlzLl9uRGF0YUJ5dGVzICs9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFByb2Nlc3NlcyBhdmFpbGFibGUgZGF0YSBibG9ja3MuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIF9kb1Byb2Nlc3NCbG9jayhvZmZzZXQpLCB3aGljaCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGEgY29uY3JldGUgc3VidHlwZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9GbHVzaCBXaGV0aGVyIGFsbCBibG9ja3MgYW5kIHBhcnRpYWwgYmxvY2tzIHNob3VsZCBiZSBwcm9jZXNzZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwcm9jZXNzZWQgZGF0YS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHByb2Nlc3NlZERhdGEgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9wcm9jZXNzKCk7XG5cdCAgICAgICAgICogICAgIHZhciBwcm9jZXNzZWREYXRhID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fcHJvY2VzcyghISdmbHVzaCcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wcm9jZXNzOiBmdW5jdGlvbiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIGRhdGFTaWdCeXRlcyA9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSB0aGlzLmJsb2NrU2l6ZTtcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBibG9ja3MgcmVhZHlcblx0ICAgICAgICAgICAgdmFyIG5CbG9ja3NSZWFkeSA9IGRhdGFTaWdCeXRlcyAvIGJsb2NrU2l6ZUJ5dGVzO1xuXHQgICAgICAgICAgICBpZiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAgICAgLy8gUm91bmQgdXAgdG8gaW5jbHVkZSBwYXJ0aWFsIGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgbkJsb2Nrc1JlYWR5ID0gTWF0aC5jZWlsKG5CbG9ja3NSZWFkeSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBSb3VuZCBkb3duIHRvIGluY2x1ZGUgb25seSBmdWxsIGJsb2Nrcyxcblx0ICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhlIG51bWJlciBvZiBibG9ja3MgdGhhdCBtdXN0IHJlbWFpbiBpbiB0aGUgYnVmZmVyXG5cdCAgICAgICAgICAgICAgICBuQmxvY2tzUmVhZHkgPSBNYXRoLm1heCgobkJsb2Nrc1JlYWR5IHwgMCkgLSB0aGlzLl9taW5CdWZmZXJTaXplLCAwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIENvdW50IHdvcmRzIHJlYWR5XG5cdCAgICAgICAgICAgIHZhciBuV29yZHNSZWFkeSA9IG5CbG9ja3NSZWFkeSAqIGJsb2NrU2l6ZTtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBieXRlcyByZWFkeVxuXHQgICAgICAgICAgICB2YXIgbkJ5dGVzUmVhZHkgPSBNYXRoLm1pbihuV29yZHNSZWFkeSAqIDQsIGRhdGFTaWdCeXRlcyk7XG5cblx0ICAgICAgICAgICAgLy8gUHJvY2VzcyBibG9ja3Ncblx0ICAgICAgICAgICAgaWYgKG5Xb3Jkc1JlYWR5KSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBvZmZzZXQgPSAwOyBvZmZzZXQgPCBuV29yZHNSZWFkeTsgb2Zmc2V0ICs9IGJsb2NrU2l6ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtYWxnb3JpdGhtIGxvZ2ljXG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fZG9Qcm9jZXNzQmxvY2soZGF0YVdvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgICAgICB2YXIgcHJvY2Vzc2VkV29yZHMgPSBkYXRhV29yZHMuc3BsaWNlKDAsIG5Xb3Jkc1JlYWR5KTtcblx0ICAgICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgLT0gbkJ5dGVzUmVhZHk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQocHJvY2Vzc2VkV29yZHMsIG5CeXRlc1JlYWR5KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5jbG9uZSgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBjbG9uZSA9IEJhc2UuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2RhdGEgPSB0aGlzLl9kYXRhLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfbWluQnVmZmVyU2l6ZTogMFxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgaGFzaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBoYXNoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDE2ICg1MTIgYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBoYXNoIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaGVyID0gQ3J5cHRvSlMuYWxnby5TSEEyNTYuY3JlYXRlKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgaW5pdDogZnVuY3Rpb24gKGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXNldHMgdGhpcyBoYXNoZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGRhdGEgYnVmZmVyXG5cdCAgICAgICAgICAgIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQuY2FsbCh0aGlzKTtcblxuXHQgICAgICAgICAgICAvLyBQZXJmb3JtIGNvbmNyZXRlLWhhc2hlciBsb2dpY1xuXHQgICAgICAgICAgICB0aGlzLl9kb1Jlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFVwZGF0ZXMgdGhpcyBoYXNoZXIgd2l0aCBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgVGhlIG1lc3NhZ2UgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7SGFzaGVyfSBUaGlzIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICBoYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBBcHBlbmRcblx0ICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgaGFzaFxuXHQgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2hhaW5hYmxlXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIGhhc2ggY29tcHV0YXRpb24uXG5cdCAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSAoT3B0aW9uYWwpIEEgZmluYWwgbWVzc2FnZSB1cGRhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBGaW5hbCBtZXNzYWdlIHVwZGF0ZVxuXHQgICAgICAgICAgICBpZiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1oYXNoZXIgbG9naWNcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9kb0ZpbmFsaXplKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhhc2g7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogNTEyLzMyLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIHNob3J0Y3V0IGZ1bmN0aW9uIHRvIGEgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7SGFzaGVyfSBoYXNoZXIgVGhlIGhhc2hlciB0byBjcmVhdGUgYSBoZWxwZXIgZm9yLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIFNIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhlbHBlcihDcnlwdG9KUy5hbGdvLlNIQTI1Nik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2NyZWF0ZUhlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGNmZykge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBoYXNoZXIuaW5pdChjZmcpLmZpbmFsaXplKG1lc3NhZ2UpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgc2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZSBpbiB0aGlzIEhNQUMgaGVscGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIEhtYWNTSEEyNTYgPSBDcnlwdG9KUy5saWIuSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKENyeXB0b0pTLmFsZ28uU0hBMjU2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBfY3JlYXRlSG1hY0hlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGtleSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDX2FsZ28uSE1BQy5pbml0KGhhc2hlciwga2V5KS5maW5hbGl6ZShtZXNzYWdlKTtcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBbGdvcml0aG0gbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvID0ge307XG5cblx0ICAgIHJldHVybiBDO1xuXHR9KE1hdGgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblx0ICAgIHZhciBDX2VuYyA9IEMuZW5jO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEJhc2U2NCBlbmNvZGluZyBzdHJhdGVneS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJhc2U2NCA9IENfZW5jLkJhc2U2NCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBCYXNlNjQgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIEJhc2U2NCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBiYXNlNjRTdHJpbmcgPSBDcnlwdG9KUy5lbmMuQmFzZTY0LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB3b3JkQXJyYXkuc2lnQnl0ZXM7XG5cdCAgICAgICAgICAgIHZhciBtYXAgPSB0aGlzLl9tYXA7XG5cblx0ICAgICAgICAgICAgLy8gQ2xhbXAgZXhjZXNzIGJpdHNcblx0ICAgICAgICAgICAgd29yZEFycmF5LmNsYW1wKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgYmFzZTY0Q2hhcnMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWdCeXRlczsgaSArPSAzKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgYnl0ZTEgPSAod29yZHNbaSA+Pj4gMl0gICAgICAgPj4+ICgyNCAtIChpICUgNCkgKiA4KSkgICAgICAgJiAweGZmO1xuXHQgICAgICAgICAgICAgICAgdmFyIGJ5dGUyID0gKHdvcmRzWyhpICsgMSkgPj4+IDJdID4+PiAoMjQgLSAoKGkgKyAxKSAlIDQpICogOCkpICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIHZhciBieXRlMyA9ICh3b3Jkc1soaSArIDIpID4+PiAyXSA+Pj4gKDI0IC0gKChpICsgMikgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cblx0ICAgICAgICAgICAgICAgIHZhciB0cmlwbGV0ID0gKGJ5dGUxIDw8IDE2KSB8IChieXRlMiA8PCA4KSB8IGJ5dGUzO1xuXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgKGogPCA0KSAmJiAoaSArIGogKiAwLjc1IDwgc2lnQnl0ZXMpOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKG1hcC5jaGFyQXQoKHRyaXBsZXQgPj4+ICg2ICogKDMgLSBqKSkpICYgMHgzZikpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmdDaGFyID0gbWFwLmNoYXJBdCg2NCk7XG5cdCAgICAgICAgICAgIGlmIChwYWRkaW5nQ2hhcikge1xuXHQgICAgICAgICAgICAgICAgd2hpbGUgKGJhc2U2NENoYXJzLmxlbmd0aCAlIDQpIHtcblx0ICAgICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKHBhZGRpbmdDaGFyKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBiYXNlNjRDaGFycy5qb2luKCcnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSBCYXNlNjQgc3RyaW5nIHRvIGEgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlNjRTdHIgVGhlIEJhc2U2NCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLkJhc2U2NC5wYXJzZShiYXNlNjRTdHJpbmcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAoYmFzZTY0U3RyKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgYmFzZTY0U3RyTGVuZ3RoID0gYmFzZTY0U3RyLmxlbmd0aDtcblx0ICAgICAgICAgICAgdmFyIG1hcCA9IHRoaXMuX21hcDtcblx0ICAgICAgICAgICAgdmFyIHJldmVyc2VNYXAgPSB0aGlzLl9yZXZlcnNlTWFwO1xuXG5cdCAgICAgICAgICAgIGlmICghcmV2ZXJzZU1hcCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldmVyc2VNYXAgPSB0aGlzLl9yZXZlcnNlTWFwID0gW107XG5cdCAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYXAubGVuZ3RoOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZU1hcFttYXAuY2hhckNvZGVBdChqKV0gPSBqO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElnbm9yZSBwYWRkaW5nXG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nQ2hhciA9IG1hcC5jaGFyQXQoNjQpO1xuXHQgICAgICAgICAgICBpZiAocGFkZGluZ0NoYXIpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nSW5kZXggPSBiYXNlNjRTdHIuaW5kZXhPZihwYWRkaW5nQ2hhcik7XG5cdCAgICAgICAgICAgICAgICBpZiAocGFkZGluZ0luZGV4ICE9PSAtMSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGJhc2U2NFN0ckxlbmd0aCA9IHBhZGRpbmdJbmRleDtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgcmV0dXJuIHBhcnNlTG9vcChiYXNlNjRTdHIsIGJhc2U2NFN0ckxlbmd0aCwgcmV2ZXJzZU1hcCk7XG5cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX21hcDogJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89J1xuXHQgICAgfTtcblxuXHQgICAgZnVuY3Rpb24gcGFyc2VMb29wKGJhc2U2NFN0ciwgYmFzZTY0U3RyTGVuZ3RoLCByZXZlcnNlTWFwKSB7XG5cdCAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICB2YXIgbkJ5dGVzID0gMDtcblx0ICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiYXNlNjRTdHJMZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgaWYgKGkgJSA0KSB7XG5cdCAgICAgICAgICAgICAgdmFyIGJpdHMxID0gcmV2ZXJzZU1hcFtiYXNlNjRTdHIuY2hhckNvZGVBdChpIC0gMSldIDw8ICgoaSAlIDQpICogMik7XG5cdCAgICAgICAgICAgICAgdmFyIGJpdHMyID0gcmV2ZXJzZU1hcFtiYXNlNjRTdHIuY2hhckNvZGVBdChpKV0gPj4+ICg2IC0gKGkgJSA0KSAqIDIpO1xuXHQgICAgICAgICAgICAgIHdvcmRzW25CeXRlcyA+Pj4gMl0gfD0gKGJpdHMxIHwgYml0czIpIDw8ICgyNCAtIChuQnl0ZXMgJSA0KSAqIDgpO1xuXHQgICAgICAgICAgICAgIG5CeXRlcysrO1xuXHQgICAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiBXb3JkQXJyYXkuY3JlYXRlKHdvcmRzLCBuQnl0ZXMpO1xuXHQgICAgfVxuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLmVuYy5CYXNlNjQ7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdHJldHVybiBDcnlwdG9KUy5lbmMuSGV4O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL3NoYTFcIiksIHJlcXVpcmUoXCIuL2htYWNcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4vc2hhMVwiLCBcIi4vaG1hY1wiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cdCAgICB2YXIgTUQ1ID0gQ19hbGdvLk1ENTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBUaGlzIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIGlzIG1lYW50IHRvIGNvbmZvcm0gd2l0aCBFVlBfQnl0ZXNUb0tleS5cblx0ICAgICAqIHd3dy5vcGVuc3NsLm9yZy9kb2NzL2NyeXB0by9FVlBfQnl0ZXNUb0tleS5odG1sXG5cdCAgICAgKi9cblx0ICAgIHZhciBFdnBLREYgPSBDX2FsZ28uRXZwS0RGID0gQmFzZS5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBrZXlTaXplIFRoZSBrZXkgc2l6ZSBpbiB3b3JkcyB0byBnZW5lcmF0ZS4gRGVmYXVsdDogNCAoMTI4IGJpdHMpXG5cdCAgICAgICAgICogQHByb3BlcnR5IHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaCBhbGdvcml0aG0gdG8gdXNlLiBEZWZhdWx0OiBNRDVcblx0ICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gaXRlcmF0aW9ucyBUaGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdG8gcGVyZm9ybS4gRGVmYXVsdDogMVxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogQmFzZS5leHRlbmQoe1xuXHQgICAgICAgICAgICBrZXlTaXplOiAxMjgvMzIsXG5cdCAgICAgICAgICAgIGhhc2hlcjogTUQ1LFxuXHQgICAgICAgICAgICBpdGVyYXRpb25zOiAxXG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQga2V5IGRlcml2YXRpb24gZnVuY3Rpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoZSBkZXJpdmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIga2RmID0gQ3J5cHRvSlMuYWxnby5FdnBLREYuY3JlYXRlKCk7XG5cdCAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoeyBrZXlTaXplOiA4IH0pO1xuXHQgICAgICAgICAqICAgICB2YXIga2RmID0gQ3J5cHRvSlMuYWxnby5FdnBLREYuY3JlYXRlKHsga2V5U2l6ZTogOCwgaXRlcmF0aW9uczogMTAwMCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2ZnKSB7XG5cdCAgICAgICAgICAgIHRoaXMuY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlcml2ZXMgYSBrZXkgZnJvbSBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBzYWx0IEEgc2FsdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIga2V5ID0ga2RmLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbXB1dGU6IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jZmc7XG5cblx0ICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXJcblx0ICAgICAgICAgICAgdmFyIGhhc2hlciA9IGNmZy5oYXNoZXIuY3JlYXRlKCk7XG5cblx0ICAgICAgICAgICAgLy8gSW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRLZXkgPSBXb3JkQXJyYXkuY3JlYXRlKCk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkZXJpdmVkS2V5V29yZHMgPSBkZXJpdmVkS2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGNmZy5rZXlTaXplO1xuXHQgICAgICAgICAgICB2YXIgaXRlcmF0aW9ucyA9IGNmZy5pdGVyYXRpb25zO1xuXG5cdCAgICAgICAgICAgIC8vIEdlbmVyYXRlIGtleVxuXHQgICAgICAgICAgICB3aGlsZSAoZGVyaXZlZEtleVdvcmRzLmxlbmd0aCA8IGtleVNpemUpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChibG9jaykge1xuXHQgICAgICAgICAgICAgICAgICAgIGhhc2hlci51cGRhdGUoYmxvY2spO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gaGFzaGVyLnVwZGF0ZShwYXNzd29yZCkuZmluYWxpemUoc2FsdCk7XG5cdCAgICAgICAgICAgICAgICBoYXNoZXIucmVzZXQoKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gSXRlcmF0aW9uc1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBpdGVyYXRpb25zOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICBibG9jayA9IGhhc2hlci5maW5hbGl6ZShibG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgaGFzaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIGRlcml2ZWRLZXkuY29uY2F0KGJsb2NrKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBkZXJpdmVkS2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGRlcml2ZWRLZXk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogRGVyaXZlcyBhIGtleSBmcm9tIGEgcGFzc3dvcmQuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LlxuXHQgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIGNvbXB1dGF0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0KTtcblx0ICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDggfSk7XG5cdCAgICAgKiAgICAgdmFyIGtleSA9IENyeXB0b0pTLkV2cEtERihwYXNzd29yZCwgc2FsdCwgeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pO1xuXHQgICAgICovXG5cdCAgICBDLkV2cEtERiA9IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCwgY2ZnKSB7XG5cdCAgICAgICAgcmV0dXJuIEV2cEtERi5jcmVhdGUoY2ZnKS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTtcblx0ICAgIH07XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuRXZwS0RGO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgQ19lbmMgPSBDLmVuYztcblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmODtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8qKlxuXHQgICAgICogSE1BQyBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBITUFDID0gQ19hbGdvLkhNQUMgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIEhNQUMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBobWFjSGFzaGVyID0gQ3J5cHRvSlMuYWxnby5ITUFDLmNyZWF0ZShDcnlwdG9KUy5hbGdvLlNIQTI1Niwga2V5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoaGFzaGVyLCBrZXkpIHtcblx0ICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXJcblx0ICAgICAgICAgICAgaGFzaGVyID0gdGhpcy5faGFzaGVyID0gbmV3IGhhc2hlci5pbml0KCk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGtleSA9PSAnc3RyaW5nJykge1xuXHQgICAgICAgICAgICAgICAga2V5ID0gVXRmOC5wYXJzZShrZXkpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBoYXNoZXJCbG9ja1NpemUgPSBoYXNoZXIuYmxvY2tTaXplO1xuXHQgICAgICAgICAgICB2YXIgaGFzaGVyQmxvY2tTaXplQnl0ZXMgPSBoYXNoZXJCbG9ja1NpemUgKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEFsbG93IGFyYml0cmFyeSBsZW5ndGgga2V5c1xuXHQgICAgICAgICAgICBpZiAoa2V5LnNpZ0J5dGVzID4gaGFzaGVyQmxvY2tTaXplQnl0ZXMpIHtcblx0ICAgICAgICAgICAgICAgIGtleSA9IGhhc2hlci5maW5hbGl6ZShrZXkpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQ2xhbXAgZXhjZXNzIGJpdHNcblx0ICAgICAgICAgICAga2V5LmNsYW1wKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2xvbmUga2V5IGZvciBpbm5lciBhbmQgb3V0ZXIgcGFkc1xuXHQgICAgICAgICAgICB2YXIgb0tleSA9IHRoaXMuX29LZXkgPSBrZXkuY2xvbmUoKTtcblx0ICAgICAgICAgICAgdmFyIGlLZXkgPSB0aGlzLl9pS2V5ID0ga2V5LmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBvS2V5V29yZHMgPSBvS2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgaUtleVdvcmRzID0gaUtleS53b3JkcztcblxuXHQgICAgICAgICAgICAvLyBYT1Iga2V5cyB3aXRoIHBhZCBjb25zdGFudHNcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoZXJCbG9ja1NpemU7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgb0tleVdvcmRzW2ldIF49IDB4NWM1YzVjNWM7XG5cdCAgICAgICAgICAgICAgICBpS2V5V29yZHNbaV0gXj0gMHgzNjM2MzYzNjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBvS2V5LnNpZ0J5dGVzID0gaUtleS5zaWdCeXRlcyA9IGhhc2hlckJsb2NrU2l6ZUJ5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFJlc2V0cyB0aGlzIEhNQUMgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgaGFzaGVyID0gdGhpcy5faGFzaGVyO1xuXG5cdCAgICAgICAgICAgIC8vIFJlc2V0XG5cdCAgICAgICAgICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAgICBoYXNoZXIudXBkYXRlKHRoaXMuX2lLZXkpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBVcGRhdGVzIHRoaXMgSE1BQyB3aXRoIGEgbWVzc2FnZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSBUaGUgbWVzc2FnZSB0byBhcHBlbmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtITUFDfSBUaGlzIEhNQUMgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKCdtZXNzYWdlJyk7XG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoZXIudXBkYXRlKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRmluYWxpemVzIHRoZSBITUFDIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqIE5vdGUgdGhhdCB0aGUgZmluYWxpemUgb3BlcmF0aW9uIGlzIGVmZmVjdGl2ZWx5IGEgZGVzdHJ1Y3RpdmUsIHJlYWQtb25jZSBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgKE9wdGlvbmFsKSBBIGZpbmFsIG1lc3NhZ2UgdXBkYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBobWFjSGFzaGVyLmZpbmFsaXplKCk7XG5cdCAgICAgICAgICogICAgIHZhciBobWFjID0gaG1hY0hhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaG1hYyA9IGhtYWNIYXNoZXIuZmluYWxpemUod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmaW5hbGl6ZTogZnVuY3Rpb24gKG1lc3NhZ2VVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhhc2hlciA9IHRoaXMuX2hhc2hlcjtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIEhNQUNcblx0ICAgICAgICAgICAgdmFyIGlubmVySGFzaCA9IGhhc2hlci5maW5hbGl6ZShtZXNzYWdlVXBkYXRlKTtcblx0ICAgICAgICAgICAgaGFzaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICAgIHZhciBobWFjID0gaGFzaGVyLmZpbmFsaXplKHRoaXMuX29LZXkuY2xvbmUoKS5jb25jYXQoaW5uZXJIYXNoKSk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhtYWM7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdH0oKSk7XG5cblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uIChNYXRoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyO1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblxuXHQgICAgLy8gQ29uc3RhbnRzIHRhYmxlXG5cdCAgICB2YXIgVCA9IFtdO1xuXG5cdCAgICAvLyBDb21wdXRlIGNvbnN0YW50c1xuXHQgICAgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDY0OyBpKyspIHtcblx0ICAgICAgICAgICAgVFtpXSA9IChNYXRoLmFicyhNYXRoLnNpbihpICsgMSkpICogMHgxMDAwMDAwMDApIHwgMDtcblx0ICAgICAgICB9XG5cdCAgICB9KCkpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIE1ENSBoYXNoIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIE1ENSA9IENfYWxnby5NRDUgPSBIYXNoZXIuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoID0gbmV3IFdvcmRBcnJheS5pbml0KFtcblx0ICAgICAgICAgICAgICAgIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksXG5cdCAgICAgICAgICAgICAgICAweDk4YmFkY2ZlLCAweDEwMzI1NDc2XG5cdCAgICAgICAgICAgIF0pO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgICAgIHZhciBvZmZzZXRfaSA9IG9mZnNldCArIGk7XG5cdCAgICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfaSA9IE1bb2Zmc2V0X2ldO1xuXG5cdCAgICAgICAgICAgICAgICBNW29mZnNldF9pXSA9IChcblx0ICAgICAgICAgICAgICAgICAgICAoKChNX29mZnNldF9pIDw8IDgpICB8IChNX29mZnNldF9pID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICgoKE1fb2Zmc2V0X2kgPDwgMjQpIHwgKE1fb2Zmc2V0X2kgPj4+IDgpKSAgJiAweGZmMDBmZjAwKVxuXHQgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgSCA9IHRoaXMuX2hhc2gud29yZHM7XG5cblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzAgID0gTVtvZmZzZXQgKyAwXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEgID0gTVtvZmZzZXQgKyAxXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzIgID0gTVtvZmZzZXQgKyAyXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzMgID0gTVtvZmZzZXQgKyAzXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzQgID0gTVtvZmZzZXQgKyA0XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzUgID0gTVtvZmZzZXQgKyA1XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzYgID0gTVtvZmZzZXQgKyA2XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzcgID0gTVtvZmZzZXQgKyA3XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzggID0gTVtvZmZzZXQgKyA4XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzkgID0gTVtvZmZzZXQgKyA5XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEwID0gTVtvZmZzZXQgKyAxMF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xMSA9IE1bb2Zmc2V0ICsgMTFdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTIgPSBNW29mZnNldCArIDEyXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEzID0gTVtvZmZzZXQgKyAxM107XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xNCA9IE1bb2Zmc2V0ICsgMTRdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTUgPSBNW29mZnNldCArIDE1XTtcblxuXHQgICAgICAgICAgICAvLyBXb3JraW5nIHZhcmlhbGJlc1xuXHQgICAgICAgICAgICB2YXIgYSA9IEhbMF07XG5cdCAgICAgICAgICAgIHZhciBiID0gSFsxXTtcblx0ICAgICAgICAgICAgdmFyIGMgPSBIWzJdO1xuXHQgICAgICAgICAgICB2YXIgZCA9IEhbM107XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0YXRpb25cblx0ICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzAsICA3LCAgVFswXSk7XG5cdCAgICAgICAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBNX29mZnNldF8xLCAgMTIsIFRbMV0pO1xuXHQgICAgICAgICAgICBjID0gRkYoYywgZCwgYSwgYiwgTV9vZmZzZXRfMiwgIDE3LCBUWzJdKTtcblx0ICAgICAgICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzMsICAyMiwgVFszXSk7XG5cdCAgICAgICAgICAgIGEgPSBGRihhLCBiLCBjLCBkLCBNX29mZnNldF80LCAgNywgIFRbNF0pO1xuXHQgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfNSwgIDEyLCBUWzVdKTtcblx0ICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzYsICAxNywgVFs2XSk7XG5cdCAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF83LCAgMjIsIFRbN10pO1xuXHQgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfOCwgIDcsICBUWzhdKTtcblx0ICAgICAgICAgICAgZCA9IEZGKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzksICAxMiwgVFs5XSk7XG5cdCAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF8xMCwgMTcsIFRbMTBdKTtcblx0ICAgICAgICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzExLCAyMiwgVFsxMV0pO1xuXHQgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTIsIDcsICBUWzEyXSk7XG5cdCAgICAgICAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBNX29mZnNldF8xMywgMTIsIFRbMTNdKTtcblx0ICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE0LCAxNywgVFsxNF0pO1xuXHQgICAgICAgICAgICBiID0gRkYoYiwgYywgZCwgYSwgTV9vZmZzZXRfMTUsIDIyLCBUWzE1XSk7XG5cblx0ICAgICAgICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEsICA1LCAgVFsxNl0pO1xuXHQgICAgICAgICAgICBkID0gR0coZCwgYSwgYiwgYywgTV9vZmZzZXRfNiwgIDksICBUWzE3XSk7XG5cdCAgICAgICAgICAgIGMgPSBHRyhjLCBkLCBhLCBiLCBNX29mZnNldF8xMSwgMTQsIFRbMThdKTtcblx0ICAgICAgICAgICAgYiA9IEdHKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzAsICAyMCwgVFsxOV0pO1xuXHQgICAgICAgICAgICBhID0gR0coYSwgYiwgYywgZCwgTV9vZmZzZXRfNSwgIDUsICBUWzIwXSk7XG5cdCAgICAgICAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBNX29mZnNldF8xMCwgOSwgIFRbMjFdKTtcblx0ICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE1LCAxNCwgVFsyMl0pO1xuXHQgICAgICAgICAgICBiID0gR0coYiwgYywgZCwgYSwgTV9vZmZzZXRfNCwgIDIwLCBUWzIzXSk7XG5cdCAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF85LCAgNSwgIFRbMjRdKTtcblx0ICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzE0LCA5LCAgVFsyNV0pO1xuXHQgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfMywgIDE0LCBUWzI2XSk7XG5cdCAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF84LCAgMjAsIFRbMjddKTtcblx0ICAgICAgICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEzLCA1LCAgVFsyOF0pO1xuXHQgICAgICAgICAgICBkID0gR0coZCwgYSwgYiwgYywgTV9vZmZzZXRfMiwgIDksICBUWzI5XSk7XG5cdCAgICAgICAgICAgIGMgPSBHRyhjLCBkLCBhLCBiLCBNX29mZnNldF83LCAgMTQsIFRbMzBdKTtcblx0ICAgICAgICAgICAgYiA9IEdHKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEyLCAyMCwgVFszMV0pO1xuXG5cdCAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF81LCAgNCwgIFRbMzJdKTtcblx0ICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzgsICAxMSwgVFszM10pO1xuXHQgICAgICAgICAgICBjID0gSEgoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTEsIDE2LCBUWzM0XSk7XG5cdCAgICAgICAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBNX29mZnNldF8xNCwgMjMsIFRbMzVdKTtcblx0ICAgICAgICAgICAgYSA9IEhIKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEsICA0LCAgVFszNl0pO1xuXHQgICAgICAgICAgICBkID0gSEgoZCwgYSwgYiwgYywgTV9vZmZzZXRfNCwgIDExLCBUWzM3XSk7XG5cdCAgICAgICAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBNX29mZnNldF83LCAgMTYsIFRbMzhdKTtcblx0ICAgICAgICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEwLCAyMywgVFszOV0pO1xuXHQgICAgICAgICAgICBhID0gSEgoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTMsIDQsICBUWzQwXSk7XG5cdCAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF8wLCAgMTEsIFRbNDFdKTtcblx0ICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzMsICAxNiwgVFs0Ml0pO1xuXHQgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfNiwgIDIzLCBUWzQzXSk7XG5cdCAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF85LCAgNCwgIFRbNDRdKTtcblx0ICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzEyLCAxMSwgVFs0NV0pO1xuXHQgICAgICAgICAgICBjID0gSEgoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTUsIDE2LCBUWzQ2XSk7XG5cdCAgICAgICAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBNX29mZnNldF8yLCAgMjMsIFRbNDddKTtcblxuXHQgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfMCwgIDYsICBUWzQ4XSk7XG5cdCAgICAgICAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBNX29mZnNldF83LCAgMTAsIFRbNDldKTtcblx0ICAgICAgICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE0LCAxNSwgVFs1MF0pO1xuXHQgICAgICAgICAgICBiID0gSUkoYiwgYywgZCwgYSwgTV9vZmZzZXRfNSwgIDIxLCBUWzUxXSk7XG5cdCAgICAgICAgICAgIGEgPSBJSShhLCBiLCBjLCBkLCBNX29mZnNldF8xMiwgNiwgIFRbNTJdKTtcblx0ICAgICAgICAgICAgZCA9IElJKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzMsICAxMCwgVFs1M10pO1xuXHQgICAgICAgICAgICBjID0gSUkoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTAsIDE1LCBUWzU0XSk7XG5cdCAgICAgICAgICAgIGIgPSBJSShiLCBjLCBkLCBhLCBNX29mZnNldF8xLCAgMjEsIFRbNTVdKTtcblx0ICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzgsICA2LCAgVFs1Nl0pO1xuXHQgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTUsIDEwLCBUWzU3XSk7XG5cdCAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF82LCAgMTUsIFRbNThdKTtcblx0ICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEzLCAyMSwgVFs1OV0pO1xuXHQgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfNCwgIDYsICBUWzYwXSk7XG5cdCAgICAgICAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBNX29mZnNldF8xMSwgMTAsIFRbNjFdKTtcblx0ICAgICAgICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzIsICAxNSwgVFs2Ml0pO1xuXHQgICAgICAgICAgICBiID0gSUkoYiwgYywgZCwgYSwgTV9vZmZzZXRfOSwgIDIxLCBUWzYzXSk7XG5cblx0ICAgICAgICAgICAgLy8gSW50ZXJtZWRpYXRlIGhhc2ggdmFsdWVcblx0ICAgICAgICAgICAgSFswXSA9IChIWzBdICsgYSkgfCAwO1xuXHQgICAgICAgICAgICBIWzFdID0gKEhbMV0gKyBiKSB8IDA7XG5cdCAgICAgICAgICAgIEhbMl0gPSAoSFsyXSArIGMpIHwgMDtcblx0ICAgICAgICAgICAgSFszXSA9IChIWzNdICsgZCkgfCAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkcztcblxuXHQgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4O1xuXHQgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBuQml0c0xlZnQgJSAzMik7XG5cblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWxIID0gTWF0aC5mbG9vcihuQml0c1RvdGFsIC8gMHgxMDAwMDAwMDApO1xuXHQgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbEwgPSBuQml0c1RvdGFsO1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE1XSA9IChcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxIIDw8IDgpICB8IChuQml0c1RvdGFsSCA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxIIDw8IDI0KSB8IChuQml0c1RvdGFsSCA+Pj4gOCkpICAmIDB4ZmYwMGZmMDApXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyA2NCkgPj4+IDkpIDw8IDQpICsgMTRdID0gKFxuXHQgICAgICAgICAgICAgICAgKCgobkJpdHNUb3RhbEwgPDwgOCkgIHwgKG5CaXRzVG90YWxMID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgKCgobkJpdHNUb3RhbEwgPDwgMjQpIHwgKG5CaXRzVG90YWxMID4+PiA4KSkgICYgMHhmZjAwZmYwMClcblx0ICAgICAgICAgICAgKTtcblxuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzID0gKGRhdGFXb3Jkcy5sZW5ndGggKyAxKSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gSGFzaCBmaW5hbCBibG9ja3Ncblx0ICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgaGFzaCA9IHRoaXMuX2hhc2g7XG5cdCAgICAgICAgICAgIHZhciBIID0gaGFzaC53b3JkcztcblxuXHQgICAgICAgICAgICAvLyBTd2FwIGVuZGlhblxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgICAgIHZhciBIX2kgPSBIW2ldO1xuXG5cdCAgICAgICAgICAgICAgICBIW2ldID0gKCgoSF9pIDw8IDgpICB8IChIX2kgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG5cdCAgICAgICAgICAgICAgICAgICAgICAgKCgoSF9pIDw8IDI0KSB8IChIX2kgPj4+IDgpKSAgJiAweGZmMDBmZjAwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFJldHVybiBmaW5hbCBjb21wdXRlZCBoYXNoXG5cdCAgICAgICAgICAgIHJldHVybiBoYXNoO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2hhc2ggPSB0aGlzLl9oYXNoLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICBmdW5jdGlvbiBGRihhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5cdCAgICAgICAgdmFyIG4gPSBhICsgKChiICYgYykgfCAofmIgJiBkKSkgKyB4ICsgdDtcblx0ICAgICAgICByZXR1cm4gKChuIDw8IHMpIHwgKG4gPj4+ICgzMiAtIHMpKSkgKyBiO1xuXHQgICAgfVxuXG5cdCAgICBmdW5jdGlvbiBHRyhhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5cdCAgICAgICAgdmFyIG4gPSBhICsgKChiICYgZCkgfCAoYyAmIH5kKSkgKyB4ICsgdDtcblx0ICAgICAgICByZXR1cm4gKChuIDw8IHMpIHwgKG4gPj4+ICgzMiAtIHMpKSkgKyBiO1xuXHQgICAgfVxuXG5cdCAgICBmdW5jdGlvbiBISChhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5cdCAgICAgICAgdmFyIG4gPSBhICsgKGIgXiBjIF4gZCkgKyB4ICsgdDtcblx0ICAgICAgICByZXR1cm4gKChuIDw8IHMpIHwgKG4gPj4+ICgzMiAtIHMpKSkgKyBiO1xuXHQgICAgfVxuXG5cdCAgICBmdW5jdGlvbiBJSShhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5cdCAgICAgICAgdmFyIG4gPSBhICsgKGMgXiAoYiB8IH5kKSkgKyB4ICsgdDtcblx0ICAgICAgICByZXR1cm4gKChuIDw8IHMpIHwgKG4gPj4+ICgzMiAtIHMpKSkgKyBiO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuTUQ1KCdtZXNzYWdlJyk7XG5cdCAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5NRDUod29yZEFycmF5KTtcblx0ICAgICAqL1xuXHQgICAgQy5NRDUgPSBIYXNoZXIuX2NyZWF0ZUhlbHBlcihNRDUpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBobWFjID0gQ3J5cHRvSlMuSG1hY01ENShtZXNzYWdlLCBrZXkpO1xuXHQgICAgICovXG5cdCAgICBDLkhtYWNNRDUgPSBIYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoTUQ1KTtcblx0fShNYXRoKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuTUQ1O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlcjtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8vIFJldXNhYmxlIG9iamVjdFxuXHQgICAgdmFyIFcgPSBbXTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTSEEtMSBoYXNoIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIFNIQTEgPSBDX2FsZ28uU0hBMSA9IEhhc2hlci5leHRlbmQoe1xuXHQgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2hhc2ggPSBuZXcgV29yZEFycmF5LmluaXQoW1xuXHQgICAgICAgICAgICAgICAgMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSxcblx0ICAgICAgICAgICAgICAgIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsXG5cdCAgICAgICAgICAgICAgICAweGMzZDJlMWYwXG5cdCAgICAgICAgICAgIF0pO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIEggPSB0aGlzLl9oYXNoLndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzXG5cdCAgICAgICAgICAgIHZhciBhID0gSFswXTtcblx0ICAgICAgICAgICAgdmFyIGIgPSBIWzFdO1xuXHQgICAgICAgICAgICB2YXIgYyA9IEhbMl07XG5cdCAgICAgICAgICAgIHZhciBkID0gSFszXTtcblx0ICAgICAgICAgICAgdmFyIGUgPSBIWzRdO1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGF0aW9uXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODA7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgaWYgKGkgPCAxNikge1xuXHQgICAgICAgICAgICAgICAgICAgIFdbaV0gPSBNW29mZnNldCArIGldIHwgMDtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIG4gPSBXW2kgLSAzXSBeIFdbaSAtIDhdIF4gV1tpIC0gMTRdIF4gV1tpIC0gMTZdO1xuXHQgICAgICAgICAgICAgICAgICAgIFdbaV0gPSAobiA8PCAxKSB8IChuID4+PiAzMSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIHZhciB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBlICsgV1tpXTtcblx0ICAgICAgICAgICAgICAgIGlmIChpIDwgMjApIHtcblx0ICAgICAgICAgICAgICAgICAgICB0ICs9ICgoYiAmIGMpIHwgKH5iICYgZCkpICsgMHg1YTgyNzk5OTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDQwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdCArPSAoYiBeIGMgXiBkKSArIDB4NmVkOWViYTE7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGkgPCA2MCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHQgKz0gKChiICYgYykgfCAoYiAmIGQpIHwgKGMgJiBkKSkgLSAweDcwZTQ0MzI0O1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIC8qIGlmIChpIDwgODApICovIHtcblx0ICAgICAgICAgICAgICAgICAgICB0ICs9IChiIF4gYyBeIGQpIC0gMHgzNTlkM2UyYTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgZSA9IGQ7XG5cdCAgICAgICAgICAgICAgICBkID0gYztcblx0ICAgICAgICAgICAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7XG5cdCAgICAgICAgICAgICAgICBiID0gYTtcblx0ICAgICAgICAgICAgICAgIGEgPSB0O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gSW50ZXJtZWRpYXRlIGhhc2ggdmFsdWVcblx0ICAgICAgICAgICAgSFswXSA9IChIWzBdICsgYSkgfCAwO1xuXHQgICAgICAgICAgICBIWzFdID0gKEhbMV0gKyBiKSB8IDA7XG5cdCAgICAgICAgICAgIEhbMl0gPSAoSFsyXSArIGMpIHwgMDtcblx0ICAgICAgICAgICAgSFszXSA9IChIWzNdICsgZCkgfCAwO1xuXHQgICAgICAgICAgICBIWzRdID0gKEhbNF0gKyBlKSB8IDA7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb0ZpbmFsaXplOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7XG5cdCAgICAgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzO1xuXG5cdCAgICAgICAgICAgIHZhciBuQml0c1RvdGFsID0gdGhpcy5fbkRhdGFCeXRlcyAqIDg7XG5cdCAgICAgICAgICAgIHZhciBuQml0c0xlZnQgPSBkYXRhLnNpZ0J5dGVzICogODtcblxuXHQgICAgICAgICAgICAvLyBBZGQgcGFkZGluZ1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDgwIDw8ICgyNCAtIG5CaXRzTGVmdCAlIDMyKTtcblx0ICAgICAgICAgICAgZGF0YVdvcmRzWygoKG5CaXRzTGVmdCArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNF0gPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyA2NCkgPj4+IDkpIDw8IDQpICsgMTVdID0gbkJpdHNUb3RhbDtcblx0ICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGRhdGFXb3Jkcy5sZW5ndGggKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEhhc2ggZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTtcblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaFxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5faGFzaDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gSGFzaGVyLmNsb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBjbG9uZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTEoJ21lc3NhZ2UnKTtcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTEod29yZEFycmF5KTtcblx0ICAgICAqL1xuXHQgICAgQy5TSEExID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoU0hBMSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy5cblx0ICAgICAqXG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBMShtZXNzYWdlLCBrZXkpO1xuXHQgICAgICovXG5cdCAgICBDLkhtYWNTSEExID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKFNIQTEpO1xuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLlNIQTE7XG5cbn0pKTsiLCJ2YXIgcFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIG9iamVjdEtleXMgPSByZXF1aXJlKCcuL2xpYi9rZXlzLmpzJyk7XG52YXIgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2xpYi9pc19hcmd1bWVudHMuanMnKTtcblxudmFyIGRlZXBFcXVhbCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQsIG9wdHMpIHtcbiAgaWYgKCFvcHRzKSBvcHRzID0ge307XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuXG4gIH0gZWxzZSBpZiAoYWN0dWFsIGluc3RhbmNlb2YgRGF0ZSAmJiBleHBlY3RlZCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gYWN0dWFsLmdldFRpbWUoKSA9PT0gZXhwZWN0ZWQuZ2V0VGltZSgpO1xuXG4gIC8vIDcuMy4gT3RoZXIgcGFpcnMgdGhhdCBkbyBub3QgYm90aCBwYXNzIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JyxcbiAgLy8gZXF1aXZhbGVuY2UgaXMgZGV0ZXJtaW5lZCBieSA9PS5cbiAgfSBlbHNlIGlmICghYWN0dWFsIHx8ICFleHBlY3RlZCB8fCB0eXBlb2YgYWN0dWFsICE9ICdvYmplY3QnICYmIHR5cGVvZiBleHBlY3RlZCAhPSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBvcHRzLnN0cmljdCA/IGFjdHVhbCA9PT0gZXhwZWN0ZWQgOiBhY3R1YWwgPT0gZXhwZWN0ZWQ7XG5cbiAgLy8gNy40LiBGb3IgYWxsIG90aGVyIE9iamVjdCBwYWlycywgaW5jbHVkaW5nIEFycmF5IG9iamVjdHMsIGVxdWl2YWxlbmNlIGlzXG4gIC8vIGRldGVybWluZWQgYnkgaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChhcyB2ZXJpZmllZFxuICAvLyB3aXRoIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCksIHRoZSBzYW1lIHNldCBvZiBrZXlzXG4gIC8vIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLCBlcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnlcbiAgLy8gY29ycmVzcG9uZGluZyBrZXksIGFuZCBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuIE5vdGU6IHRoaXNcbiAgLy8gYWNjb3VudHMgZm9yIGJvdGggbmFtZWQgYW5kIGluZGV4ZWQgcHJvcGVydGllcyBvbiBBcnJheXMuXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQsIG9wdHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkT3JOdWxsKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBpc0J1ZmZlciAoeCkge1xuICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnIHx8IHR5cGVvZiB4Lmxlbmd0aCAhPT0gJ251bWJlcicpIHJldHVybiBmYWxzZTtcbiAgaWYgKHR5cGVvZiB4LmNvcHkgIT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHguc2xpY2UgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHgubGVuZ3RoID4gMCAmJiB0eXBlb2YgeFswXSAhPT0gJ251bWJlcicpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIsIG9wdHMpIHtcbiAgdmFyIGksIGtleTtcbiAgaWYgKGlzVW5kZWZpbmVkT3JOdWxsKGEpIHx8IGlzVW5kZWZpbmVkT3JOdWxsKGIpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy8gYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LlxuICBpZiAoYS5wcm90b3R5cGUgIT09IGIucHJvdG90eXBlKSByZXR1cm4gZmFsc2U7XG4gIC8vfn5+SSd2ZSBtYW5hZ2VkIHRvIGJyZWFrIE9iamVjdC5rZXlzIHRocm91Z2ggc2NyZXd5IGFyZ3VtZW50cyBwYXNzaW5nLlxuICAvLyAgIENvbnZlcnRpbmcgdG8gYXJyYXkgc29sdmVzIHRoZSBwcm9ibGVtLlxuICBpZiAoaXNBcmd1bWVudHMoYSkpIHtcbiAgICBpZiAoIWlzQXJndW1lbnRzKGIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGEgPSBwU2xpY2UuY2FsbChhKTtcbiAgICBiID0gcFNsaWNlLmNhbGwoYik7XG4gICAgcmV0dXJuIGRlZXBFcXVhbChhLCBiLCBvcHRzKTtcbiAgfVxuICBpZiAoaXNCdWZmZXIoYSkpIHtcbiAgICBpZiAoIWlzQnVmZmVyKGIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFbaV0gIT09IGJbaV0pIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdHJ5IHtcbiAgICB2YXIga2EgPSBvYmplY3RLZXlzKGEpLFxuICAgICAgICBrYiA9IG9iamVjdEtleXMoYik7XG4gIH0gY2F0Y2ggKGUpIHsvL2hhcHBlbnMgd2hlbiBvbmUgaXMgYSBzdHJpbmcgbGl0ZXJhbCBhbmQgdGhlIG90aGVyIGlzbid0XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT0ga2JbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9lcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnkgY29ycmVzcG9uZGluZyBrZXksIGFuZFxuICAvL35+fnBvc3NpYmx5IGV4cGVuc2l2ZSBkZWVwIHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBrZXkgPSBrYVtpXTtcbiAgICBpZiAoIWRlZXBFcXVhbChhW2tleV0sIGJba2V5XSwgb3B0cykpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHlwZW9mIGEgPT09IHR5cGVvZiBiO1xufVxuIiwidmFyIHN1cHBvcnRzQXJndW1lbnRzQ2xhc3MgPSAoZnVuY3Rpb24oKXtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmd1bWVudHMpXG59KSgpID09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xuXG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBzdXBwb3J0c0FyZ3VtZW50c0NsYXNzID8gc3VwcG9ydGVkIDogdW5zdXBwb3J0ZWQ7XG5cbmV4cG9ydHMuc3VwcG9ydGVkID0gc3VwcG9ydGVkO1xuZnVuY3Rpb24gc3VwcG9ydGVkKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59O1xuXG5leHBvcnRzLnVuc3VwcG9ydGVkID0gdW5zdXBwb3J0ZWQ7XG5mdW5jdGlvbiB1bnN1cHBvcnRlZChvYmplY3Qpe1xuICByZXR1cm4gb2JqZWN0ICYmXG4gICAgdHlwZW9mIG9iamVjdCA9PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBvYmplY3QubGVuZ3RoID09ICdudW1iZXInICYmXG4gICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ2NhbGxlZScpICYmXG4gICAgIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmplY3QsICdjYWxsZWUnKSB8fFxuICAgIGZhbHNlO1xufTtcbiIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHR5cGVvZiBPYmplY3Qua2V5cyA9PT0gJ2Z1bmN0aW9uJ1xuICA/IE9iamVjdC5rZXlzIDogc2hpbTtcblxuZXhwb3J0cy5zaGltID0gc2hpbTtcbmZ1bmN0aW9uIHNoaW0gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSBrZXlzLnB1c2goa2V5KTtcbiAgcmV0dXJuIGtleXM7XG59XG4iLCJ2YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0JylcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnYmlnaScpXG5cbnZhciBQb2ludCA9IHJlcXVpcmUoJy4vcG9pbnQnKVxuXG5mdW5jdGlvbiBDdXJ2ZSAocCwgYSwgYiwgR3gsIEd5LCBuLCBoKSB7XG4gIHRoaXMucCA9IHBcbiAgdGhpcy5hID0gYVxuICB0aGlzLmIgPSBiXG4gIHRoaXMuRyA9IFBvaW50LmZyb21BZmZpbmUodGhpcywgR3gsIEd5KVxuICB0aGlzLm4gPSBuXG4gIHRoaXMuaCA9IGhcblxuICB0aGlzLmluZmluaXR5ID0gbmV3IFBvaW50KHRoaXMsIG51bGwsIG51bGwsIEJpZ0ludGVnZXIuWkVSTylcblxuICAvLyByZXN1bHQgY2FjaGluZ1xuICB0aGlzLnBPdmVyRm91ciA9IHAuYWRkKEJpZ0ludGVnZXIuT05FKS5zaGlmdFJpZ2h0KDIpXG5cbiAgLy8gZGV0ZXJtaW5lIHNpemUgb2YgcCBpbiBieXRlc1xuICB0aGlzLnBMZW5ndGggPSBNYXRoLmZsb29yKCh0aGlzLnAuYml0TGVuZ3RoKCkgKyA3KSAvIDgpXG59XG5cbkN1cnZlLnByb3RvdHlwZS5wb2ludEZyb21YID0gZnVuY3Rpb24gKGlzT2RkLCB4KSB7XG4gIHZhciBhbHBoYSA9IHgucG93KDMpLmFkZCh0aGlzLmEubXVsdGlwbHkoeCkpLmFkZCh0aGlzLmIpLm1vZCh0aGlzLnApXG4gIHZhciBiZXRhID0gYWxwaGEubW9kUG93KHRoaXMucE92ZXJGb3VyLCB0aGlzLnApIC8vIFhYWDogbm90IGNvbXBhdGlibGUgd2l0aCBhbGwgY3VydmVzXG5cbiAgdmFyIHkgPSBiZXRhXG4gIGlmIChiZXRhLmlzRXZlbigpIF4gIWlzT2RkKSB7XG4gICAgeSA9IHRoaXMucC5zdWJ0cmFjdCh5KSAvLyAteSAlIHBcbiAgfVxuXG4gIHJldHVybiBQb2ludC5mcm9tQWZmaW5lKHRoaXMsIHgsIHkpXG59XG5cbkN1cnZlLnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gKFEpIHtcbiAgaWYgKFEgPT09IHRoaXMuaW5maW5pdHkpIHJldHVybiB0cnVlXG5cbiAgcmV0dXJuIFEuei5zaWdudW0oKSA9PT0gMCAmJiBRLnkuc2lnbnVtKCkgIT09IDBcbn1cblxuQ3VydmUucHJvdG90eXBlLmlzT25DdXJ2ZSA9IGZ1bmN0aW9uIChRKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoUSkpIHJldHVybiB0cnVlXG5cbiAgdmFyIHggPSBRLmFmZmluZVhcbiAgdmFyIHkgPSBRLmFmZmluZVlcbiAgdmFyIGEgPSB0aGlzLmFcbiAgdmFyIGIgPSB0aGlzLmJcbiAgdmFyIHAgPSB0aGlzLnBcblxuICAvLyBDaGVjayB0aGF0IHhRIGFuZCB5USBhcmUgaW50ZWdlcnMgaW4gdGhlIGludGVydmFsIFswLCBwIC0gMV1cbiAgaWYgKHguc2lnbnVtKCkgPCAwIHx8IHguY29tcGFyZVRvKHApID49IDApIHJldHVybiBmYWxzZVxuICBpZiAoeS5zaWdudW0oKSA8IDAgfHwgeS5jb21wYXJlVG8ocCkgPj0gMCkgcmV0dXJuIGZhbHNlXG5cbiAgLy8gYW5kIGNoZWNrIHRoYXQgeV4yID0geF4zICsgYXggKyBiIChtb2QgcClcbiAgdmFyIGxocyA9IHkuc3F1YXJlKCkubW9kKHApXG4gIHZhciByaHMgPSB4LnBvdygzKS5hZGQoYS5tdWx0aXBseSh4KSkuYWRkKGIpLm1vZChwKVxuICByZXR1cm4gbGhzLmVxdWFscyhyaHMpXG59XG5cbi8qKlxuICogVmFsaWRhdGUgYW4gZWxsaXB0aWMgY3VydmUgcG9pbnQuXG4gKlxuICogU2VlIFNFQyAxLCBzZWN0aW9uIDMuMi4yLjE6IEVsbGlwdGljIEN1cnZlIFB1YmxpYyBLZXkgVmFsaWRhdGlvbiBQcmltaXRpdmVcbiAqL1xuQ3VydmUucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gKFEpIHtcbiAgLy8gQ2hlY2sgUSAhPSBPXG4gIGFzc2VydCghdGhpcy5pc0luZmluaXR5KFEpLCAnUG9pbnQgaXMgYXQgaW5maW5pdHknKVxuICBhc3NlcnQodGhpcy5pc09uQ3VydmUoUSksICdQb2ludCBpcyBub3Qgb24gdGhlIGN1cnZlJylcblxuICAvLyBDaGVjayBuUSA9IE8gKHdoZXJlIFEgaXMgYSBzY2FsYXIgbXVsdGlwbGUgb2YgRylcbiAgdmFyIG5RID0gUS5tdWx0aXBseSh0aGlzLm4pXG4gIGFzc2VydCh0aGlzLmlzSW5maW5pdHkoblEpLCAnUG9pbnQgaXMgbm90IGEgc2NhbGFyIG11bHRpcGxlIG9mIEcnKVxuXG4gIHJldHVybiB0cnVlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ3VydmVcbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJzZWNwMTI4cjFcIjoge1xuICAgIFwicFwiOiBcImZmZmZmZmZkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXCIsXG4gICAgXCJhXCI6IFwiZmZmZmZmZmRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmNcIixcbiAgICBcImJcIjogXCJlODc1NzljMTEwNzlmNDNkZDgyNDk5M2MyY2VlNWVkM1wiLFxuICAgIFwiblwiOiBcImZmZmZmZmZlMDAwMDAwMDA3NWEzMGQxYjkwMzhhMTE1XCIsXG4gICAgXCJoXCI6IFwiMDFcIixcbiAgICBcIkd4XCI6IFwiMTYxZmY3NTI4Yjg5OWIyZDBjMjg2MDdjYTUyYzViODZcIixcbiAgICBcIkd5XCI6IFwiY2Y1YWM4Mzk1YmFmZWIxM2MwMmRhMjkyZGRlZDdhODNcIlxuICB9LFxuICBcInNlY3AxNjBrMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmYWM3M1wiLFxuICAgIFwiYVwiOiBcIjAwXCIsXG4gICAgXCJiXCI6IFwiMDdcIixcbiAgICBcIm5cIjogXCIwMTAwMDAwMDAwMDAwMDAwMDAwMDAxYjhmYTE2ZGZhYjlhY2ExNmI2YjNcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCIzYjRjMzgyY2UzN2FhMTkyYTQwMTllNzYzMDM2ZjRmNWRkNGQ3ZWJiXCIsXG4gICAgXCJHeVwiOiBcIjkzOGNmOTM1MzE4ZmRjZWQ2YmMyODI4NjUzMTczM2MzZjAzYzRmZWVcIlxuICB9LFxuICBcInNlY3AxNjByMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY3ZmZmZmZmZlwiLFxuICAgIFwiYVwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmN2ZmZmZmZmNcIixcbiAgICBcImJcIjogXCIxYzk3YmVmYzU0YmQ3YThiNjVhY2Y4OWY4MWQ0ZDRhZGM1NjVmYTQ1XCIsXG4gICAgXCJuXCI6IFwiMDEwMDAwMDAwMDAwMDAwMDAwMDAwMWY0YzhmOTI3YWVkM2NhNzUyMjU3XCIsXG4gICAgXCJoXCI6IFwiMDFcIixcbiAgICBcIkd4XCI6IFwiNGE5NmI1Njg4ZWY1NzMyODQ2NjQ2OTg5NjhjMzhiYjkxM2NiZmM4MlwiLFxuICAgIFwiR3lcIjogXCIyM2E2Mjg1NTMxNjg5NDdkNTlkY2M5MTIwNDIzNTEzNzdhYzVmYjMyXCJcbiAgfSxcbiAgXCJzZWNwMTkyazFcIjoge1xuICAgIFwicFwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZWUzN1wiLFxuICAgIFwiYVwiOiBcIjAwXCIsXG4gICAgXCJiXCI6IFwiMDNcIixcbiAgICBcIm5cIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmUyNmYyZmMxNzBmNjk0NjZhNzRkZWZkOGRcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCJkYjRmZjEwZWMwNTdlOWFlMjZiMDdkMDI4MGI3ZjQzNDFkYTVkMWIxZWFlMDZjN2RcIixcbiAgICBcIkd5XCI6IFwiOWIyZjJmNmQ5YzU2MjhhNzg0NDE2M2QwMTViZTg2MzQ0MDgyYWE4OGQ5NWUyZjlkXCJcbiAgfSxcbiAgXCJzZWNwMTkycjFcIjoge1xuICAgIFwicFwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZmZmZmZmZmZmZmZmZmZmZlwiLFxuICAgIFwiYVwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZmZmZmZmZmZmZmZmZmZmY1wiLFxuICAgIFwiYlwiOiBcIjY0MjEwNTE5ZTU5YzgwZTcwZmE3ZTlhYjcyMjQzMDQ5ZmViOGRlZWNjMTQ2YjliMVwiLFxuICAgIFwiblwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjk5ZGVmODM2MTQ2YmM5YjFiNGQyMjgzMVwiLFxuICAgIFwiaFwiOiBcIjAxXCIsXG4gICAgXCJHeFwiOiBcIjE4OGRhODBlYjAzMDkwZjY3Y2JmMjBlYjQzYTE4ODAwZjRmZjBhZmQ4MmZmMTAxMlwiLFxuICAgIFwiR3lcIjogXCIwNzE5MmI5NWZmYzhkYTc4NjMxMDExZWQ2YjI0Y2RkNTczZjk3N2ExMWU3OTQ4MTFcIlxuICB9LFxuICBcInNlY3AyNTZrMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZmMyZlwiLFxuICAgIFwiYVwiOiBcIjAwXCIsXG4gICAgXCJiXCI6IFwiMDdcIixcbiAgICBcIm5cIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWJhYWVkY2U2YWY0OGEwM2JiZmQyNWU4Y2QwMzY0MTQxXCIsXG4gICAgXCJoXCI6IFwiMDFcIixcbiAgICBcIkd4XCI6IFwiNzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OFwiLFxuICAgIFwiR3lcIjogXCI0ODNhZGE3NzI2YTNjNDY1NWRhNGZiZmMwZTExMDhhOGZkMTdiNDQ4YTY4NTU0MTk5YzQ3ZDA4ZmZiMTBkNGI4XCJcbiAgfSxcbiAgXCJzZWNwMjU2cjFcIjoge1xuICAgIFwicFwiOiBcImZmZmZmZmZmMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZcIixcbiAgICBcImFcIjogXCJmZmZmZmZmZjAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjXCIsXG4gICAgXCJiXCI6IFwiNWFjNjM1ZDhhYTNhOTNlN2IzZWJiZDU1NzY5ODg2YmM2NTFkMDZiMGNjNTNiMGY2M2JjZTNjM2UyN2QyNjA0YlwiLFxuICAgIFwiblwiOiBcImZmZmZmZmZmMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmYmNlNmZhYWRhNzE3OWU4NGYzYjljYWMyZmM2MzI1NTFcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCI2YjE3ZDFmMmUxMmM0MjQ3ZjhiY2U2ZTU2M2E0NDBmMjc3MDM3ZDgxMmRlYjMzYTBmNGExMzk0NWQ4OThjMjk2XCIsXG4gICAgXCJHeVwiOiBcIjRmZTM0MmUyZmUxYTdmOWI4ZWU3ZWI0YTdjMGY5ZTE2MmJjZTMzNTc2YjMxNWVjZWNiYjY0MDY4MzdiZjUxZjVcIlxuICB9XG59XG4iLCJ2YXIgUG9pbnQgPSByZXF1aXJlKCcuL3BvaW50JylcbnZhciBDdXJ2ZSA9IHJlcXVpcmUoJy4vY3VydmUnKVxuXG52YXIgZ2V0Q3VydmVCeU5hbWUgPSByZXF1aXJlKCcuL25hbWVzJylcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIEN1cnZlOiBDdXJ2ZSxcbiAgUG9pbnQ6IFBvaW50LFxuICBnZXRDdXJ2ZUJ5TmFtZTogZ2V0Q3VydmVCeU5hbWVcbn1cbiIsInZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnYmlnaScpXG5cbnZhciBjdXJ2ZXMgPSByZXF1aXJlKCcuL2N1cnZlcy5qc29uJylcbnZhciBDdXJ2ZSA9IHJlcXVpcmUoJy4vY3VydmUnKVxuXG5mdW5jdGlvbiBnZXRDdXJ2ZUJ5TmFtZSAobmFtZSkge1xuICB2YXIgY3VydmUgPSBjdXJ2ZXNbbmFtZV1cbiAgaWYgKCFjdXJ2ZSkgcmV0dXJuIG51bGxcblxuICB2YXIgcCA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLnAsIDE2KVxuICB2YXIgYSA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLmEsIDE2KVxuICB2YXIgYiA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLmIsIDE2KVxuICB2YXIgbiA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLm4sIDE2KVxuICB2YXIgaCA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLmgsIDE2KVxuICB2YXIgR3ggPSBuZXcgQmlnSW50ZWdlcihjdXJ2ZS5HeCwgMTYpXG4gIHZhciBHeSA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLkd5LCAxNilcblxuICByZXR1cm4gbmV3IEN1cnZlKHAsIGEsIGIsIEd4LCBHeSwgbiwgaClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRDdXJ2ZUJ5TmFtZVxuIiwidmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnYmlnaScpXG5cbnZhciBUSFJFRSA9IEJpZ0ludGVnZXIudmFsdWVPZigzKVxuXG5mdW5jdGlvbiBQb2ludCAoY3VydmUsIHgsIHksIHopIHtcbiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKHosIHVuZGVmaW5lZCwgJ01pc3NpbmcgWiBjb29yZGluYXRlJylcblxuICB0aGlzLmN1cnZlID0gY3VydmVcbiAgdGhpcy54ID0geFxuICB0aGlzLnkgPSB5XG4gIHRoaXMueiA9IHpcbiAgdGhpcy5fekludiA9IG51bGxcblxuICB0aGlzLmNvbXByZXNzZWQgPSB0cnVlXG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShQb2ludC5wcm90b3R5cGUsICd6SW52Jywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5fekludiA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5fekludiA9IHRoaXMuei5tb2RJbnZlcnNlKHRoaXMuY3VydmUucClcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fekludlxuICB9XG59KVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoUG9pbnQucHJvdG90eXBlLCAnYWZmaW5lWCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMueC5tdWx0aXBseSh0aGlzLnpJbnYpLm1vZCh0aGlzLmN1cnZlLnApXG4gIH1cbn0pXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShQb2ludC5wcm90b3R5cGUsICdhZmZpbmVZJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy55Lm11bHRpcGx5KHRoaXMuekludikubW9kKHRoaXMuY3VydmUucClcbiAgfVxufSlcblxuUG9pbnQuZnJvbUFmZmluZSA9IGZ1bmN0aW9uIChjdXJ2ZSwgeCwgeSkge1xuICByZXR1cm4gbmV3IFBvaW50KGN1cnZlLCB4LCB5LCBCaWdJbnRlZ2VyLk9ORSlcbn1cblxuUG9pbnQucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAob3RoZXIgPT09IHRoaXMpIHJldHVybiB0cnVlXG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcykpIHJldHVybiB0aGlzLmN1cnZlLmlzSW5maW5pdHkob3RoZXIpXG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkob3RoZXIpKSByZXR1cm4gdGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpXG5cbiAgLy8gdSA9IFkyICogWjEgLSBZMSAqIFoyXG4gIHZhciB1ID0gb3RoZXIueS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueS5tdWx0aXBseShvdGhlci56KSkubW9kKHRoaXMuY3VydmUucClcblxuICBpZiAodS5zaWdudW0oKSAhPT0gMCkgcmV0dXJuIGZhbHNlXG5cbiAgLy8gdiA9IFgyICogWjEgLSBYMSAqIFoyXG4gIHZhciB2ID0gb3RoZXIueC5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueC5tdWx0aXBseShvdGhlci56KSkubW9kKHRoaXMuY3VydmUucClcblxuICByZXR1cm4gdi5zaWdudW0oKSA9PT0gMFxufVxuXG5Qb2ludC5wcm90b3R5cGUubmVnYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgeSA9IHRoaXMuY3VydmUucC5zdWJ0cmFjdCh0aGlzLnkpXG5cbiAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLmN1cnZlLCB0aGlzLngsIHksIHRoaXMueilcbn1cblxuUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChiKSB7XG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcykpIHJldHVybiBiXG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkoYikpIHJldHVybiB0aGlzXG5cbiAgdmFyIHgxID0gdGhpcy54XG4gIHZhciB5MSA9IHRoaXMueVxuICB2YXIgeDIgPSBiLnhcbiAgdmFyIHkyID0gYi55XG5cbiAgLy8gdSA9IFkyICogWjEgLSBZMSAqIFoyXG4gIHZhciB1ID0geTIubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh5MS5tdWx0aXBseShiLnopKS5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB2ID0gWDIgKiBaMSAtIFgxICogWjJcbiAgdmFyIHYgPSB4Mi5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHgxLm11bHRpcGx5KGIueikpLm1vZCh0aGlzLmN1cnZlLnApXG5cbiAgaWYgKHYuc2lnbnVtKCkgPT09IDApIHtcbiAgICBpZiAodS5zaWdudW0oKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMudHdpY2UoKSAvLyB0aGlzID09IGIsIHNvIGRvdWJsZVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmN1cnZlLmluZmluaXR5IC8vIHRoaXMgPSAtYiwgc28gaW5maW5pdHlcbiAgfVxuXG4gIHZhciB2MiA9IHYuc3F1YXJlKClcbiAgdmFyIHYzID0gdjIubXVsdGlwbHkodilcbiAgdmFyIHgxdjIgPSB4MS5tdWx0aXBseSh2MilcbiAgdmFyIHp1MiA9IHUuc3F1YXJlKCkubXVsdGlwbHkodGhpcy56KVxuXG4gIC8vIHgzID0gdiAqICh6MiAqICh6MSAqIHVeMiAtIDIgKiB4MSAqIHZeMikgLSB2XjMpXG4gIHZhciB4MyA9IHp1Mi5zdWJ0cmFjdCh4MXYyLnNoaWZ0TGVmdCgxKSkubXVsdGlwbHkoYi56KS5zdWJ0cmFjdCh2MykubXVsdGlwbHkodikubW9kKHRoaXMuY3VydmUucClcbiAgLy8geTMgPSB6MiAqICgzICogeDEgKiB1ICogdl4yIC0geTEgKiB2XjMgLSB6MSAqIHVeMykgKyB1ICogdl4zXG4gIHZhciB5MyA9IHgxdjIubXVsdGlwbHkoVEhSRUUpLm11bHRpcGx5KHUpLnN1YnRyYWN0KHkxLm11bHRpcGx5KHYzKSkuc3VidHJhY3QoenUyLm11bHRpcGx5KHUpKS5tdWx0aXBseShiLnopLmFkZCh1Lm11bHRpcGx5KHYzKSkubW9kKHRoaXMuY3VydmUucClcbiAgLy8gejMgPSB2XjMgKiB6MSAqIHoyXG4gIHZhciB6MyA9IHYzLm11bHRpcGx5KHRoaXMueikubXVsdGlwbHkoYi56KS5tb2QodGhpcy5jdXJ2ZS5wKVxuXG4gIHJldHVybiBuZXcgUG9pbnQodGhpcy5jdXJ2ZSwgeDMsIHkzLCB6Mylcbn1cblxuUG9pbnQucHJvdG90eXBlLnR3aWNlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpKSByZXR1cm4gdGhpc1xuICBpZiAodGhpcy55LnNpZ251bSgpID09PSAwKSByZXR1cm4gdGhpcy5jdXJ2ZS5pbmZpbml0eVxuXG4gIHZhciB4MSA9IHRoaXMueFxuICB2YXIgeTEgPSB0aGlzLnlcblxuICB2YXIgeTF6MSA9IHkxLm11bHRpcGx5KHRoaXMueikubW9kKHRoaXMuY3VydmUucClcbiAgdmFyIHkxc3F6MSA9IHkxejEubXVsdGlwbHkoeTEpLm1vZCh0aGlzLmN1cnZlLnApXG4gIHZhciBhID0gdGhpcy5jdXJ2ZS5hXG5cbiAgLy8gdyA9IDMgKiB4MV4yICsgYSAqIHoxXjJcbiAgdmFyIHcgPSB4MS5zcXVhcmUoKS5tdWx0aXBseShUSFJFRSlcblxuICBpZiAoYS5zaWdudW0oKSAhPT0gMCkge1xuICAgIHcgPSB3LmFkZCh0aGlzLnouc3F1YXJlKCkubXVsdGlwbHkoYSkpXG4gIH1cblxuICB3ID0gdy5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB4MyA9IDIgKiB5MSAqIHoxICogKHdeMiAtIDggKiB4MSAqIHkxXjIgKiB6MSlcbiAgdmFyIHgzID0gdy5zcXVhcmUoKS5zdWJ0cmFjdCh4MS5zaGlmdExlZnQoMykubXVsdGlwbHkoeTFzcXoxKSkuc2hpZnRMZWZ0KDEpLm11bHRpcGx5KHkxejEpLm1vZCh0aGlzLmN1cnZlLnApXG4gIC8vIHkzID0gNCAqIHkxXjIgKiB6MSAqICgzICogdyAqIHgxIC0gMiAqIHkxXjIgKiB6MSkgLSB3XjNcbiAgdmFyIHkzID0gdy5tdWx0aXBseShUSFJFRSkubXVsdGlwbHkoeDEpLnN1YnRyYWN0KHkxc3F6MS5zaGlmdExlZnQoMSkpLnNoaWZ0TGVmdCgyKS5tdWx0aXBseSh5MXNxejEpLnN1YnRyYWN0KHcucG93KDMpKS5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB6MyA9IDggKiAoeTEgKiB6MSleM1xuICB2YXIgejMgPSB5MXoxLnBvdygzKS5zaGlmdExlZnQoMykubW9kKHRoaXMuY3VydmUucClcblxuICByZXR1cm4gbmV3IFBvaW50KHRoaXMuY3VydmUsIHgzLCB5MywgejMpXG59XG5cbi8vIFNpbXBsZSBOQUYgKE5vbi1BZGphY2VudCBGb3JtKSBtdWx0aXBsaWNhdGlvbiBhbGdvcml0aG1cbi8vIFRPRE86IG1vZHVsYXJpemUgdGhlIG11bHRpcGxpY2F0aW9uIGFsZ29yaXRobVxuUG9pbnQucHJvdG90eXBlLm11bHRpcGx5ID0gZnVuY3Rpb24gKGspIHtcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eSh0aGlzKSkgcmV0dXJuIHRoaXNcbiAgaWYgKGsuc2lnbnVtKCkgPT09IDApIHJldHVybiB0aGlzLmN1cnZlLmluZmluaXR5XG5cbiAgdmFyIGUgPSBrXG4gIHZhciBoID0gZS5tdWx0aXBseShUSFJFRSlcblxuICB2YXIgbmVnID0gdGhpcy5uZWdhdGUoKVxuICB2YXIgUiA9IHRoaXNcblxuICBmb3IgKHZhciBpID0gaC5iaXRMZW5ndGgoKSAtIDI7IGkgPiAwOyAtLWkpIHtcbiAgICB2YXIgaEJpdCA9IGgudGVzdEJpdChpKVxuICAgIHZhciBlQml0ID0gZS50ZXN0Qml0KGkpXG5cbiAgICBSID0gUi50d2ljZSgpXG5cbiAgICBpZiAoaEJpdCAhPT0gZUJpdCkge1xuICAgICAgUiA9IFIuYWRkKGhCaXQgPyB0aGlzIDogbmVnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBSXG59XG5cbi8vIENvbXB1dGUgdGhpcypqICsgeCprIChzaW11bHRhbmVvdXMgbXVsdGlwbGljYXRpb24pXG5Qb2ludC5wcm90b3R5cGUubXVsdGlwbHlUd28gPSBmdW5jdGlvbiAoaiwgeCwgaykge1xuICB2YXIgaSA9IE1hdGgubWF4KGouYml0TGVuZ3RoKCksIGsuYml0TGVuZ3RoKCkpIC0gMVxuICB2YXIgUiA9IHRoaXMuY3VydmUuaW5maW5pdHlcbiAgdmFyIGJvdGggPSB0aGlzLmFkZCh4KVxuXG4gIHdoaWxlIChpID49IDApIHtcbiAgICB2YXIgakJpdCA9IGoudGVzdEJpdChpKVxuICAgIHZhciBrQml0ID0gay50ZXN0Qml0KGkpXG5cbiAgICBSID0gUi50d2ljZSgpXG5cbiAgICBpZiAoakJpdCkge1xuICAgICAgaWYgKGtCaXQpIHtcbiAgICAgICAgUiA9IFIuYWRkKGJvdGgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBSID0gUi5hZGQodGhpcylcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGtCaXQpIHtcbiAgICAgIFIgPSBSLmFkZCh4KVxuICAgIH1cbiAgICAtLWlcbiAgfVxuXG4gIHJldHVybiBSXG59XG5cblBvaW50LnByb3RvdHlwZS5nZXRFbmNvZGVkID0gZnVuY3Rpb24gKGNvbXByZXNzZWQpIHtcbiAgaWYgKGNvbXByZXNzZWQgPT0gbnVsbCkgY29tcHJlc3NlZCA9IHRoaXMuY29tcHJlc3NlZFxuICBpZiAodGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpKSByZXR1cm4gQnVmZmVyLmFsbG9jKDEsIDApIC8vIEluZmluaXR5IHBvaW50IGVuY29kZWQgaXMgc2ltcGx5ICcwMCdcblxuICB2YXIgeCA9IHRoaXMuYWZmaW5lWFxuICB2YXIgeSA9IHRoaXMuYWZmaW5lWVxuICB2YXIgYnl0ZUxlbmd0aCA9IHRoaXMuY3VydmUucExlbmd0aFxuICB2YXIgYnVmZmVyXG5cbiAgLy8gMHgwMi8weDAzIHwgWFxuICBpZiAoY29tcHJlc3NlZCkge1xuICAgIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgxICsgYnl0ZUxlbmd0aClcbiAgICBidWZmZXIud3JpdGVVSW50OCh5LmlzRXZlbigpID8gMHgwMiA6IDB4MDMsIDApXG5cbiAgLy8gMHgwNCB8IFggfCBZXG4gIH0gZWxzZSB7XG4gICAgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKDEgKyBieXRlTGVuZ3RoICsgYnl0ZUxlbmd0aClcbiAgICBidWZmZXIud3JpdGVVSW50OCgweDA0LCAwKVxuXG4gICAgeS50b0J1ZmZlcihieXRlTGVuZ3RoKS5jb3B5KGJ1ZmZlciwgMSArIGJ5dGVMZW5ndGgpXG4gIH1cblxuICB4LnRvQnVmZmVyKGJ5dGVMZW5ndGgpLmNvcHkoYnVmZmVyLCAxKVxuXG4gIHJldHVybiBidWZmZXJcbn1cblxuUG9pbnQuZGVjb2RlRnJvbSA9IGZ1bmN0aW9uIChjdXJ2ZSwgYnVmZmVyKSB7XG4gIHZhciB0eXBlID0gYnVmZmVyLnJlYWRVSW50OCgwKVxuICB2YXIgY29tcHJlc3NlZCA9ICh0eXBlICE9PSA0KVxuXG4gIHZhciBieXRlTGVuZ3RoID0gTWF0aC5mbG9vcigoY3VydmUucC5iaXRMZW5ndGgoKSArIDcpIC8gOClcbiAgdmFyIHggPSBCaWdJbnRlZ2VyLmZyb21CdWZmZXIoYnVmZmVyLnNsaWNlKDEsIDEgKyBieXRlTGVuZ3RoKSlcblxuICB2YXIgUVxuICBpZiAoY29tcHJlc3NlZCkge1xuICAgIGFzc2VydC5lcXVhbChidWZmZXIubGVuZ3RoLCBieXRlTGVuZ3RoICsgMSwgJ0ludmFsaWQgc2VxdWVuY2UgbGVuZ3RoJylcbiAgICBhc3NlcnQodHlwZSA9PT0gMHgwMiB8fCB0eXBlID09PSAweDAzLCAnSW52YWxpZCBzZXF1ZW5jZSB0YWcnKVxuXG4gICAgdmFyIGlzT2RkID0gKHR5cGUgPT09IDB4MDMpXG4gICAgUSA9IGN1cnZlLnBvaW50RnJvbVgoaXNPZGQsIHgpXG4gIH0gZWxzZSB7XG4gICAgYXNzZXJ0LmVxdWFsKGJ1ZmZlci5sZW5ndGgsIDEgKyBieXRlTGVuZ3RoICsgYnl0ZUxlbmd0aCwgJ0ludmFsaWQgc2VxdWVuY2UgbGVuZ3RoJylcblxuICAgIHZhciB5ID0gQmlnSW50ZWdlci5mcm9tQnVmZmVyKGJ1ZmZlci5zbGljZSgxICsgYnl0ZUxlbmd0aCkpXG4gICAgUSA9IFBvaW50LmZyb21BZmZpbmUoY3VydmUsIHgsIHkpXG4gIH1cblxuICBRLmNvbXByZXNzZWQgPSBjb21wcmVzc2VkXG4gIHJldHVybiBRXG59XG5cblBvaW50LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eSh0aGlzKSkgcmV0dXJuICcoSU5GSU5JVFkpJ1xuXG4gIHJldHVybiAnKCcgKyB0aGlzLmFmZmluZVgudG9TdHJpbmcoKSArICcsJyArIHRoaXMuYWZmaW5lWS50b1N0cmluZygpICsgJyknXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUG9pbnRcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2V2ZW50cyB8fCB7fTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxuRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24obikge1xuICBpZiAoIWlzTnVtYmVyKG4pIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IFR5cGVFcnJvcignbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50cy5lcnJvciB8fFxuICAgICAgICAoaXNPYmplY3QodGhpcy5fZXZlbnRzLmVycm9yKSAmJiAhdGhpcy5fZXZlbnRzLmVycm9yLmxlbmd0aCkpIHtcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuY2F1Z2h0LCB1bnNwZWNpZmllZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICBpZiAoaXNVbmRlZmluZWQoaGFuZGxlcikpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc09iamVjdChoYW5kbGVyKSkge1xuICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gIGlmICh0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSAmJiAhdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuICAgIGlmICghaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgaWYgKHR5cGVvZiBjb25zb2xlLnRyYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIG5vdCBzdXBwb3J0ZWQgaW4gSUUgMTBcbiAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICB2YXIgZmlyZWQgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG5cbiAgICBpZiAoIWZpcmVkKSB7XG4gICAgICBmaXJlZCA9IHRydWU7XG4gICAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgbGlzdCA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gIHBvc2l0aW9uID0gLTE7XG5cbiAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8XG4gICAgICAoaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAoaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGxpc3RlbmVycykpIHtcbiAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gIH0gZWxzZSBpZiAobGlzdGVuZXJzKSB7XG4gICAgLy8gTElGTyBvcmRlclxuICAgIHdoaWxlIChsaXN0ZW5lcnMubGVuZ3RoKVxuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbbGlzdGVuZXJzLmxlbmd0aCAtIDFdKTtcbiAgfVxuICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghdGhpcy5fZXZlbnRzIHx8ICF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gW107XG4gIGVsc2UgaWYgKGlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24odHlwZSkge1xuICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgICBpZiAoaXNGdW5jdGlvbihldmxpc3RlbmVyKSlcbiAgICAgIHJldHVybiAxO1xuICAgIGVsc2UgaWYgKGV2bGlzdGVuZXIpXG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gIH1cbiAgcmV0dXJuIDA7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKTtcbn07XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbiIsIid1c2Ugc3RyaWN0J1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnc3RyZWFtJykuVHJhbnNmb3JtXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG5cbmZ1bmN0aW9uIHRocm93SWZOb3RTdHJpbmdPckJ1ZmZlciAodmFsLCBwcmVmaXgpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodmFsKSAmJiB0eXBlb2YgdmFsICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocHJlZml4ICsgJyBtdXN0IGJlIGEgc3RyaW5nIG9yIGEgYnVmZmVyJylcbiAgfVxufVxuXG5mdW5jdGlvbiBIYXNoQmFzZSAoYmxvY2tTaXplKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG5cbiAgdGhpcy5fYmxvY2sgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tTaXplKVxuICB0aGlzLl9ibG9ja1NpemUgPSBibG9ja1NpemVcbiAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIHRoaXMuX2xlbmd0aCA9IFswLCAwLCAwLCAwXVxuXG4gIHRoaXMuX2ZpbmFsaXplZCA9IGZhbHNlXG59XG5cbmluaGVyaXRzKEhhc2hCYXNlLCBUcmFuc2Zvcm0pXG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2FsbGJhY2spIHtcbiAgdmFyIGVycm9yID0gbnVsbFxuICB0cnkge1xuICAgIHRoaXMudXBkYXRlKGNodW5rLCBlbmNvZGluZylcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXJyb3IgPSBlcnJcbiAgfVxuXG4gIGNhbGxiYWNrKGVycm9yKVxufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIHZhciBlcnJvciA9IG51bGxcbiAgdHJ5IHtcbiAgICB0aGlzLnB1c2godGhpcy5kaWdlc3QoKSlcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXJyb3IgPSBlcnJcbiAgfVxuXG4gIGNhbGxiYWNrKGVycm9yKVxufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGVuY29kaW5nKSB7XG4gIHRocm93SWZOb3RTdHJpbmdPckJ1ZmZlcihkYXRhLCAnRGF0YScpXG4gIGlmICh0aGlzLl9maW5hbGl6ZWQpIHRocm93IG5ldyBFcnJvcignRGlnZXN0IGFscmVhZHkgY2FsbGVkJylcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoZGF0YSkpIGRhdGEgPSBCdWZmZXIuZnJvbShkYXRhLCBlbmNvZGluZylcblxuICAvLyBjb25zdW1lIGRhdGFcbiAgdmFyIGJsb2NrID0gdGhpcy5fYmxvY2tcbiAgdmFyIG9mZnNldCA9IDBcbiAgd2hpbGUgKHRoaXMuX2Jsb2NrT2Zmc2V0ICsgZGF0YS5sZW5ndGggLSBvZmZzZXQgPj0gdGhpcy5fYmxvY2tTaXplKSB7XG4gICAgZm9yICh2YXIgaSA9IHRoaXMuX2Jsb2NrT2Zmc2V0OyBpIDwgdGhpcy5fYmxvY2tTaXplOykgYmxvY2tbaSsrXSA9IGRhdGFbb2Zmc2V0KytdXG4gICAgdGhpcy5fdXBkYXRlKClcbiAgICB0aGlzLl9ibG9ja09mZnNldCA9IDBcbiAgfVxuICB3aGlsZSAob2Zmc2V0IDwgZGF0YS5sZW5ndGgpIGJsb2NrW3RoaXMuX2Jsb2NrT2Zmc2V0KytdID0gZGF0YVtvZmZzZXQrK11cblxuICAvLyB1cGRhdGUgbGVuZ3RoXG4gIGZvciAodmFyIGogPSAwLCBjYXJyeSA9IGRhdGEubGVuZ3RoICogODsgY2FycnkgPiAwOyArK2opIHtcbiAgICB0aGlzLl9sZW5ndGhbal0gKz0gY2FycnlcbiAgICBjYXJyeSA9ICh0aGlzLl9sZW5ndGhbal0gLyAweDAxMDAwMDAwMDApIHwgMFxuICAgIGlmIChjYXJyeSA+IDApIHRoaXMuX2xlbmd0aFtqXSAtPSAweDAxMDAwMDAwMDAgKiBjYXJyeVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignX3VwZGF0ZSBpcyBub3QgaW1wbGVtZW50ZWQnKVxufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuZGlnZXN0ID0gZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIGlmICh0aGlzLl9maW5hbGl6ZWQpIHRocm93IG5ldyBFcnJvcignRGlnZXN0IGFscmVhZHkgY2FsbGVkJylcbiAgdGhpcy5fZmluYWxpemVkID0gdHJ1ZVxuXG4gIHZhciBkaWdlc3QgPSB0aGlzLl9kaWdlc3QoKVxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkgZGlnZXN0ID0gZGlnZXN0LnRvU3RyaW5nKGVuY29kaW5nKVxuXG4gIC8vIHJlc2V0IHN0YXRlXG4gIHRoaXMuX2Jsb2NrLmZpbGwoMClcbiAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgKytpKSB0aGlzLl9sZW5ndGhbaV0gPSAwXG5cbiAgcmV0dXJuIGRpZ2VzdFxufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfZGlnZXN0IGlzIG5vdCBpbXBsZW1lbnRlZCcpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gSGFzaEJhc2VcbiIsImV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBuQml0cyA9IC03XG4gIHZhciBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDBcbiAgdmFyIGQgPSBpc0xFID8gLTEgOiAxXG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldXG5cbiAgaSArPSBkXG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgcyA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gZUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gKGUgKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gKG0gKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApXG4gIHZhciBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSlcbiAgdmFyIGQgPSBpc0xFID8gMSA6IC0xXG4gIHZhciBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwXG5cbiAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSlcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMFxuICAgIGUgPSBlTWF4XG4gIH0gZWxzZSB7XG4gICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpXG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tXG4gICAgICBjICo9IDJcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGNcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpXG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrXG4gICAgICBjIC89IDJcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwXG4gICAgICBlID0gZU1heFxuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAoKHZhbHVlICogYykgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsImlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgfVxufVxuIiwiLyohXG4gKiBEZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGlzIGEgQnVmZmVyXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGh0dHBzOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuXG4vLyBUaGUgX2lzQnVmZmVyIGNoZWNrIGlzIGZvciBTYWZhcmkgNS03IHN1cHBvcnQsIGJlY2F1c2UgaXQncyBtaXNzaW5nXG4vLyBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yLiBSZW1vdmUgdGhpcyBldmVudHVhbGx5XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgcmV0dXJuIG9iaiAhPSBudWxsICYmIChpc0J1ZmZlcihvYmopIHx8IGlzU2xvd0J1ZmZlcihvYmopIHx8ICEhb2JqLl9pc0J1ZmZlcilcbn1cblxuZnVuY3Rpb24gaXNCdWZmZXIgKG9iaikge1xuICByZXR1cm4gISFvYmouY29uc3RydWN0b3IgJiYgdHlwZW9mIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIob2JqKVxufVxuXG4vLyBGb3IgTm9kZSB2MC4xMCBzdXBwb3J0LiBSZW1vdmUgdGhpcyBldmVudHVhbGx5LlxuZnVuY3Rpb24gaXNTbG93QnVmZmVyIChvYmopIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmoucmVhZEZsb2F0TEUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIG9iai5zbGljZSA9PT0gJ2Z1bmN0aW9uJyAmJiBpc0J1ZmZlcihvYmouc2xpY2UoMCwgMCkpXG59XG4iLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIi8qXHJcbiBDb3B5cmlnaHQgMjAxMyBEYW5pZWwgV2lydHogPGRjb2RlQGRjb2RlLmlvPlxyXG4gQ29weXJpZ2h0IDIwMDkgVGhlIENsb3N1cmUgTGlicmFyeSBBdXRob3JzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxyXG5cclxuIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XHJcbiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXHJcbiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuXHJcbiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuXHJcbiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXHJcbiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTLUlTXCIgQkFTSVMsXHJcbiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cclxuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcclxuIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBAbGljZW5zZSBsb25nLmpzIChjKSAyMDEzIERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjBcclxuICogc2VlOiBodHRwczovL2dpdGh1Yi5jb20vZGNvZGVJTy9sb25nLmpzIGZvciBkZXRhaWxzXHJcbiAqL1xyXG4oZnVuY3Rpb24oZ2xvYmFsLCBmYWN0b3J5KSB7XHJcblxyXG4gICAgLyogQU1EICovIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZVtcImFtZFwiXSlcclxuICAgICAgICBkZWZpbmUoW10sIGZhY3RvcnkpO1xyXG4gICAgLyogQ29tbW9uSlMgKi8gZWxzZSBpZiAodHlwZW9mIHJlcXVpcmUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiBtb2R1bGUgJiYgbW9kdWxlW1wiZXhwb3J0c1wiXSlcclxuICAgICAgICBtb2R1bGVbXCJleHBvcnRzXCJdID0gZmFjdG9yeSgpO1xyXG4gICAgLyogR2xvYmFsICovIGVsc2VcclxuICAgICAgICAoZ2xvYmFsW1wiZGNvZGVJT1wiXSA9IGdsb2JhbFtcImRjb2RlSU9cIl0gfHwge30pW1wiTG9uZ1wiXSA9IGZhY3RvcnkoKTtcclxuXHJcbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xyXG4gICAgXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIGEgNjQgYml0IHR3bydzLWNvbXBsZW1lbnQgaW50ZWdlciwgZ2l2ZW4gaXRzIGxvdyBhbmQgaGlnaCAzMiBiaXQgdmFsdWVzIGFzICpzaWduZWQqIGludGVnZXJzLlxyXG4gICAgICogIFNlZSB0aGUgZnJvbSogZnVuY3Rpb25zIGJlbG93IGZvciBtb3JlIGNvbnZlbmllbnQgd2F5cyBvZiBjb25zdHJ1Y3RpbmcgTG9uZ3MuXHJcbiAgICAgKiBAZXhwb3J0cyBMb25nXHJcbiAgICAgKiBAY2xhc3MgQSBMb25nIGNsYXNzIGZvciByZXByZXNlbnRpbmcgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyIHZhbHVlLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxvdyBUaGUgbG93IChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoIFRoZSBoaWdoIChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBgZmFsc2VgIGZvciBzaWduZWRcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBMb25nKGxvdywgaGlnaCwgdW5zaWduZWQpIHtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5sb3cgPSBsb3cgfCAwO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgaGlnaCAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5oaWdoID0gaGlnaCB8IDA7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LlxyXG4gICAgICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMudW5zaWduZWQgPSAhIXVuc2lnbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBhIGxvbmcgaXMgdGhlIHR3byBnaXZlbiBzaWduZWQsIDMyLWJpdCB2YWx1ZXMuXHJcbiAgICAvLyBXZSB1c2UgMzItYml0IHBpZWNlcyBiZWNhdXNlIHRoZXNlIGFyZSB0aGUgc2l6ZSBvZiBpbnRlZ2VycyBvbiB3aGljaFxyXG4gICAgLy8gSmF2YXNjcmlwdCBwZXJmb3JtcyBiaXQtb3BlcmF0aW9ucy4gIEZvciBvcGVyYXRpb25zIGxpa2UgYWRkaXRpb24gYW5kXHJcbiAgICAvLyBtdWx0aXBsaWNhdGlvbiwgd2Ugc3BsaXQgZWFjaCBudW1iZXIgaW50byAxNiBiaXQgcGllY2VzLCB3aGljaCBjYW4gZWFzaWx5IGJlXHJcbiAgICAvLyBtdWx0aXBsaWVkIHdpdGhpbiBKYXZhc2NyaXB0J3MgZmxvYXRpbmctcG9pbnQgcmVwcmVzZW50YXRpb24gd2l0aG91dCBvdmVyZmxvd1xyXG4gICAgLy8gb3IgY2hhbmdlIGluIHNpZ24uXHJcbiAgICAvL1xyXG4gICAgLy8gSW4gdGhlIGFsZ29yaXRobXMgYmVsb3csIHdlIGZyZXF1ZW50bHkgcmVkdWNlIHRoZSBuZWdhdGl2ZSBjYXNlIHRvIHRoZVxyXG4gICAgLy8gcG9zaXRpdmUgY2FzZSBieSBuZWdhdGluZyB0aGUgaW5wdXQocykgYW5kIHRoZW4gcG9zdC1wcm9jZXNzaW5nIHRoZSByZXN1bHQuXHJcbiAgICAvLyBOb3RlIHRoYXQgd2UgbXVzdCBBTFdBWVMgY2hlY2sgc3BlY2lhbGx5IHdoZXRoZXIgdGhvc2UgdmFsdWVzIGFyZSBNSU5fVkFMVUVcclxuICAgIC8vICgtMl42MykgYmVjYXVzZSAtTUlOX1ZBTFVFID09IE1JTl9WQUxVRSAoc2luY2UgMl42MyBjYW5ub3QgYmUgcmVwcmVzZW50ZWQgYXNcclxuICAgIC8vIGEgcG9zaXRpdmUgbnVtYmVyLCBpdCBvdmVyZmxvd3MgYmFjayBpbnRvIGEgbmVnYXRpdmUpLiAgTm90IGhhbmRsaW5nIHRoaXNcclxuICAgIC8vIGNhc2Ugd291bGQgb2Z0ZW4gcmVzdWx0IGluIGluZmluaXRlIHJlY3Vyc2lvbi5cclxuICAgIC8vXHJcbiAgICAvLyBDb21tb24gY29uc3RhbnQgdmFsdWVzIFpFUk8sIE9ORSwgTkVHX09ORSwgZXRjLiBhcmUgZGVmaW5lZCBiZWxvdyB0aGUgZnJvbSpcclxuICAgIC8vIG1ldGhvZHMgb24gd2hpY2ggdGhleSBkZXBlbmQuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbiBpbmRpY2F0b3IgdXNlZCB0byByZWxpYWJseSBkZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGlzIGEgTG9uZyBvciBub3QuXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgTG9uZy5wcm90b3R5cGUuX19pc0xvbmdfXztcclxuXHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTG9uZy5wcm90b3R5cGUsIFwiX19pc0xvbmdfX1wiLCB7XHJcbiAgICAgICAgdmFsdWU6IHRydWUsXHJcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZVxyXG4gICAgfSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7Kn0gb2JqIE9iamVjdFxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gaXNMb25nKG9iaikge1xyXG4gICAgICAgIHJldHVybiAob2JqICYmIG9ialtcIl9faXNMb25nX19cIl0pID09PSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgYSBMb25nLlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyp9IG9iaiBPYmplY3RcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nLmlzTG9uZyA9IGlzTG9uZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEEgY2FjaGUgb2YgdGhlIExvbmcgcmVwcmVzZW50YXRpb25zIG9mIHNtYWxsIGludGVnZXIgdmFsdWVzLlxyXG4gICAgICogQHR5cGUgeyFPYmplY3R9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIElOVF9DQUNIRSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjYWNoZSBvZiB0aGUgTG9uZyByZXByZXNlbnRhdGlvbnMgb2Ygc21hbGwgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuXHJcbiAgICAgKiBAdHlwZSB7IU9iamVjdH1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgVUlOVF9DQUNIRSA9IHt9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGZyb21JbnQodmFsdWUsIHVuc2lnbmVkKSB7XHJcbiAgICAgICAgdmFyIG9iaiwgY2FjaGVkT2JqLCBjYWNoZTtcclxuICAgICAgICBpZiAodW5zaWduZWQpIHtcclxuICAgICAgICAgICAgdmFsdWUgPj4+PSAwO1xyXG4gICAgICAgICAgICBpZiAoY2FjaGUgPSAoMCA8PSB2YWx1ZSAmJiB2YWx1ZSA8IDI1NikpIHtcclxuICAgICAgICAgICAgICAgIGNhY2hlZE9iaiA9IFVJTlRfQ0FDSEVbdmFsdWVdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGNhY2hlZE9iailcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FjaGVkT2JqO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9iaiA9IGZyb21CaXRzKHZhbHVlLCAodmFsdWUgfCAwKSA8IDAgPyAtMSA6IDAsIHRydWUpO1xyXG4gICAgICAgICAgICBpZiAoY2FjaGUpXHJcbiAgICAgICAgICAgICAgICBVSU5UX0NBQ0hFW3ZhbHVlXSA9IG9iajtcclxuICAgICAgICAgICAgcmV0dXJuIG9iajtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB2YWx1ZSB8PSAwO1xyXG4gICAgICAgICAgICBpZiAoY2FjaGUgPSAoLTEyOCA8PSB2YWx1ZSAmJiB2YWx1ZSA8IDEyOCkpIHtcclxuICAgICAgICAgICAgICAgIGNhY2hlZE9iaiA9IElOVF9DQUNIRVt2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICBpZiAoY2FjaGVkT2JqKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZWRPYmo7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb2JqID0gZnJvbUJpdHModmFsdWUsIHZhbHVlIDwgMCA/IC0xIDogMCwgZmFsc2UpO1xyXG4gICAgICAgICAgICBpZiAoY2FjaGUpXHJcbiAgICAgICAgICAgICAgICBJTlRfQ0FDSEVbdmFsdWVdID0gb2JqO1xyXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gMzIgYml0IGludGVnZXIgdmFsdWUuXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgMzIgYml0IGludGVnZXIgaW4gcXVlc3Rpb25cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBgZmFsc2VgIGZvciBzaWduZWRcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBMb25nLmZyb21JbnQgPSBmcm9tSW50O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGZyb21OdW1iZXIodmFsdWUsIHVuc2lnbmVkKSB7XHJcbiAgICAgICAgaWYgKGlzTmFOKHZhbHVlKSB8fCAhaXNGaW5pdGUodmFsdWUpKVxyXG4gICAgICAgICAgICByZXR1cm4gdW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XHJcbiAgICAgICAgaWYgKHVuc2lnbmVkKSB7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSA8IDApXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVVpFUk87XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSA+PSBUV09fUFdSXzY0X0RCTClcclxuICAgICAgICAgICAgICAgIHJldHVybiBNQVhfVU5TSUdORURfVkFMVUU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHZhbHVlIDw9IC1UV09fUFdSXzYzX0RCTClcclxuICAgICAgICAgICAgICAgIHJldHVybiBNSU5fVkFMVUU7XHJcbiAgICAgICAgICAgIGlmICh2YWx1ZSArIDEgPj0gVFdPX1BXUl82M19EQkwpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTUFYX1ZBTFVFO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodmFsdWUgPCAwKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbU51bWJlcigtdmFsdWUsIHVuc2lnbmVkKS5uZWcoKTtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMoKHZhbHVlICUgVFdPX1BXUl8zMl9EQkwpIHwgMCwgKHZhbHVlIC8gVFdPX1BXUl8zMl9EQkwpIHwgMCwgdW5zaWduZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiB2YWx1ZSwgcHJvdmlkZWQgdGhhdCBpdCBpcyBhIGZpbml0ZSBudW1iZXIuIE90aGVyd2lzZSwgemVybyBpcyByZXR1cm5lZC5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBudW1iZXIgaW4gcXVlc3Rpb25cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBgZmFsc2VgIGZvciBzaWduZWRcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBMb25nLmZyb21OdW1iZXIgPSBmcm9tTnVtYmVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHNcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoQml0c1xyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBmcm9tQml0cyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpIHtcclxuICAgICAgICByZXR1cm4gbmV3IExvbmcobG93Qml0cywgaGlnaEJpdHMsIHVuc2lnbmVkKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgNjQgYml0IGludGVnZXIgdGhhdCBjb21lcyBieSBjb25jYXRlbmF0aW5nIHRoZSBnaXZlbiBsb3cgYW5kIGhpZ2ggYml0cy4gRWFjaCBpc1xyXG4gICAgICogIGFzc3VtZWQgdG8gdXNlIDMyIGJpdHMuXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsb3dCaXRzIFRoZSBsb3cgMzIgYml0c1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzIFRoZSBoaWdoIDMyIGJpdHNcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBgZmFsc2VgIGZvciBzaWduZWRcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBMb25nLmZyb21CaXRzID0gZnJvbUJpdHM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiYXNlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZXhwb25lbnRcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIHBvd19kYmwgPSBNYXRoLnBvdzsgLy8gVXNlZCA0IHRpbWVzICg0KjggdG8gMTUrNClcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcclxuICAgICAqIEBwYXJhbSB7KGJvb2xlYW58bnVtYmVyKT19IHVuc2lnbmVkXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IHJhZGl4XHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbVN0cmluZyhzdHIsIHVuc2lnbmVkLCByYWRpeCkge1xyXG4gICAgICAgIGlmIChzdHIubGVuZ3RoID09PSAwKVxyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcignZW1wdHkgc3RyaW5nJyk7XHJcbiAgICAgICAgaWYgKHN0ciA9PT0gXCJOYU5cIiB8fCBzdHIgPT09IFwiSW5maW5pdHlcIiB8fCBzdHIgPT09IFwiK0luZmluaXR5XCIgfHwgc3RyID09PSBcIi1JbmZpbml0eVwiKVxyXG4gICAgICAgICAgICByZXR1cm4gWkVSTztcclxuICAgICAgICBpZiAodHlwZW9mIHVuc2lnbmVkID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgICAgICAvLyBGb3IgZ29vZy5tYXRoLmxvbmcgY29tcGF0aWJpbGl0eVxyXG4gICAgICAgICAgICByYWRpeCA9IHVuc2lnbmVkLFxyXG4gICAgICAgICAgICB1bnNpZ25lZCA9IGZhbHNlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHVuc2lnbmVkID0gISEgdW5zaWduZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJhZGl4ID0gcmFkaXggfHwgMTA7XHJcbiAgICAgICAgaWYgKHJhZGl4IDwgMiB8fCAzNiA8IHJhZGl4KVxyXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKCdyYWRpeCcpO1xyXG5cclxuICAgICAgICB2YXIgcDtcclxuICAgICAgICBpZiAoKHAgPSBzdHIuaW5kZXhPZignLScpKSA+IDApXHJcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdpbnRlcmlvciBoeXBoZW4nKTtcclxuICAgICAgICBlbHNlIGlmIChwID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tU3RyaW5nKHN0ci5zdWJzdHJpbmcoMSksIHVuc2lnbmVkLCByYWRpeCkubmVnKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEbyBzZXZlcmFsICg4KSBkaWdpdHMgZWFjaCB0aW1lIHRocm91Z2ggdGhlIGxvb3AsIHNvIGFzIHRvXHJcbiAgICAgICAgLy8gbWluaW1pemUgdGhlIGNhbGxzIHRvIHRoZSB2ZXJ5IGV4cGVuc2l2ZSBlbXVsYXRlZCBkaXYuXHJcbiAgICAgICAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgOCkpO1xyXG5cclxuICAgICAgICB2YXIgcmVzdWx0ID0gWkVSTztcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkgKz0gOCkge1xyXG4gICAgICAgICAgICB2YXIgc2l6ZSA9IE1hdGgubWluKDgsIHN0ci5sZW5ndGggLSBpKSxcclxuICAgICAgICAgICAgICAgIHZhbHVlID0gcGFyc2VJbnQoc3RyLnN1YnN0cmluZyhpLCBpICsgc2l6ZSksIHJhZGl4KTtcclxuICAgICAgICAgICAgaWYgKHNpemUgPCA4KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcG93ZXIgPSBmcm9tTnVtYmVyKHBvd19kYmwocmFkaXgsIHNpemUpKTtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5tdWwocG93ZXIpLmFkZChmcm9tTnVtYmVyKHZhbHVlKSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQubXVsKHJhZGl4VG9Qb3dlcik7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXN1bHQudW5zaWduZWQgPSB1bnNpZ25lZDtcclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIHN0cmluZywgd3JpdHRlbiB1c2luZyB0aGUgc3BlY2lmaWVkIHJhZGl4LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBMb25nXHJcbiAgICAgKiBAcGFyYW0geyhib29sZWFufG51bWJlcik9fSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdCwgZGVmYXVsdHMgdG8gYGZhbHNlYCBmb3Igc2lnbmVkXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFRoZSByYWRpeCBpbiB3aGljaCB0aGUgdGV4dCBpcyB3cml0dGVuICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBMb25nLmZyb21TdHJpbmcgPSBmcm9tU3RyaW5nO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd8IXtsb3c6IG51bWJlciwgaGlnaDogbnVtYmVyLCB1bnNpZ25lZDogYm9vbGVhbn19IHZhbFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGZyb21WYWx1ZSh2YWwpIHtcclxuICAgICAgICBpZiAodmFsIC8qIGlzIGNvbXBhdGlibGUgKi8gaW5zdGFuY2VvZiBMb25nKVxyXG4gICAgICAgICAgICByZXR1cm4gdmFsO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJylcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21OdW1iZXIodmFsKTtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tU3RyaW5nKHZhbCk7XHJcbiAgICAgICAgLy8gVGhyb3dzIGZvciBub24tb2JqZWN0cywgY29udmVydHMgbm9uLWluc3RhbmNlb2YgTG9uZzpcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModmFsLmxvdywgdmFsLmhpZ2gsIHZhbC51bnNpZ25lZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyB0aGUgc3BlY2lmaWVkIHZhbHVlIHRvIGEgTG9uZy5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfCF7bG93OiBudW1iZXIsIGhpZ2g6IG51bWJlciwgdW5zaWduZWQ6IGJvb2xlYW59fSB2YWwgVmFsdWVcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5mcm9tVmFsdWUgPSBmcm9tVmFsdWU7XHJcblxyXG4gICAgLy8gTk9URTogdGhlIGNvbXBpbGVyIHNob3VsZCBpbmxpbmUgdGhlc2UgY29uc3RhbnQgdmFsdWVzIGJlbG93IGFuZCB0aGVuIHJlbW92ZSB0aGVzZSB2YXJpYWJsZXMsIHNvIHRoZXJlIHNob3VsZCBiZVxyXG4gICAgLy8gbm8gcnVudGltZSBwZW5hbHR5IGZvciB0aGVzZS5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgVFdPX1BXUl8xNl9EQkwgPSAxIDw8IDE2O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBUV09fUFdSXzI0X0RCTCA9IDEgPDwgMjQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfMzJfREJMID0gVFdPX1BXUl8xNl9EQkwgKiBUV09fUFdSXzE2X0RCTDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgVFdPX1BXUl82NF9EQkwgPSBUV09fUFdSXzMyX0RCTCAqIFRXT19QV1JfMzJfREJMO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBUV09fUFdSXzYzX0RCTCA9IFRXT19QV1JfNjRfREJMIC8gMjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBUV09fUFdSXzI0ID0gZnJvbUludChUV09fUFdSXzI0X0RCTCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFpFUk8gPSBmcm9tSW50KDApO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2lnbmVkIHplcm8uXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmcuWkVSTyA9IFpFUk87XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFVaRVJPID0gZnJvbUludCgwLCB0cnVlKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFVuc2lnbmVkIHplcm8uXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmcuVVpFUk8gPSBVWkVSTztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgT05FID0gZnJvbUludCgxKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNpZ25lZCBvbmUuXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmcuT05FID0gT05FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBVT05FID0gZnJvbUludCgxLCB0cnVlKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFVuc2lnbmVkIG9uZS5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5VT05FID0gVU9ORTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgTkVHX09ORSA9IGZyb21JbnQoLTEpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2lnbmVkIG5lZ2F0aXZlIG9uZS5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5ORUdfT05FID0gTkVHX09ORTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgTUFYX1ZBTFVFID0gZnJvbUJpdHMoMHhGRkZGRkZGRnwwLCAweDdGRkZGRkZGfDAsIGZhbHNlKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1heGltdW0gc2lnbmVkIHZhbHVlLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLk1BWF9WQUxVRSA9IE1BWF9WQUxVRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgTUFYX1VOU0lHTkVEX1ZBTFVFID0gZnJvbUJpdHMoMHhGRkZGRkZGRnwwLCAweEZGRkZGRkZGfDAsIHRydWUpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWF4aW11bSB1bnNpZ25lZCB2YWx1ZS5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5NQVhfVU5TSUdORURfVkFMVUUgPSBNQVhfVU5TSUdORURfVkFMVUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIE1JTl9WQUxVRSA9IGZyb21CaXRzKDAsIDB4ODAwMDAwMDB8MCwgZmFsc2UpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWluaW11bSBzaWduZWQgdmFsdWUuXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmcuTUlOX1ZBTFVFID0gTUlOX1ZBTFVFO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGFsaWFzIExvbmcucHJvdG90eXBlXHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIExvbmdQcm90b3R5cGUgPSBMb25nLnByb3RvdHlwZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgMzIgYml0IGludGVnZXIsIGFzc3VtaW5nIGl0IGlzIGEgMzIgYml0IGludGVnZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvSW50ID0gZnVuY3Rpb24gdG9JbnQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyB0aGlzLmxvdyA+Pj4gMCA6IHRoaXMubG93O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgdGhlIG5lYXJlc3QgZmxvYXRpbmctcG9pbnQgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB2YWx1ZSAoZG91YmxlLCA1MyBiaXQgbWFudGlzc2EpLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b051bWJlciA9IGZ1bmN0aW9uIHRvTnVtYmVyKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgICAgICByZXR1cm4gKCh0aGlzLmhpZ2ggPj4+IDApICogVFdPX1BXUl8zMl9EQkwpICsgKHRoaXMubG93ID4+PiAwKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWdoICogVFdPX1BXUl8zMl9EQkwgKyAodGhpcy5sb3cgPj4+IDApO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgc3RyaW5nIHdyaXR0ZW4gaW4gdGhlIHNwZWNpZmllZCByYWRpeC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXggUmFkaXggKDItMzYpLCBkZWZhdWx0cyB0byAxMFxyXG4gICAgICogQHJldHVybnMge3N0cmluZ31cclxuICAgICAqIEBvdmVycmlkZVxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYHJhZGl4YCBpcyBvdXQgb2YgcmFuZ2VcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKHJhZGl4KSB7XHJcbiAgICAgICAgcmFkaXggPSByYWRpeCB8fCAxMDtcclxuICAgICAgICBpZiAocmFkaXggPCAyIHx8IDM2IDwgcmFkaXgpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoJ3JhZGl4Jyk7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNaZXJvKCkpXHJcbiAgICAgICAgICAgIHJldHVybiAnMCc7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7IC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxyXG4gICAgICAgICAgICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGNoYW5nZSB0aGUgTG9uZyB2YWx1ZSBiZWZvcmUgaXQgY2FuIGJlIG5lZ2F0ZWQsIHNvIHdlIHJlbW92ZVxyXG4gICAgICAgICAgICAgICAgLy8gdGhlIGJvdHRvbS1tb3N0IGRpZ2l0IGluIHRoaXMgYmFzZSBhbmQgdGhlbiByZWN1cnNlIHRvIGRvIHRoZSByZXN0LlxyXG4gICAgICAgICAgICAgICAgdmFyIHJhZGl4TG9uZyA9IGZyb21OdW1iZXIocmFkaXgpLFxyXG4gICAgICAgICAgICAgICAgICAgIGRpdiA9IHRoaXMuZGl2KHJhZGl4TG9uZyksXHJcbiAgICAgICAgICAgICAgICAgICAgcmVtMSA9IGRpdi5tdWwocmFkaXhMb25nKS5zdWIodGhpcyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZGl2LnRvU3RyaW5nKHJhZGl4KSArIHJlbTEudG9JbnQoKS50b1N0cmluZyhyYWRpeCk7XHJcbiAgICAgICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICctJyArIHRoaXMubmVnKCkudG9TdHJpbmcocmFkaXgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRG8gc2V2ZXJhbCAoNikgZGlnaXRzIGVhY2ggdGltZSB0aHJvdWdoIHRoZSBsb29wLCBzbyBhcyB0b1xyXG4gICAgICAgIC8vIG1pbmltaXplIHRoZSBjYWxscyB0byB0aGUgdmVyeSBleHBlbnNpdmUgZW11bGF0ZWQgZGl2LlxyXG4gICAgICAgIHZhciByYWRpeFRvUG93ZXIgPSBmcm9tTnVtYmVyKHBvd19kYmwocmFkaXgsIDYpLCB0aGlzLnVuc2lnbmVkKSxcclxuICAgICAgICAgICAgcmVtID0gdGhpcztcclxuICAgICAgICB2YXIgcmVzdWx0ID0gJyc7XHJcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcclxuICAgICAgICAgICAgdmFyIHJlbURpdiA9IHJlbS5kaXYocmFkaXhUb1Bvd2VyKSxcclxuICAgICAgICAgICAgICAgIGludHZhbCA9IHJlbS5zdWIocmVtRGl2Lm11bChyYWRpeFRvUG93ZXIpKS50b0ludCgpID4+PiAwLFxyXG4gICAgICAgICAgICAgICAgZGlnaXRzID0gaW50dmFsLnRvU3RyaW5nKHJhZGl4KTtcclxuICAgICAgICAgICAgcmVtID0gcmVtRGl2O1xyXG4gICAgICAgICAgICBpZiAocmVtLmlzWmVybygpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRpZ2l0cyArIHJlc3VsdDtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoZGlnaXRzLmxlbmd0aCA8IDYpXHJcbiAgICAgICAgICAgICAgICAgICAgZGlnaXRzID0gJzAnICsgZGlnaXRzO1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gJycgKyBkaWdpdHMgKyByZXN1bHQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgaGlnaCAzMiBiaXRzIGFzIGEgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgaGlnaCBiaXRzXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ2V0SGlnaEJpdHMgPSBmdW5jdGlvbiBnZXRIaWdoQml0cygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWdoO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGhpZ2ggMzIgYml0cyBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgaGlnaCBiaXRzXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ2V0SGlnaEJpdHNVbnNpZ25lZCA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzVW5zaWduZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaGlnaCA+Pj4gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBsb3cgMzIgYml0cyBhcyBhIHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gU2lnbmVkIGxvdyBiaXRzXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ2V0TG93Qml0cyA9IGZ1bmN0aW9uIGdldExvd0JpdHMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubG93O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGxvdyAzMiBiaXRzIGFzIGFuIHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBsb3cgYml0c1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmdldExvd0JpdHNVbnNpZ25lZCA9IGZ1bmN0aW9uIGdldExvd0JpdHNVbnNpZ25lZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sb3cgPj4+IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGJpdHMgbmVlZGVkIHRvIHJlcHJlc2VudCB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhpcyBMb25nLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXROdW1CaXRzQWJzID0gZnVuY3Rpb24gZ2V0TnVtQml0c0FicygpIHtcclxuICAgICAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lcShNSU5fVkFMVUUpID8gNjQgOiB0aGlzLm5lZygpLmdldE51bUJpdHNBYnMoKTtcclxuICAgICAgICB2YXIgdmFsID0gdGhpcy5oaWdoICE9IDAgPyB0aGlzLmhpZ2ggOiB0aGlzLmxvdztcclxuICAgICAgICBmb3IgKHZhciBiaXQgPSAzMTsgYml0ID4gMDsgYml0LS0pXHJcbiAgICAgICAgICAgIGlmICgodmFsICYgKDEgPDwgYml0KSkgIT0gMClcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2ggIT0gMCA/IGJpdCArIDMzIDogYml0ICsgMTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgemVyby5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmlzWmVybyA9IGZ1bmN0aW9uIGlzWmVybygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWdoID09PSAwICYmIHRoaXMubG93ID09PSAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG5lZ2F0aXZlLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuaXNOZWdhdGl2ZSA9IGZ1bmN0aW9uIGlzTmVnYXRpdmUoKSB7XHJcbiAgICAgICAgcmV0dXJuICF0aGlzLnVuc2lnbmVkICYmIHRoaXMuaGlnaCA8IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgcG9zaXRpdmUuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5pc1Bvc2l0aXZlID0gZnVuY3Rpb24gaXNQb3NpdGl2ZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy51bnNpZ25lZCB8fCB0aGlzLmhpZ2ggPj0gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBvZGQuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5pc09kZCA9IGZ1bmN0aW9uIGlzT2RkKCkge1xyXG4gICAgICAgIHJldHVybiAodGhpcy5sb3cgJiAxKSA9PT0gMTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBldmVuLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuaXNFdmVuID0gZnVuY3Rpb24gaXNFdmVuKCkge1xyXG4gICAgICAgIHJldHVybiAodGhpcy5sb3cgJiAxKSA9PT0gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICAgICAgaWYgKHRoaXMudW5zaWduZWQgIT09IG90aGVyLnVuc2lnbmVkICYmICh0aGlzLmhpZ2ggPj4+IDMxKSA9PT0gMSAmJiAob3RoZXIuaGlnaCA+Pj4gMzEpID09PSAxKVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaGlnaCA9PT0gb3RoZXIuaGlnaCAmJiB0aGlzLmxvdyA9PT0gb3RoZXIubG93O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZXF1YWxzfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZXEgPSBMb25nUHJvdG90eXBlLmVxdWFscztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHMgPSBmdW5jdGlvbiBub3RFcXVhbHMob3RoZXIpIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMuZXEoLyogdmFsaWRhdGVzICovIG90aGVyKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI25vdEVxdWFsc30uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm5lcSA9IExvbmdQcm90b3R5cGUubm90RXF1YWxzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQncy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmxlc3NUaGFuID0gZnVuY3Rpb24gbGVzc1RoYW4ob3RoZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPCAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW59LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5sdCA9IExvbmdQcm90b3R5cGUubGVzc1RoYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsID0gZnVuY3Rpb24gbGVzc1RoYW5PckVxdWFsKG90aGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpIDw9IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbk9yRXF1YWx9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5sdGUgPSBMb25nUHJvdG90eXBlLmxlc3NUaGFuT3JFcXVhbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbiA9IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuKG90aGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID4gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2dyZWF0ZXJUaGFufS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ3QgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbCA9IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuT3JFcXVhbChvdGhlcikge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA+PSAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW5PckVxdWFsfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ3RlID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb21wYXJlcyB0aGlzIExvbmcncyB2YWx1ZSB3aXRoIHRoZSBzcGVjaWZpZWQncy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcclxuICAgICAqICBpZiB0aGUgZ2l2ZW4gb25lIGlzIGdyZWF0ZXJcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZShvdGhlcikge1xyXG4gICAgICAgIGlmICghaXNMb25nKG90aGVyKSlcclxuICAgICAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgICAgIGlmICh0aGlzLmVxKG90aGVyKSlcclxuICAgICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgdmFyIHRoaXNOZWcgPSB0aGlzLmlzTmVnYXRpdmUoKSxcclxuICAgICAgICAgICAgb3RoZXJOZWcgPSBvdGhlci5pc05lZ2F0aXZlKCk7XHJcbiAgICAgICAgaWYgKHRoaXNOZWcgJiYgIW90aGVyTmVnKVxyXG4gICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgaWYgKCF0aGlzTmVnICYmIG90aGVyTmVnKVxyXG4gICAgICAgICAgICByZXR1cm4gMTtcclxuICAgICAgICAvLyBBdCB0aGlzIHBvaW50IHRoZSBzaWduIGJpdHMgYXJlIHRoZSBzYW1lXHJcbiAgICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdWIob3RoZXIpLmlzTmVnYXRpdmUoKSA/IC0xIDogMTtcclxuICAgICAgICAvLyBCb3RoIGFyZSBwb3NpdGl2ZSBpZiBhdCBsZWFzdCBvbmUgaXMgdW5zaWduZWRcclxuICAgICAgICByZXR1cm4gKG90aGVyLmhpZ2ggPj4+IDApID4gKHRoaXMuaGlnaCA+Pj4gMCkgfHwgKG90aGVyLmhpZ2ggPT09IHRoaXMuaGlnaCAmJiAob3RoZXIubG93ID4+PiAwKSA+ICh0aGlzLmxvdyA+Pj4gMCkpID8gLTEgOiAxO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbXBhcmVzIHRoaXMgTG9uZydzIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2NvbXBhcmV9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSAwIGlmIHRoZXkgYXJlIHRoZSBzYW1lLCAxIGlmIHRoZSB0aGlzIGlzIGdyZWF0ZXIgYW5kIC0xXHJcbiAgICAgKiAgaWYgdGhlIGdpdmVuIG9uZSBpcyBncmVhdGVyXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuY29tcCA9IExvbmdQcm90b3R5cGUuY29tcGFyZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE5lZ2F0ZXMgdGhpcyBMb25nJ3MgdmFsdWUuXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IE5lZ2F0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm5lZ2F0ZSA9IGZ1bmN0aW9uIG5lZ2F0ZSgpIHtcclxuICAgICAgICBpZiAoIXRoaXMudW5zaWduZWQgJiYgdGhpcy5lcShNSU5fVkFMVUUpKVxyXG4gICAgICAgICAgICByZXR1cm4gTUlOX1ZBTFVFO1xyXG4gICAgICAgIHJldHVybiB0aGlzLm5vdCgpLmFkZChPTkUpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE5lZ2F0ZXMgdGhpcyBMb25nJ3MgdmFsdWUuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbmVnYXRlfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBOZWdhdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5uZWcgPSBMb25nUHJvdG90eXBlLm5lZ2F0ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIHN1bSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGFkZGVuZCBBZGRlbmRcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU3VtXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkKGFkZGVuZCkge1xyXG4gICAgICAgIGlmICghaXNMb25nKGFkZGVuZCkpXHJcbiAgICAgICAgICAgIGFkZGVuZCA9IGZyb21WYWx1ZShhZGRlbmQpO1xyXG5cclxuICAgICAgICAvLyBEaXZpZGUgZWFjaCBudW1iZXIgaW50byA0IGNodW5rcyBvZiAxNiBiaXRzLCBhbmQgdGhlbiBzdW0gdGhlIGNodW5rcy5cclxuXHJcbiAgICAgICAgdmFyIGE0OCA9IHRoaXMuaGlnaCA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGEzMiA9IHRoaXMuaGlnaCAmIDB4RkZGRjtcclxuICAgICAgICB2YXIgYTE2ID0gdGhpcy5sb3cgPj4+IDE2O1xyXG4gICAgICAgIHZhciBhMDAgPSB0aGlzLmxvdyAmIDB4RkZGRjtcclxuXHJcbiAgICAgICAgdmFyIGI0OCA9IGFkZGVuZC5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYjMyID0gYWRkZW5kLmhpZ2ggJiAweEZGRkY7XHJcbiAgICAgICAgdmFyIGIxNiA9IGFkZGVuZC5sb3cgPj4+IDE2O1xyXG4gICAgICAgIHZhciBiMDAgPSBhZGRlbmQubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYzQ4ID0gMCwgYzMyID0gMCwgYzE2ID0gMCwgYzAwID0gMDtcclxuICAgICAgICBjMDAgKz0gYTAwICsgYjAwO1xyXG4gICAgICAgIGMxNiArPSBjMDAgPj4+IDE2O1xyXG4gICAgICAgIGMwMCAmPSAweEZGRkY7XHJcbiAgICAgICAgYzE2ICs9IGExNiArIGIxNjtcclxuICAgICAgICBjMzIgKz0gYzE2ID4+PiAxNjtcclxuICAgICAgICBjMTYgJj0gMHhGRkZGO1xyXG4gICAgICAgIGMzMiArPSBhMzIgKyBiMzI7XHJcbiAgICAgICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICAgICAgYzMyICY9IDB4RkZGRjtcclxuICAgICAgICBjNDggKz0gYTQ4ICsgYjQ4O1xyXG4gICAgICAgIGM0OCAmPSAweEZGRkY7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKChjMTYgPDwgMTYpIHwgYzAwLCAoYzQ4IDw8IDE2KSB8IGMzMiwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc3VidHJhY3QgPSBmdW5jdGlvbiBzdWJ0cmFjdChzdWJ0cmFoZW5kKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcoc3VidHJhaGVuZCkpXHJcbiAgICAgICAgICAgIHN1YnRyYWhlbmQgPSBmcm9tVmFsdWUoc3VidHJhaGVuZCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkKHN1YnRyYWhlbmQubmVnKCkpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2Ugb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3N1YnRyYWN0fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBzdWJ0cmFoZW5kIFN1YnRyYWhlbmRcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gRGlmZmVyZW5jZVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnN1YiA9IExvbmdQcm90b3R5cGUuc3VidHJhY3Q7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBwcm9kdWN0IG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gbXVsdGlwbGllciBNdWx0aXBsaWVyXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFByb2R1Y3RcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5tdWx0aXBseSA9IGZ1bmN0aW9uIG11bHRpcGx5KG11bHRpcGxpZXIpIHtcclxuICAgICAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuIFpFUk87XHJcbiAgICAgICAgaWYgKCFpc0xvbmcobXVsdGlwbGllcikpXHJcbiAgICAgICAgICAgIG11bHRpcGxpZXIgPSBmcm9tVmFsdWUobXVsdGlwbGllcik7XHJcbiAgICAgICAgaWYgKG11bHRpcGxpZXIuaXNaZXJvKCkpXHJcbiAgICAgICAgICAgIHJldHVybiBaRVJPO1xyXG4gICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgIHJldHVybiBtdWx0aXBsaWVyLmlzT2RkKCkgPyBNSU5fVkFMVUUgOiBaRVJPO1xyXG4gICAgICAgIGlmIChtdWx0aXBsaWVyLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzT2RkKCkgPyBNSU5fVkFMVUUgOiBaRVJPO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHtcclxuICAgICAgICAgICAgaWYgKG11bHRpcGxpZXIuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkubXVsKG11bHRpcGxpZXIubmVnKCkpO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5tdWwobXVsdGlwbGllcikubmVnKCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubXVsKG11bHRpcGxpZXIubmVnKCkpLm5lZygpO1xyXG5cclxuICAgICAgICAvLyBJZiBib3RoIGxvbmdzIGFyZSBzbWFsbCwgdXNlIGZsb2F0IG11bHRpcGxpY2F0aW9uXHJcbiAgICAgICAgaWYgKHRoaXMubHQoVFdPX1BXUl8yNCkgJiYgbXVsdGlwbGllci5sdChUV09fUFdSXzI0KSlcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21OdW1iZXIodGhpcy50b051bWJlcigpICogbXVsdGlwbGllci50b051bWJlcigpLCB0aGlzLnVuc2lnbmVkKTtcclxuXHJcbiAgICAgICAgLy8gRGl2aWRlIGVhY2ggbG9uZyBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIGFkZCB1cCA0eDQgcHJvZHVjdHMuXHJcbiAgICAgICAgLy8gV2UgY2FuIHNraXAgcHJvZHVjdHMgdGhhdCB3b3VsZCBvdmVyZmxvdy5cclxuXHJcbiAgICAgICAgdmFyIGE0OCA9IHRoaXMuaGlnaCA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGEzMiA9IHRoaXMuaGlnaCAmIDB4RkZGRjtcclxuICAgICAgICB2YXIgYTE2ID0gdGhpcy5sb3cgPj4+IDE2O1xyXG4gICAgICAgIHZhciBhMDAgPSB0aGlzLmxvdyAmIDB4RkZGRjtcclxuXHJcbiAgICAgICAgdmFyIGI0OCA9IG11bHRpcGxpZXIuaGlnaCA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGIzMiA9IG11bHRpcGxpZXIuaGlnaCAmIDB4RkZGRjtcclxuICAgICAgICB2YXIgYjE2ID0gbXVsdGlwbGllci5sb3cgPj4+IDE2O1xyXG4gICAgICAgIHZhciBiMDAgPSBtdWx0aXBsaWVyLmxvdyAmIDB4RkZGRjtcclxuXHJcbiAgICAgICAgdmFyIGM0OCA9IDAsIGMzMiA9IDAsIGMxNiA9IDAsIGMwMCA9IDA7XHJcbiAgICAgICAgYzAwICs9IGEwMCAqIGIwMDtcclxuICAgICAgICBjMTYgKz0gYzAwID4+PiAxNjtcclxuICAgICAgICBjMDAgJj0gMHhGRkZGO1xyXG4gICAgICAgIGMxNiArPSBhMTYgKiBiMDA7XHJcbiAgICAgICAgYzMyICs9IGMxNiA+Pj4gMTY7XHJcbiAgICAgICAgYzE2ICY9IDB4RkZGRjtcclxuICAgICAgICBjMTYgKz0gYTAwICogYjE2O1xyXG4gICAgICAgIGMzMiArPSBjMTYgPj4+IDE2O1xyXG4gICAgICAgIGMxNiAmPSAweEZGRkY7XHJcbiAgICAgICAgYzMyICs9IGEzMiAqIGIwMDtcclxuICAgICAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgICAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgICAgIGMzMiArPSBhMTYgKiBiMTY7XHJcbiAgICAgICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICAgICAgYzMyICY9IDB4RkZGRjtcclxuICAgICAgICBjMzIgKz0gYTAwICogYjMyO1xyXG4gICAgICAgIGM0OCArPSBjMzIgPj4+IDE2O1xyXG4gICAgICAgIGMzMiAmPSAweEZGRkY7XHJcbiAgICAgICAgYzQ4ICs9IGE0OCAqIGIwMCArIGEzMiAqIGIxNiArIGExNiAqIGIzMiArIGEwMCAqIGI0ODtcclxuICAgICAgICBjNDggJj0gMHhGRkZGO1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cygoYzE2IDw8IDE2KSB8IGMwMCwgKGM0OCA8PCAxNikgfCBjMzIsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI211bHRpcGx5fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUHJvZHVjdFxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm11bCA9IExvbmdQcm90b3R5cGUubXVsdGlwbHk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyBkaXZpZGVkIGJ5IHRoZSBzcGVjaWZpZWQuIFRoZSByZXN1bHQgaXMgc2lnbmVkIGlmIHRoaXMgTG9uZyBpcyBzaWduZWQgb3JcclxuICAgICAqICB1bnNpZ25lZCBpZiB0aGlzIExvbmcgaXMgdW5zaWduZWQuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBRdW90aWVudFxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmRpdmlkZSA9IGZ1bmN0aW9uIGRpdmlkZShkaXZpc29yKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcoZGl2aXNvcikpXHJcbiAgICAgICAgICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XHJcbiAgICAgICAgaWYgKGRpdmlzb3IuaXNaZXJvKCkpXHJcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdkaXZpc2lvbiBieSB6ZXJvJyk7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNaZXJvKCkpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xyXG4gICAgICAgIHZhciBhcHByb3gsIHJlbSwgcmVzO1xyXG4gICAgICAgIGlmICghdGhpcy51bnNpZ25lZCkge1xyXG4gICAgICAgICAgICAvLyBUaGlzIHNlY3Rpb24gaXMgb25seSByZWxldmFudCBmb3Igc2lnbmVkIGxvbmdzIGFuZCBpcyBkZXJpdmVkIGZyb20gdGhlXHJcbiAgICAgICAgICAgIC8vIGNsb3N1cmUgbGlicmFyeSBhcyBhIHdob2xlLlxyXG4gICAgICAgICAgICBpZiAodGhpcy5lcShNSU5fVkFMVUUpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGl2aXNvci5lcShPTkUpIHx8IGRpdmlzb3IuZXEoTkVHX09ORSkpXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1JTl9WQUxVRTsgIC8vIHJlY2FsbCB0aGF0IC1NSU5fVkFMVUUgPT0gTUlOX1ZBTFVFXHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9ORTtcclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQsIHdlIGhhdmUgfG90aGVyfCA+PSAyLCBzbyB8dGhpcy9vdGhlcnwgPCB8TUlOX1ZBTFVFfC5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgaGFsZlRoaXMgPSB0aGlzLnNocigxKTtcclxuICAgICAgICAgICAgICAgICAgICBhcHByb3ggPSBoYWxmVGhpcy5kaXYoZGl2aXNvcikuc2hsKDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhcHByb3guZXEoWkVSTykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpdmlzb3IuaXNOZWdhdGl2ZSgpID8gT05FIDogTkVHX09ORTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW0gPSB0aGlzLnN1YihkaXZpc29yLm11bChhcHByb3gpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gYXBwcm94LmFkZChyZW0uZGl2KGRpdmlzb3IpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZGl2aXNvci5lcShNSU5fVkFMVUUpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yLm5lZygpKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yKS5uZWcoKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChkaXZpc29yLmlzTmVnYXRpdmUoKSlcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRpdihkaXZpc29yLm5lZygpKS5uZWcoKTtcclxuICAgICAgICAgICAgcmVzID0gWkVSTztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBUaGUgYWxnb3JpdGhtIGJlbG93IGhhcyBub3QgYmVlbiBtYWRlIGZvciB1bnNpZ25lZCBsb25ncy4gSXQncyB0aGVyZWZvcmVcclxuICAgICAgICAgICAgLy8gcmVxdWlyZWQgdG8gdGFrZSBzcGVjaWFsIGNhcmUgb2YgdGhlIE1TQiBwcmlvciB0byBydW5uaW5nIGl0LlxyXG4gICAgICAgICAgICBpZiAoIWRpdmlzb3IudW5zaWduZWQpXHJcbiAgICAgICAgICAgICAgICBkaXZpc29yID0gZGl2aXNvci50b1Vuc2lnbmVkKCk7XHJcbiAgICAgICAgICAgIGlmIChkaXZpc29yLmd0KHRoaXMpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFVaRVJPO1xyXG4gICAgICAgICAgICBpZiAoZGl2aXNvci5ndCh0aGlzLnNocnUoMSkpKSAvLyAxNSA+Pj4gMSA9IDcgOyB3aXRoIGRpdmlzb3IgPSA4IDsgdHJ1ZVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFVPTkU7XHJcbiAgICAgICAgICAgIHJlcyA9IFVaRVJPO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmVwZWF0IHRoZSBmb2xsb3dpbmcgdW50aWwgdGhlIHJlbWFpbmRlciBpcyBsZXNzIHRoYW4gb3RoZXI6ICBmaW5kIGFcclxuICAgICAgICAvLyBmbG9hdGluZy1wb2ludCB0aGF0IGFwcHJveGltYXRlcyByZW1haW5kZXIgLyBvdGhlciAqZnJvbSBiZWxvdyosIGFkZCB0aGlzXHJcbiAgICAgICAgLy8gaW50byB0aGUgcmVzdWx0LCBhbmQgc3VidHJhY3QgaXQgZnJvbSB0aGUgcmVtYWluZGVyLiAgSXQgaXMgY3JpdGljYWwgdGhhdFxyXG4gICAgICAgIC8vIHRoZSBhcHByb3hpbWF0ZSB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHJlYWwgdmFsdWUgc28gdGhhdCB0aGVcclxuICAgICAgICAvLyByZW1haW5kZXIgbmV2ZXIgYmVjb21lcyBuZWdhdGl2ZS5cclxuICAgICAgICByZW0gPSB0aGlzO1xyXG4gICAgICAgIHdoaWxlIChyZW0uZ3RlKGRpdmlzb3IpKSB7XHJcbiAgICAgICAgICAgIC8vIEFwcHJveGltYXRlIHRoZSByZXN1bHQgb2YgZGl2aXNpb24uIFRoaXMgbWF5IGJlIGEgbGl0dGxlIGdyZWF0ZXIgb3JcclxuICAgICAgICAgICAgLy8gc21hbGxlciB0aGFuIHRoZSBhY3R1YWwgdmFsdWUuXHJcbiAgICAgICAgICAgIGFwcHJveCA9IE1hdGgubWF4KDEsIE1hdGguZmxvb3IocmVtLnRvTnVtYmVyKCkgLyBkaXZpc29yLnRvTnVtYmVyKCkpKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFdlIHdpbGwgdHdlYWsgdGhlIGFwcHJveGltYXRlIHJlc3VsdCBieSBjaGFuZ2luZyBpdCBpbiB0aGUgNDgtdGggZGlnaXQgb3JcclxuICAgICAgICAgICAgLy8gdGhlIHNtYWxsZXN0IG5vbi1mcmFjdGlvbmFsIGRpZ2l0LCB3aGljaGV2ZXIgaXMgbGFyZ2VyLlxyXG4gICAgICAgICAgICB2YXIgbG9nMiA9IE1hdGguY2VpbChNYXRoLmxvZyhhcHByb3gpIC8gTWF0aC5MTjIpLFxyXG4gICAgICAgICAgICAgICAgZGVsdGEgPSAobG9nMiA8PSA0OCkgPyAxIDogcG93X2RibCgyLCBsb2cyIC0gNDgpLFxyXG5cclxuICAgICAgICAgICAgLy8gRGVjcmVhc2UgdGhlIGFwcHJveGltYXRpb24gdW50aWwgaXQgaXMgc21hbGxlciB0aGFuIHRoZSByZW1haW5kZXIuICBOb3RlXHJcbiAgICAgICAgICAgIC8vIHRoYXQgaWYgaXQgaXMgdG9vIGxhcmdlLCB0aGUgcHJvZHVjdCBvdmVyZmxvd3MgYW5kIGlzIG5lZ2F0aXZlLlxyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVzID0gZnJvbU51bWJlcihhcHByb3gpLFxyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcclxuICAgICAgICAgICAgd2hpbGUgKGFwcHJveFJlbS5pc05lZ2F0aXZlKCkgfHwgYXBwcm94UmVtLmd0KHJlbSkpIHtcclxuICAgICAgICAgICAgICAgIGFwcHJveCAtPSBkZWx0YTtcclxuICAgICAgICAgICAgICAgIGFwcHJveFJlcyA9IGZyb21OdW1iZXIoYXBwcm94LCB0aGlzLnVuc2lnbmVkKTtcclxuICAgICAgICAgICAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFdlIGtub3cgdGhlIGFuc3dlciBjYW4ndCBiZSB6ZXJvLi4uIGFuZCBhY3R1YWxseSwgemVybyB3b3VsZCBjYXVzZVxyXG4gICAgICAgICAgICAvLyBpbmZpbml0ZSByZWN1cnNpb24gc2luY2Ugd2Ugd291bGQgbWFrZSBubyBwcm9ncmVzcy5cclxuICAgICAgICAgICAgaWYgKGFwcHJveFJlcy5pc1plcm8oKSlcclxuICAgICAgICAgICAgICAgIGFwcHJveFJlcyA9IE9ORTtcclxuXHJcbiAgICAgICAgICAgIHJlcyA9IHJlcy5hZGQoYXBwcm94UmVzKTtcclxuICAgICAgICAgICAgcmVtID0gcmVtLnN1YihhcHByb3hSZW0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNkaXZpZGV9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBRdW90aWVudFxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmRpdiA9IExvbmdQcm90b3R5cGUuZGl2aWRlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5tb2R1bG8gPSBmdW5jdGlvbiBtb2R1bG8oZGl2aXNvcikge1xyXG4gICAgICAgIGlmICghaXNMb25nKGRpdmlzb3IpKVxyXG4gICAgICAgICAgICBkaXZpc29yID0gZnJvbVZhbHVlKGRpdmlzb3IpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLnN1Yih0aGlzLmRpdihkaXZpc29yKS5tdWwoZGl2aXNvcikpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIG1vZHVsbyB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI21vZHVsb30uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm1vZCA9IExvbmdQcm90b3R5cGUubW9kdWxvO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgYml0d2lzZSBOT1Qgb2YgdGhpcyBMb25nLlxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm5vdCA9IGZ1bmN0aW9uIG5vdCgpIHtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMofnRoaXMubG93LCB+dGhpcy5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBiaXR3aXNlIEFORCBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5hbmQgPSBmdW5jdGlvbiBhbmQob3RoZXIpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgJiBvdGhlci5sb3csIHRoaXMuaGlnaCAmIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGJpdHdpc2UgT1Igb2YgdGhpcyBMb25nIGFuZCB0aGUgc3BlY2lmaWVkLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUub3IgPSBmdW5jdGlvbiBvcihvdGhlcikge1xyXG4gICAgICAgIGlmICghaXNMb25nKG90aGVyKSlcclxuICAgICAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyB8IG90aGVyLmxvdywgdGhpcy5oaWdoIHwgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgYml0d2lzZSBYT1Igb2YgdGhpcyBMb25nIGFuZCB0aGUgZ2l2ZW4gb25lLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUueG9yID0gZnVuY3Rpb24geG9yKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IF4gb3RoZXIubG93LCB0aGlzLmhpZ2ggXiBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgc2hpZnRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc2hpZnRMZWZ0ID0gZnVuY3Rpb24gc2hpZnRMZWZ0KG51bUJpdHMpIHtcclxuICAgICAgICBpZiAoaXNMb25nKG51bUJpdHMpKVxyXG4gICAgICAgICAgICBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xyXG4gICAgICAgIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIGVsc2UgaWYgKG51bUJpdHMgPCAzMilcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IDw8IG51bUJpdHMsICh0aGlzLmhpZ2ggPDwgbnVtQml0cykgfCAodGhpcy5sb3cgPj4+ICgzMiAtIG51bUJpdHMpKSwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoMCwgdGhpcy5sb3cgPDwgKG51bUJpdHMgLSAzMiksIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRMZWZ0fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc2hsID0gTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgYXJpdGhtZXRpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBmdW5jdGlvbiBzaGlmdFJpZ2h0KG51bUJpdHMpIHtcclxuICAgICAgICBpZiAoaXNMb25nKG51bUJpdHMpKVxyXG4gICAgICAgICAgICBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xyXG4gICAgICAgIGlmICgobnVtQml0cyAmPSA2MykgPT09IDApXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIGVsc2UgaWYgKG51bUJpdHMgPCAzMilcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21CaXRzKCh0aGlzLmxvdyA+Pj4gbnVtQml0cykgfCAodGhpcy5oaWdoIDw8ICgzMiAtIG51bUJpdHMpKSwgdGhpcy5oaWdoID4+IG51bUJpdHMsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21CaXRzKHRoaXMuaGlnaCA+PiAobnVtQml0cyAtIDMyKSwgdGhpcy5oaWdoID49IDAgPyAwIDogLTEsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI3NoaWZ0UmlnaHR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaHIgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQgPSBmdW5jdGlvbiBzaGlmdFJpZ2h0VW5zaWduZWQobnVtQml0cykge1xyXG4gICAgICAgIGlmIChpc0xvbmcobnVtQml0cykpXHJcbiAgICAgICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICAgICAgbnVtQml0cyAmPSA2MztcclxuICAgICAgICBpZiAobnVtQml0cyA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHZhciBoaWdoID0gdGhpcy5oaWdoO1xyXG4gICAgICAgICAgICBpZiAobnVtQml0cyA8IDMyKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbG93ID0gdGhpcy5sb3c7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoKGxvdyA+Pj4gbnVtQml0cykgfCAoaGlnaCA8PCAoMzIgLSBudW1CaXRzKSksIGhpZ2ggPj4+IG51bUJpdHMsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKG51bUJpdHMgPT09IDMyKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZyb21CaXRzKGhpZ2gsIDAsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoaGlnaCA+Pj4gKG51bUJpdHMgLSAzMiksIDAsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc2hydSA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodFVuc2lnbmVkO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIHNpZ25lZC5cclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2lnbmVkIGxvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b1NpZ25lZCA9IGZ1bmN0aW9uIHRvU2lnbmVkKCkge1xyXG4gICAgICAgIGlmICghdGhpcy51bnNpZ25lZClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93LCB0aGlzLmhpZ2gsIGZhbHNlKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gdW5zaWduZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFVuc2lnbmVkIGxvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b1Vuc2lnbmVkID0gZnVuY3Rpb24gdG9VbnNpZ25lZCgpIHtcclxuICAgICAgICBpZiAodGhpcy51bnNpZ25lZClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93LCB0aGlzLmhpZ2gsIHRydWUpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxlIFdoZXRoZXIgbGl0dGxlIG9yIGJpZyBlbmRpYW4sIGRlZmF1bHRzIHRvIGJpZyBlbmRpYW5cclxuICAgICAqIEByZXR1cm5zIHshQXJyYXkuPG51bWJlcj59IEJ5dGUgcmVwcmVzZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b0J5dGVzID0gZnVuY3Rpb24obGUpIHtcclxuICAgICAgICByZXR1cm4gbGUgPyB0aGlzLnRvQnl0ZXNMRSgpIDogdGhpcy50b0J5dGVzQkUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgbGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gTGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUudG9CeXRlc0xFID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdmFyIGhpID0gdGhpcy5oaWdoLFxyXG4gICAgICAgICAgICBsbyA9IHRoaXMubG93O1xyXG4gICAgICAgIHJldHVybiBbXHJcbiAgICAgICAgICAgICBsbyAgICAgICAgICYgMHhmZixcclxuICAgICAgICAgICAgKGxvID4+PiAgOCkgJiAweGZmLFxyXG4gICAgICAgICAgICAobG8gPj4+IDE2KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChsbyA+Pj4gMjQpICYgMHhmZixcclxuICAgICAgICAgICAgIGhpICAgICAgICAgJiAweGZmLFxyXG4gICAgICAgICAgICAoaGkgPj4+ICA4KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChoaSA+Pj4gMTYpICYgMHhmZixcclxuICAgICAgICAgICAgKGhpID4+PiAyNCkgJiAweGZmXHJcbiAgICAgICAgXTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgYmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUudG9CeXRlc0JFID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdmFyIGhpID0gdGhpcy5oaWdoLFxyXG4gICAgICAgICAgICBsbyA9IHRoaXMubG93O1xyXG4gICAgICAgIHJldHVybiBbXHJcbiAgICAgICAgICAgIChoaSA+Pj4gMjQpICYgMHhmZixcclxuICAgICAgICAgICAgKGhpID4+PiAxNikgJiAweGZmLFxyXG4gICAgICAgICAgICAoaGkgPj4+ICA4KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgICBoaSAgICAgICAgICYgMHhmZixcclxuICAgICAgICAgICAgKGxvID4+PiAyNCkgJiAweGZmLFxyXG4gICAgICAgICAgICAobG8gPj4+IDE2KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChsbyA+Pj4gIDgpICYgMHhmZixcclxuICAgICAgICAgICAgIGxvICAgICAgICAgJiAweGZmXHJcbiAgICAgICAgXTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gTG9uZztcclxufSk7XHJcbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2hCYXNlID0gcmVxdWlyZSgnaGFzaC1iYXNlJylcblxudmFyIEFSUkFZMTYgPSBuZXcgQXJyYXkoMTYpXG5cbmZ1bmN0aW9uIE1ENSAoKSB7XG4gIEhhc2hCYXNlLmNhbGwodGhpcywgNjQpXG5cbiAgLy8gc3RhdGVcbiAgdGhpcy5fYSA9IDB4Njc0NTIzMDFcbiAgdGhpcy5fYiA9IDB4ZWZjZGFiODlcbiAgdGhpcy5fYyA9IDB4OThiYWRjZmVcbiAgdGhpcy5fZCA9IDB4MTAzMjU0NzZcbn1cblxuaW5oZXJpdHMoTUQ1LCBIYXNoQmFzZSlcblxuTUQ1LnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgTSA9IEFSUkFZMTZcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgKytpKSBNW2ldID0gdGhpcy5fYmxvY2sucmVhZEludDMyTEUoaSAqIDQpXG5cbiAgdmFyIGEgPSB0aGlzLl9hXG4gIHZhciBiID0gdGhpcy5fYlxuICB2YXIgYyA9IHRoaXMuX2NcbiAgdmFyIGQgPSB0aGlzLl9kXG5cbiAgYSA9IGZuRihhLCBiLCBjLCBkLCBNWzBdLCAweGQ3NmFhNDc4LCA3KVxuICBkID0gZm5GKGQsIGEsIGIsIGMsIE1bMV0sIDB4ZThjN2I3NTYsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMl0sIDB4MjQyMDcwZGIsIDE3KVxuICBiID0gZm5GKGIsIGMsIGQsIGEsIE1bM10sIDB4YzFiZGNlZWUsIDIyKVxuICBhID0gZm5GKGEsIGIsIGMsIGQsIE1bNF0sIDB4ZjU3YzBmYWYsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVs1XSwgMHg0Nzg3YzYyYSwgMTIpXG4gIGMgPSBmbkYoYywgZCwgYSwgYiwgTVs2XSwgMHhhODMwNDYxMywgMTcpXG4gIGIgPSBmbkYoYiwgYywgZCwgYSwgTVs3XSwgMHhmZDQ2OTUwMSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVs4XSwgMHg2OTgwOThkOCwgNylcbiAgZCA9IGZuRihkLCBhLCBiLCBjLCBNWzldLCAweDhiNDRmN2FmLCAxMilcbiAgYyA9IGZuRihjLCBkLCBhLCBiLCBNWzEwXSwgMHhmZmZmNWJiMSwgMTcpXG4gIGIgPSBmbkYoYiwgYywgZCwgYSwgTVsxMV0sIDB4ODk1Y2Q3YmUsIDIyKVxuICBhID0gZm5GKGEsIGIsIGMsIGQsIE1bMTJdLCAweDZiOTAxMTIyLCA3KVxuICBkID0gZm5GKGQsIGEsIGIsIGMsIE1bMTNdLCAweGZkOTg3MTkzLCAxMilcbiAgYyA9IGZuRihjLCBkLCBhLCBiLCBNWzE0XSwgMHhhNjc5NDM4ZSwgMTcpXG4gIGIgPSBmbkYoYiwgYywgZCwgYSwgTVsxNV0sIDB4NDliNDA4MjEsIDIyKVxuXG4gIGEgPSBmbkcoYSwgYiwgYywgZCwgTVsxXSwgMHhmNjFlMjU2MiwgNSlcbiAgZCA9IGZuRyhkLCBhLCBiLCBjLCBNWzZdLCAweGMwNDBiMzQwLCA5KVxuICBjID0gZm5HKGMsIGQsIGEsIGIsIE1bMTFdLCAweDI2NWU1YTUxLCAxNClcbiAgYiA9IGZuRyhiLCBjLCBkLCBhLCBNWzBdLCAweGU5YjZjN2FhLCAyMClcbiAgYSA9IGZuRyhhLCBiLCBjLCBkLCBNWzVdLCAweGQ2MmYxMDVkLCA1KVxuICBkID0gZm5HKGQsIGEsIGIsIGMsIE1bMTBdLCAweDAyNDQxNDUzLCA5KVxuICBjID0gZm5HKGMsIGQsIGEsIGIsIE1bMTVdLCAweGQ4YTFlNjgxLCAxNClcbiAgYiA9IGZuRyhiLCBjLCBkLCBhLCBNWzRdLCAweGU3ZDNmYmM4LCAyMClcbiAgYSA9IGZuRyhhLCBiLCBjLCBkLCBNWzldLCAweDIxZTFjZGU2LCA1KVxuICBkID0gZm5HKGQsIGEsIGIsIGMsIE1bMTRdLCAweGMzMzcwN2Q2LCA5KVxuICBjID0gZm5HKGMsIGQsIGEsIGIsIE1bM10sIDB4ZjRkNTBkODcsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bOF0sIDB4NDU1YTE0ZWQsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bMTNdLCAweGE5ZTNlOTA1LCA1KVxuICBkID0gZm5HKGQsIGEsIGIsIGMsIE1bMl0sIDB4ZmNlZmEzZjgsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVs3XSwgMHg2NzZmMDJkOSwgMTQpXG4gIGIgPSBmbkcoYiwgYywgZCwgYSwgTVsxMl0sIDB4OGQyYTRjOGEsIDIwKVxuXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVs1XSwgMHhmZmZhMzk0MiwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzhdLCAweDg3NzFmNjgxLCAxMSlcbiAgYyA9IGZuSChjLCBkLCBhLCBiLCBNWzExXSwgMHg2ZDlkNjEyMiwgMTYpXG4gIGIgPSBmbkgoYiwgYywgZCwgYSwgTVsxNF0sIDB4ZmRlNTM4MGMsIDIzKVxuICBhID0gZm5IKGEsIGIsIGMsIGQsIE1bMV0sIDB4YTRiZWVhNDQsIDQpXG4gIGQgPSBmbkgoZCwgYSwgYiwgYywgTVs0XSwgMHg0YmRlY2ZhOSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVs3XSwgMHhmNmJiNGI2MCwgMTYpXG4gIGIgPSBmbkgoYiwgYywgZCwgYSwgTVsxMF0sIDB4YmViZmJjNzAsIDIzKVxuICBhID0gZm5IKGEsIGIsIGMsIGQsIE1bMTNdLCAweDI4OWI3ZWM2LCA0KVxuICBkID0gZm5IKGQsIGEsIGIsIGMsIE1bMF0sIDB4ZWFhMTI3ZmEsIDExKVxuICBjID0gZm5IKGMsIGQsIGEsIGIsIE1bM10sIDB4ZDRlZjMwODUsIDE2KVxuICBiID0gZm5IKGIsIGMsIGQsIGEsIE1bNl0sIDB4MDQ4ODFkMDUsIDIzKVxuICBhID0gZm5IKGEsIGIsIGMsIGQsIE1bOV0sIDB4ZDlkNGQwMzksIDQpXG4gIGQgPSBmbkgoZCwgYSwgYiwgYywgTVsxMl0sIDB4ZTZkYjk5ZTUsIDExKVxuICBjID0gZm5IKGMsIGQsIGEsIGIsIE1bMTVdLCAweDFmYTI3Y2Y4LCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzJdLCAweGM0YWM1NjY1LCAyMylcblxuICBhID0gZm5JKGEsIGIsIGMsIGQsIE1bMF0sIDB4ZjQyOTIyNDQsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVs3XSwgMHg0MzJhZmY5NywgMTApXG4gIGMgPSBmbkkoYywgZCwgYSwgYiwgTVsxNF0sIDB4YWI5NDIzYTcsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bNV0sIDB4ZmM5M2EwMzksIDIxKVxuICBhID0gZm5JKGEsIGIsIGMsIGQsIE1bMTJdLCAweDY1NWI1OWMzLCA2KVxuICBkID0gZm5JKGQsIGEsIGIsIGMsIE1bM10sIDB4OGYwY2NjOTIsIDEwKVxuICBjID0gZm5JKGMsIGQsIGEsIGIsIE1bMTBdLCAweGZmZWZmNDdkLCAxNSlcbiAgYiA9IGZuSShiLCBjLCBkLCBhLCBNWzFdLCAweDg1ODQ1ZGQxLCAyMSlcbiAgYSA9IGZuSShhLCBiLCBjLCBkLCBNWzhdLCAweDZmYTg3ZTRmLCA2KVxuICBkID0gZm5JKGQsIGEsIGIsIGMsIE1bMTVdLCAweGZlMmNlNmUwLCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzZdLCAweGEzMDE0MzE0LCAxNSlcbiAgYiA9IGZuSShiLCBjLCBkLCBhLCBNWzEzXSwgMHg0ZTA4MTFhMSwgMjEpXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVs0XSwgMHhmNzUzN2U4MiwgNilcbiAgZCA9IGZuSShkLCBhLCBiLCBjLCBNWzExXSwgMHhiZDNhZjIzNSwgMTApXG4gIGMgPSBmbkkoYywgZCwgYSwgYiwgTVsyXSwgMHgyYWQ3ZDJiYiwgMTUpXG4gIGIgPSBmbkkoYiwgYywgZCwgYSwgTVs5XSwgMHhlYjg2ZDM5MSwgMjEpXG5cbiAgdGhpcy5fYSA9ICh0aGlzLl9hICsgYSkgfCAwXG4gIHRoaXMuX2IgPSAodGhpcy5fYiArIGIpIHwgMFxuICB0aGlzLl9jID0gKHRoaXMuX2MgKyBjKSB8IDBcbiAgdGhpcy5fZCA9ICh0aGlzLl9kICsgZCkgfCAwXG59XG5cbk1ENS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gY3JlYXRlIHBhZGRpbmcgYW5kIGhhbmRsZSBibG9ja3NcbiAgdGhpcy5fYmxvY2tbdGhpcy5fYmxvY2tPZmZzZXQrK10gPSAweDgwXG4gIGlmICh0aGlzLl9ibG9ja09mZnNldCA+IDU2KSB7XG4gICAgdGhpcy5fYmxvY2suZmlsbCgwLCB0aGlzLl9ibG9ja09mZnNldCwgNjQpXG4gICAgdGhpcy5fdXBkYXRlKClcbiAgICB0aGlzLl9ibG9ja09mZnNldCA9IDBcbiAgfVxuXG4gIHRoaXMuX2Jsb2NrLmZpbGwoMCwgdGhpcy5fYmxvY2tPZmZzZXQsIDU2KVxuICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkxFKHRoaXMuX2xlbmd0aFswXSwgNTYpXG4gIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyTEUodGhpcy5fbGVuZ3RoWzFdLCA2MClcbiAgdGhpcy5fdXBkYXRlKClcblxuICAvLyBwcm9kdWNlIHJlc3VsdFxuICB2YXIgYnVmZmVyID0gbmV3IEJ1ZmZlcigxNilcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9hLCAwKVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2IsIDQpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYywgOClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9kLCAxMilcbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiByb3RsICh4LCBuKSB7XG4gIHJldHVybiAoeCA8PCBuKSB8ICh4ID4+PiAoMzIgLSBuKSlcbn1cblxuZnVuY3Rpb24gZm5GIChhLCBiLCBjLCBkLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYiAmIGMpIHwgKCh+YikgJiBkKSkgKyBtICsgaykgfCAwLCBzKSArIGIpIHwgMFxufVxuXG5mdW5jdGlvbiBmbkcgKGEsIGIsIGMsIGQsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiICYgZCkgfCAoYyAmICh+ZCkpKSArIG0gKyBrKSB8IDAsIHMpICsgYikgfCAwXG59XG5cbmZ1bmN0aW9uIGZuSCAoYSwgYiwgYywgZCwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoYiBeIGMgXiBkKSArIG0gKyBrKSB8IDAsIHMpICsgYikgfCAwXG59XG5cbmZ1bmN0aW9uIGZuSSAoYSwgYiwgYywgZCwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGMgXiAoYiB8ICh+ZCkpKSkgKyBtICsgaykgfCAwLCBzKSArIGIpIHwgMFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IE1ENVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5NYW5hZ2VyID0gZXhwb3J0cy5DaGFpbkNvbmZpZyA9IGV4cG9ydHMuQXBpcyA9IHVuZGVmaW5lZDtcblxudmFyIF9BcGlJbnN0YW5jZXMgPSByZXF1aXJlKCcuL3NyYy9BcGlJbnN0YW5jZXMnKTtcblxudmFyIF9BcGlJbnN0YW5jZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQXBpSW5zdGFuY2VzKTtcblxudmFyIF9Db25uZWN0aW9uTWFuYWdlciA9IHJlcXVpcmUoJy4vc3JjL0Nvbm5lY3Rpb25NYW5hZ2VyJyk7XG5cbnZhciBfQ29ubmVjdGlvbk1hbmFnZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ29ubmVjdGlvbk1hbmFnZXIpO1xuXG52YXIgX0NoYWluQ29uZmlnID0gcmVxdWlyZSgnLi9zcmMvQ2hhaW5Db25maWcnKTtcblxudmFyIF9DaGFpbkNvbmZpZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpbkNvbmZpZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmV4cG9ydHMuQXBpcyA9IF9BcGlJbnN0YW5jZXMyLmRlZmF1bHQ7XG5leHBvcnRzLkNoYWluQ29uZmlnID0gX0NoYWluQ29uZmlnMi5kZWZhdWx0O1xuZXhwb3J0cy5NYW5hZ2VyID0gX0Nvbm5lY3Rpb25NYW5hZ2VyMi5kZWZhdWx0OyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9DaGFpbldlYlNvY2tldCA9IHJlcXVpcmUoJy4vQ2hhaW5XZWJTb2NrZXQnKTtcblxudmFyIF9DaGFpbldlYlNvY2tldDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpbldlYlNvY2tldCk7XG5cbnZhciBfR3JhcGhlbmVBcGkgPSByZXF1aXJlKCcuL0dyYXBoZW5lQXBpJyk7XG5cbnZhciBfR3JhcGhlbmVBcGkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfR3JhcGhlbmVBcGkpO1xuXG52YXIgX0NoYWluQ29uZmlnID0gcmVxdWlyZSgnLi9DaGFpbkNvbmZpZycpO1xuXG52YXIgX0NoYWluQ29uZmlnMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0NoYWluQ29uZmlnKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIGluc3QgPSB2b2lkIDA7XG5cbnZhciBBcGlzSW5zdGFuY2UgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEFwaXNJbnN0YW5jZSgpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQXBpc0luc3RhbmNlKTtcbiAgfVxuXG4gIC8qKiBAYXJnIHtzdHJpbmd9IGNvbm5lY3Rpb24gLi4gKi9cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5jb25uZWN0ID0gZnVuY3Rpb24gY29ubmVjdChjcywgY29ubmVjdFRpbWVvdXQpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIHJwY191c2VyID0gJyc7XG4gICAgdmFyIHJwY19wYXNzd29yZCA9ICcnO1xuXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5sb2NhdGlvbiAmJiB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgPT09ICdodHRwczonICYmIGNzLmluZGV4T2YoJ3dzczovLycpIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTZWN1cmUgZG9tYWlucyByZXF1aXJlIHdzcyBjb25uZWN0aW9uJyk7XG4gICAgfVxuXG4gICAgdGhpcy53c19ycGMgPSBuZXcgX0NoYWluV2ViU29ja2V0Mi5kZWZhdWx0KGNzLCB0aGlzLnN0YXR1c0NiLCBjb25uZWN0VGltZW91dCk7XG5cbiAgICB0aGlzLmluaXRfcHJvbWlzZSA9IHRoaXMud3NfcnBjLmxvZ2luKHJwY191c2VyLCBycGNfcGFzc3dvcmQpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgY29uc29sZS5sb2coJ0Nvbm5lY3RlZCB0byBBUEkgbm9kZTonLCBjcyk7XG4gICAgICBfdGhpcy5fZGIgPSBuZXcgX0dyYXBoZW5lQXBpMi5kZWZhdWx0KF90aGlzLndzX3JwYywgJ2RhdGFiYXNlJyk7XG4gICAgICBfdGhpcy5fbmV0ID0gbmV3IF9HcmFwaGVuZUFwaTIuZGVmYXVsdChfdGhpcy53c19ycGMsICduZXR3b3JrX2Jyb2FkY2FzdCcpO1xuICAgICAgX3RoaXMuX2hpc3QgPSBuZXcgX0dyYXBoZW5lQXBpMi5kZWZhdWx0KF90aGlzLndzX3JwYywgJ2hpc3RvcnknKTtcbiAgICAgIF90aGlzLl9jcnlwdG8gPSBuZXcgX0dyYXBoZW5lQXBpMi5kZWZhdWx0KF90aGlzLndzX3JwYywgJ2NyeXB0bycpO1xuICAgICAgX3RoaXMuX2Jvb2tpZSA9IG5ldyBfR3JhcGhlbmVBcGkyLmRlZmF1bHQoX3RoaXMud3NfcnBjLCAnYm9va2llJyk7XG4gICAgICB2YXIgZGJfcHJvbWlzZSA9IF90aGlzLl9kYi5pbml0KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBfdGhpcy5fZGIuZXhlYygnZ2V0X2NoYWluX2lkJywgW10pLnRoZW4oZnVuY3Rpb24gKF9jaGFpbl9pZCkge1xuICAgICAgICAgIF90aGlzLmNoYWluX2lkID0gX2NoYWluX2lkO1xuICAgICAgICAgIHJldHVybiBfQ2hhaW5Db25maWcyLmRlZmF1bHQuc2V0Q2hhaW5JZChfY2hhaW5faWQpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBfdGhpcy53c19ycGMub25fcmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBfdGhpcy53c19ycGMubG9naW4oJycsICcnKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBfdGhpcy5fZGIuaW5pdCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKF90aGlzLnN0YXR1c0NiKSB7XG4gICAgICAgICAgICAgIF90aGlzLnN0YXR1c0NiKF9DaGFpbldlYlNvY2tldDIuZGVmYXVsdC5zdGF0dXMuUkVDT05ORUNURUQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIF90aGlzLl9uZXQuaW5pdCgpO1xuICAgICAgICAgIF90aGlzLl9oaXN0LmluaXQoKTtcbiAgICAgICAgICBfdGhpcy5fY3J5cHRvLmluaXQoKTtcbiAgICAgICAgICBfdGhpcy5fYm9va2llLmluaXQoKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2RiX3Byb21pc2UsIF90aGlzLl9uZXQuaW5pdCgpLCBfdGhpcy5faGlzdC5pbml0KCksXG4gICAgICAvLyBUZW1wb3Jhcnkgc3F1YXNoIGNyeXB0byBBUEkgZXJyb3IgdW50aWwgdGhlIEFQSSBpcyB1cGdyYWRlZCBldmVyeXdoZXJlXG4gICAgICBfdGhpcy5fY3J5cHRvLmluaXQoKS5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICByZXR1cm4gY29uc29sZS5lcnJvcignQXBpSW5zdGFuY2VcXHRDcnlwdG8gQVBJIEVycm9yJywgZSk7XG4gICAgICB9KSwgX3RoaXMuX2Jvb2tpZS5pbml0KCldKTtcbiAgICB9KTtcbiAgfTtcblxuICBBcGlzSW5zdGFuY2UucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMud3NfcnBjKSB7XG4gICAgICB0aGlzLndzX3JwYy5jbG9zZSgpO1xuICAgIH1cblxuICAgIHRoaXMud3NfcnBjID0gbnVsbDtcbiAgfTtcblxuICBBcGlzSW5zdGFuY2UucHJvdG90eXBlLmRiX2FwaSA9IGZ1bmN0aW9uIGRiX2FwaSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGI7XG4gIH07XG5cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5uZXR3b3JrX2FwaSA9IGZ1bmN0aW9uIG5ldHdvcmtfYXBpKCkge1xuICAgIHJldHVybiB0aGlzLl9uZXQ7XG4gIH07XG5cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5oaXN0b3J5X2FwaSA9IGZ1bmN0aW9uIGhpc3RvcnlfYXBpKCkge1xuICAgIHJldHVybiB0aGlzLl9oaXN0O1xuICB9O1xuXG4gIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUuY3J5cHRvX2FwaSA9IGZ1bmN0aW9uIGNyeXB0b19hcGkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NyeXB0bztcbiAgfTtcblxuICBBcGlzSW5zdGFuY2UucHJvdG90eXBlLmJvb2tpZV9hcGkgPSBmdW5jdGlvbiBib29raWVfYXBpKCkge1xuICAgIHJldHVybiB0aGlzLl9ib29raWU7XG4gIH07XG5cbiAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5zZXRScGNDb25uZWN0aW9uU3RhdHVzQ2FsbGJhY2sgPSBmdW5jdGlvbiBzZXRScGNDb25uZWN0aW9uU3RhdHVzQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgICB0aGlzLnN0YXR1c0NiID0gY2FsbGJhY2s7XG4gIH07XG5cbiAgcmV0dXJuIEFwaXNJbnN0YW5jZTtcbn0oKTtcblxuLyoqXG4gICAgQ29uZmlndXJlOiBjb25maWd1cmUgYXMgZm9sbG93cyBgQXBpcy5pbnN0YW5jZShcIndzOi8vbG9jYWxob3N0OjgwOTBcIikuaW5pdF9wcm9taXNlYC4gIFRoaXNcbiAgICByZXR1cm5zIGEgcHJvbWlzZSwgb25jZSByZXNvbHZlZCB0aGUgY29ubmVjdGlvbiBpcyByZWFkeS5cblxuICAgIEltcG9ydDogaW1wb3J0IHsgQXBpcyB9IGZyb20gXCJAZ3JhcGhlbmUvY2hhaW5cIlxuXG4gICAgU2hvcnQtaGFuZDogQXBpcy5kYihcIm1ldGhvZFwiLCBcInBhcm0xXCIsIDIsIDMsIC4uLikuICBSZXR1cm5zIGEgcHJvbWlzZSB3aXRoIHJlc3VsdHMuXG5cbiAgICBBZGRpdGlvbmFsIHVzYWdlOiBBcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcIm1ldGhvZFwiLCBbXCJtZXRob2RcIiwgXCJwYXJtMVwiLCAyLCAzLCAuLi5dKS5cbiAgICBSZXR1cm5zIGEgcHJvbWlzZSB3aXRoIHJlc3VsdHMuXG4qL1xuXG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gIHNldFJwY0Nvbm5lY3Rpb25TdGF0dXNDYWxsYmFjazogZnVuY3Rpb24gc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgdGhpcy5zdGF0dXNDYiA9IGNhbGxiYWNrO1xuXG4gICAgaWYgKGluc3QpIHtcbiAgICAgIGluc3Quc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKGNhbGxiYWNrKTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAgICAgIEBhcmcge3N0cmluZ30gY3MgaXMgb25seSBwcm92aWRlZCBpbiB0aGUgZmlyc3QgY2FsbFxuICAgICAgICBAcmV0dXJuIHtBcGlzfSBzaW5nbGV0b24gLi4gQ2hlY2sgQXBpcy5pbnN0YW5jZSgpLmluaXRfcHJvbWlzZSB0b1xuICAgICAgICBrbm93IHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgZXN0YWJsaXNoZWRcbiAgICAqL1xuICByZXNldDogZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgdmFyIGNzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiAnd3M6Ly9sb2NhbGhvc3Q6ODA5MCc7XG4gICAgdmFyIGNvbm5lY3QgPSBhcmd1bWVudHNbMV07XG4gICAgdmFyIGNvbm5lY3RUaW1lb3V0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiA0MDAwO1xuXG4gICAgaWYgKGluc3QpIHtcbiAgICAgIGluc3QuY2xvc2UoKTtcbiAgICAgIGluc3QgPSBudWxsO1xuICAgIH1cblxuICAgIGluc3QgPSBuZXcgQXBpc0luc3RhbmNlKCk7XG4gICAgaW5zdC5zZXRScGNDb25uZWN0aW9uU3RhdHVzQ2FsbGJhY2sodGhpcy5zdGF0dXNDYik7XG5cbiAgICBpZiAoaW5zdCAmJiBjb25uZWN0KSB7XG4gICAgICBpbnN0LmNvbm5lY3QoY3MsIGNvbm5lY3RUaW1lb3V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gaW5zdDtcbiAgfSxcbiAgaW5zdGFuY2U6IGZ1bmN0aW9uIGluc3RhbmNlKCkge1xuICAgIHZhciBjcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJ3dzOi8vbG9jYWxob3N0OjgwOTAnO1xuICAgIHZhciBjb25uZWN0ID0gYXJndW1lbnRzWzFdO1xuICAgIHZhciBjb25uZWN0VGltZW91dCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogNDAwMDtcblxuICAgIGlmICghaW5zdCkge1xuICAgICAgaW5zdCA9IG5ldyBBcGlzSW5zdGFuY2UoKTtcbiAgICAgIGluc3Quc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKHRoaXMuc3RhdHVzQ2IpO1xuICAgIH1cblxuICAgIGlmIChpbnN0ICYmIGNvbm5lY3QpIHtcbiAgICAgIGluc3QuY29ubmVjdChjcywgY29ubmVjdFRpbWVvdXQpO1xuICAgIH1cblxuICAgIHJldHVybiBpbnN0O1xuICB9LFxuICBjaGFpbklkOiBmdW5jdGlvbiBjaGFpbklkKCkge1xuICAgIHJldHVybiB0aGlzLmluc3RhbmNlKCkuY2hhaW5faWQ7XG4gIH0sXG4gIGNsb3NlOiBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICBpZiAoaW5zdCkge1xuICAgICAgaW5zdC5jbG9zZSgpO1xuICAgICAgaW5zdCA9IG51bGw7XG4gICAgfVxuICB9XG4gIC8vIGRiOiAobWV0aG9kLCAuLi5hcmdzKSA9PiBBcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhtZXRob2QsIHRvU3RyaW5ncyhhcmdzKSksXG4gIC8vIG5ldHdvcms6IChtZXRob2QsIC4uLmFyZ3MpID0+IEFwaXMuaW5zdGFuY2UoKS5uZXR3b3JrX2FwaSgpLmV4ZWMobWV0aG9kLCB0b1N0cmluZ3MoYXJncykpLFxuICAvLyBoaXN0b3J5OiAobWV0aG9kLCAuLi5hcmdzKSA9PiBBcGlzLmluc3RhbmNlKCkuaGlzdG9yeV9hcGkoKS5leGVjKG1ldGhvZCwgdG9TdHJpbmdzKGFyZ3MpKSxcbiAgLy8gY3J5cHRvOiAobWV0aG9kLCAuLi5hcmdzKSA9PiBBcGlzLmluc3RhbmNlKCkuY3J5cHRvX2FwaSgpLmV4ZWMobWV0aG9kLCB0b1N0cmluZ3MoYXJncykpXG5cbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgZGVmYXVsdHMgPSB7XG4gIGNvcmVfYXNzZXQ6ICdQUFknLFxuICBhZGRyZXNzX3ByZWZpeDogJ1BQWScsXG4gIGV4cGlyZV9pbl9zZWNzOiAxNSxcbiAgZXhwaXJlX2luX3NlY3NfcHJvcG9zYWw6IDI0ICogNjAgKiA2MCxcbiAgcmV2aWV3X2luX3NlY3NfY29tbWl0dGVlOiAyNCAqIDYwICogNjBcbn07XG5cbnZhciBuZXR3b3JrcyA9IHtcbiAgbmV0d29ya3M6IHtcbiAgICBQZWVycGxheXM6IHtcbiAgICAgIGNvcmVfYXNzZXQ6ICdQUFknLFxuICAgICAgYWRkcmVzc19wcmVmaXg6ICdQUFknLFxuICAgICAgY2hhaW5faWQ6ICc2YjZiNWYwY2U3YTM2ZDMyMzc2OGU1MzRmM2VkYjQxYzZkNjMzMmE1NDFhOTU3MjViOThlMjhkMTQwODUwMTM0J1xuICAgIH0sXG4gICAgUGVlcnBsYXlzVGVzdG5ldDoge1xuICAgICAgY29yZV9hc3NldDogJ1BQWVRFU1QnLFxuICAgICAgYWRkcmVzc19wcmVmaXg6ICdQUFlURVNUJyxcbiAgICAgIGNoYWluX2lkOiAnYmU2Yjc5Mjk1ZTcyODQwNmNiYjc0OTRiY2I2MjZlNjJhZDI3OGZhNDAxODY5OWNmOGY3NTczOWY0YzFhODFmZCdcbiAgICB9XG4gIH1cbn07XG5cbnZhciBDaGFpbkNvbmZpZyA9IGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gQ2hhaW5Db25maWcoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENoYWluQ29uZmlnKTtcblxuICAgIHRoaXMucmVzZXQoKTtcbiAgfVxuXG4gIENoYWluQ29uZmlnLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcywgZGVmYXVsdHMpO1xuICB9O1xuXG4gIENoYWluQ29uZmlnLnByb3RvdHlwZS5zZXRDaGFpbklkID0gZnVuY3Rpb24gc2V0Q2hhaW5JZChjaGFpbklEKSB7XG4gICAgdmFyIHJlZiA9IE9iamVjdC5rZXlzKG5ldHdvcmtzKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSByZWYubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIHZhciBuZXR3b3JrX25hbWUgPSByZWZbaV07XG4gICAgICB2YXIgbmV0d29yayA9IG5ldHdvcmtzW25ldHdvcmtfbmFtZV07XG5cbiAgICAgIGlmIChuZXR3b3JrLmNoYWluX2lkID09PSBjaGFpbklEKSB7XG4gICAgICAgIHRoaXMubmV0d29ya19uYW1lID0gbmV0d29ya19uYW1lO1xuXG4gICAgICAgIGlmIChuZXR3b3JrLmFkZHJlc3NfcHJlZml4KSB7XG4gICAgICAgICAgdGhpcy5hZGRyZXNzX3ByZWZpeCA9IG5ldHdvcmsuYWRkcmVzc19wcmVmaXg7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5ldHdvcmtfbmFtZTogbmV0d29ya19uYW1lLFxuICAgICAgICAgIG5ldHdvcms6IG5ldHdvcmtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubmV0d29ya19uYW1lKSB7XG4gICAgICBjb25zb2xlLmxvZygnVW5rbm93biBjaGFpbiBpZCAodGhpcyBtYXkgYmUgYSB0ZXN0bmV0KScsIGNoYWluSUQpO1xuICAgIH1cbiAgfTtcblxuICBDaGFpbkNvbmZpZy5wcm90b3R5cGUuc2V0UHJlZml4ID0gZnVuY3Rpb24gc2V0UHJlZml4KCkge1xuICAgIHZhciBwcmVmaXggPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6ICdQUFknO1xuXG4gICAgdGhpcy5hZGRyZXNzX3ByZWZpeCA9IHByZWZpeDtcbiAgfTtcblxuICByZXR1cm4gQ2hhaW5Db25maWc7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IG5ldyBDaGFpbkNvbmZpZygpOyIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIFNPQ0tFVF9ERUJVRyA9IGZhbHNlO1xudmFyIFdlYlNvY2tldENsaWVudCA9IG51bGw7XG5cbmlmICh0eXBlb2YgV2ViU29ja2V0ICE9PSAndW5kZWZpbmVkJykge1xuICBXZWJTb2NrZXRDbGllbnQgPSBXZWJTb2NrZXQ7XG59IGVsc2Uge1xuICBXZWJTb2NrZXRDbGllbnQgPSByZXF1aXJlKCd3cycpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGdsb2JhbC1yZXF1aXJlXG59XG5cbnZhciBTVUJTQ1JJQkVfT1BFUkFUSU9OUyA9IFsnc2V0X3N1YnNjcmliZV9jYWxsYmFjaycsICdzdWJzY3JpYmVfdG9fbWFya2V0JywgJ2Jyb2FkY2FzdF90cmFuc2FjdGlvbl93aXRoX2NhbGxiYWNrJywgJ3NldF9wZW5kaW5nX3RyYW5zYWN0aW9uX2NhbGxiYWNrJ107XG5cbnZhciBVTlNVQlNDUklCRV9PUEVSQVRJT05TID0gWyd1bnN1YnNjcmliZV9mcm9tX21hcmtldCcsICd1bnN1YnNjcmliZV9mcm9tX2FjY291bnRzJ107XG5cbnZhciBIRUFMVEhfQ0hFQ0tfSU5URVJWQUwgPSAxMDAwMDtcblxudmFyIENoYWluV2ViU29ja2V0ID0gZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICpDcmVhdGVzIGFuIGluc3RhbmNlIG9mIENoYWluV2ViU29ja2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gICAgc2VydmVyQWRkcmVzcyAgICAgICAgICAgVGhlIGFkZHJlc3Mgb2YgdGhlIHdlYnNvY2tldCB0byBjb25uZWN0IHRvLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSAgc3RhdHVzQ2IgICAgICAgICAgICAgICAgQ2FsbGVkIHdoZW4gc3RhdHVzIGV2ZW50cyBvY2N1ci5cbiAgICogQHBhcmFtIHtudW1iZXJ9ICAgIFtjb25uZWN0VGltZW91dD0xMDAwMF0gIFRoZSB0aW1lIGZvciBhIGNvbm5lY3Rpb24gYXR0ZW1wdCB0byBjb21wbGV0ZS5cbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuICBmdW5jdGlvbiBDaGFpbldlYlNvY2tldChzZXJ2ZXJBZGRyZXNzLCBzdGF0dXNDYikge1xuICAgIHZhciBjb25uZWN0VGltZW91dCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogMTAwMDA7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ2hhaW5XZWJTb2NrZXQpO1xuXG4gICAgdGhpcy5zdGF0dXNDYiA9IHN0YXR1c0NiO1xuICAgIHRoaXMuc2VydmVyQWRkcmVzcyA9IHNlcnZlckFkZHJlc3M7XG4gICAgdGhpcy50aW1lb3V0SW50ZXJ2YWwgPSBjb25uZWN0VGltZW91dDtcblxuICAgIC8vIFRoZSBjdXJyZW5jdCBjb25uZWN0aW9uIHN0YXRlIG9mIHRoZSB3ZWJzb2NrZXQuXG4gICAgdGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLnJlY29ubmVjdFRpbWVvdXQgPSBudWxsO1xuXG4gICAgLy8gQ2FsbGJhY2sgdG8gZXhlY3V0ZSB3aGVuIHRoZSB3ZWJzb2NrZXQgaXMgcmVjb25uZWN0ZWQuXG4gICAgdGhpcy5vbl9yZWNvbm5lY3QgPSBudWxsO1xuXG4gICAgLy8gQW4gaW5jcmVtZW50aW5nIElEIGZvciBlYWNoIHJlcXVlc3Qgc28gdGhhdCB3ZSBjYW4gcGFpciBpdCB3aXRoIHRoZVxuICAgIC8vIHJlc3BvbnNlIGZyb20gdGhlIHdlYnNvY2tldC5cbiAgICB0aGlzLmNiSWQgPSAwO1xuXG4gICAgLy8gT2JqZWN0cyB0byBzdG9yZSBrZXkvdmFsdWUgcGFpcnMgZm9yIGNhbGxiYWNrcywgc3Vic2NyaXB0aW9uIGNhbGxiYWNrc1xuICAgIC8vIGFuZCB1bnN1YnNjcmliZSBjYWxsYmFja3MuXG4gICAgdGhpcy5jYnMgPSB7fTtcbiAgICB0aGlzLnN1YnMgPSB7fTtcbiAgICB0aGlzLnVuc3ViID0ge307XG5cbiAgICAvLyBDdXJyZW50IGNvbm5lY3Rpb24gcHJvbWlzZXMnIHJlamVjdGlvblxuICAgIHRoaXMuY3VycmVudFJlc29sdmUgPSBudWxsO1xuICAgIHRoaXMuY3VycmVudFJlamVjdCA9IG51bGw7XG5cbiAgICAvLyBIZWFsdGggY2hlY2sgZm9yIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBCbG9ja0NoYWluLlxuICAgIHRoaXMuaGVhbHRoQ2hlY2sgPSBudWxsO1xuXG4gICAgLy8gQ29weSB0aGUgY29uc3RhbnRzIHRvIHRoaXMgaW5zdGFuY2UuXG4gICAgdGhpcy5zdGF0dXMgPSBDaGFpbldlYlNvY2tldC5zdGF0dXM7XG5cbiAgICAvLyBCaW5kIHRoZSBmdW5jdGlvbnMgdG8gdGhlIGluc3RhbmNlLlxuICAgIHRoaXMub25Db25uZWN0aW9uT3BlbiA9IHRoaXMub25Db25uZWN0aW9uT3Blbi5iaW5kKHRoaXMpO1xuICAgIHRoaXMub25Db25uZWN0aW9uQ2xvc2UgPSB0aGlzLm9uQ29ubmVjdGlvbkNsb3NlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5vbkNvbm5lY3Rpb25UZXJtaW5hdGUgPSB0aGlzLm9uQ29ubmVjdGlvblRlcm1pbmF0ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMub25Db25uZWN0aW9uRXJyb3IgPSB0aGlzLm9uQ29ubmVjdGlvbkVycm9yLmJpbmQodGhpcyk7XG4gICAgdGhpcy5vbkNvbm5lY3Rpb25UaW1lb3V0ID0gdGhpcy5vbkNvbm5lY3Rpb25UaW1lb3V0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5jcmVhdGVDb25uZWN0aW9uID0gdGhpcy5jcmVhdGVDb25uZWN0aW9uLmJpbmQodGhpcyk7XG4gICAgdGhpcy5jcmVhdGVDb25uZWN0aW9uUHJvbWlzZSA9IHRoaXMuY3JlYXRlQ29ubmVjdGlvblByb21pc2UuYmluZCh0aGlzKTtcbiAgICB0aGlzLmxpc3RlbmVyID0gdGhpcy5saXN0ZW5lci5iaW5kKHRoaXMpO1xuXG4gICAgLy8gQ3JlYXRlIHRoZSBpbml0aWFsIGNvbm5lY3Rpb24gdGhlIGJsb2NrY2hhaW4uXG4gICAgdGhpcy5jcmVhdGVDb25uZWN0aW9uKCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBCbG9ja2NoYWluLlxuICAgKlxuICAgKiBAcmV0dXJuc1xuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvbiA9IGZ1bmN0aW9uIGNyZWF0ZUNvbm5lY3Rpb24oKSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IGNyZWF0ZSBjb25uZWN0aW9uJyk7XG5cbiAgICAvLyBDbGVhciBhbnkgcG9zc2libGUgcmVjb25uZWN0IHRpbWVycy5cbiAgICB0aGlzLnJlY29ubmVjdFRpbWVvdXQgPSBudWxsO1xuXG4gICAgLy8gQ3JlYXRlIHRoZSBwcm9taXNlIGZvciB0aGlzIGNvbm5lY3Rpb25cbiAgICBpZiAoIXRoaXMuY29ubmVjdF9wcm9taXNlKSB7XG4gICAgICB0aGlzLmNvbm5lY3RfcHJvbWlzZSA9IG5ldyBQcm9taXNlKHRoaXMuY3JlYXRlQ29ubmVjdGlvblByb21pc2UpO1xuICAgIH1cblxuICAgIC8vIEF0dGVtcHQgdG8gY3JlYXRlIHRoZSB3ZWJzb2NrZXRcbiAgICB0cnkge1xuICAgICAgdGhpcy53cyA9IG5ldyBXZWJTb2NrZXRDbGllbnQodGhpcy5zZXJ2ZXJBZGRyZXNzKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gU2V0IGEgdGltZW91dCB0byB0cnkgYW5kIHJlY29ubmVjdCBoZXJlLlxuICAgICAgcmV0dXJuIHRoaXMucmVzZXRDb25uZWN0aW9uKCk7XG4gICAgfVxuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuXG4gICAgLy8gSGFuZGxlIHRpbWVvdXRzIHRvIHRoZSB3ZWJzb2NrZXQncyBpbml0aWFsIGNvbm5lY3Rpb24uXG4gICAgdGhpcy5jb25uZWN0aW9uVGltZW91dCA9IHNldFRpbWVvdXQodGhpcy5vbkNvbm5lY3Rpb25UaW1lb3V0LCB0aGlzLnRpbWVvdXRJbnRlcnZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBjb25uZWN0aW9uIHRvIHRoZSBCbG9ja0NoYWluLlxuICAgKlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUucmVzZXRDb25uZWN0aW9uID0gZnVuY3Rpb24gcmVzZXRDb25uZWN0aW9uKCkge1xuICAgIC8vIENsb3NlIHRoZSBXZWJzb2NrZXQgaWYgaXRzIHN0aWxsICdoYWxmLW9wZW4nXG4gICAgdGhpcy5jbG9zZSgpO1xuXG4gICAgLy8gTWFrZSBzdXJlIHdlIG9ubHkgZXZlciBoYXZlIG9uZSB0aW1lb3V0IHJ1bm5pbmcgdG8gcmVjb25uZWN0LlxuICAgIGlmICghdGhpcy5yZWNvbm5lY3RUaW1lb3V0KSB7XG4gICAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgcmVzZXQgY29ubmVjdGlvbicsIHRoaXMudGltZW91dEludGVydmFsKTtcbiAgICAgIHRoaXMucmVjb25uZWN0VGltZW91dCA9IHNldFRpbWVvdXQodGhpcy5jcmVhdGVDb25uZWN0aW9uLCB0aGlzLnRpbWVvdXRJbnRlcnZhbCk7XG4gICAgfVxuXG4gICAgLy8gUmVqZWN0IHRoZSBjdXJyZW50IHByb21pc2UgaWYgdGhlcmUgaXMgb25lLlxuICAgIGlmICh0aGlzLmN1cnJlbnRSZWplY3QpIHtcbiAgICAgIHRoaXMuY3VycmVudFJlamVjdChuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gYXR0ZW1wdCBmYWlsZWQ6ICcgKyB0aGlzLnNlcnZlckFkZHJlc3MpKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEFkZCBldmVudCBsaXN0ZW5lcnMgdG8gdGhlIFdlYlNvY2tldC5cbiAgICpcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24gYWRkRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IGFkZCBldmVudCBsaXN0ZW5lcnMnKTtcbiAgICB0aGlzLndzLmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCB0aGlzLm9uQ29ubmVjdGlvbk9wZW4pO1xuICAgIHRoaXMud3MuYWRkRXZlbnRMaXN0ZW5lcignY2xvc2UnLCB0aGlzLm9uQ29ubmVjdGlvbkNsb3NlKTtcbiAgICB0aGlzLndzLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgdGhpcy5vbkNvbm5lY3Rpb25FcnJvcik7XG4gICAgdGhpcy53cy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5saXN0ZW5lcik7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgZXZlbnQgbGlzdGVycyBmcm9tIHRoZSBXZWJTb2NrZXQuIEl0cyBpbXBvcnRhbnQgdG8gcmVtb3ZlIHRoZSBldmVudCBsaXN0ZXJlcnNcbiAgICogZm9yIGdhcmJhYWdlIGNvbGxlY3Rpb24uIEJlY2F1c2Ugd2UgYXJlIGNyZWF0aW5nIGEgbmV3IFdlYlNvY2tldCBvbiBlYWNoIGNvbm5lY3Rpb24gYXR0ZW1wdFxuICAgKiBhbnkgbGlzdGVuZXJzIHRoYXQgYXJlIHN0aWxsIGF0dGFjaGVkIGNvdWxkIHByZXZlbnQgdGhlIG9sZCBzb2NrZXRzIGZyb21cbiAgICogYmVpbmcgZ2FyYmFnZSBjb2xsZWN0ZWQuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBDaGFpbldlYlNvY2tldFxuICAgKi9cblxuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVycyA9IGZ1bmN0aW9uIHJlbW92ZUV2ZW50TGlzdGVuZXJzKCkge1xuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCByZW1vdmUgZXZlbnQgbGlzdGVuZXJzJyk7XG4gICAgdGhpcy53cy5yZW1vdmVFdmVudExpc3RlbmVyKCdvcGVuJywgdGhpcy5vbkNvbm5lY3Rpb25PcGVuKTtcbiAgICB0aGlzLndzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Nsb3NlJywgdGhpcy5vbkNvbm5lY3Rpb25DbG9zZSk7XG4gICAgdGhpcy53cy5yZW1vdmVFdmVudExpc3RlbmVyKCdlcnJvcicsIHRoaXMub25Db25uZWN0aW9uRXJyb3IpO1xuICAgIHRoaXMud3MucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRoaXMubGlzdGVuZXIpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIHRoYXQgaXMgcGFzc2VkIHRvIGEgbmV3IHByb21pc2UgdGhhdCBzdG9yZXMgdGhlIHJlc29sdmUgYW5kIHJlamVjdCBjYWxsYmFja3NcbiAgICogaW4gdGhlIHN0YXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSByZXNvbHZlIEEgY2FsbGJhY2sgdG8gYmUgZXhlY3V0ZWQgd2hlbiB0aGUgcHJvbWlzZSBpcyByZXNvbHZlZC5cbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gcmVqZWN0IEEgY2FsbGJhY2sgdG8gYmUgZXhlY3V0ZWQgd2hlbiB0aGUgcHJvbWlzZSBpcyByZWplY3RlZC5cbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLmNyZWF0ZUNvbm5lY3Rpb25Qcm9taXNlID0gZnVuY3Rpb24gY3JlYXRlQ29ubmVjdGlvblByb21pc2UocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IGNyZWF0ZVByb21pc2UnKTtcbiAgICB0aGlzLmN1cnJlbnRSZXNvbHZlID0gcmVzb2x2ZTtcbiAgICB0aGlzLmN1cnJlbnRSZWplY3QgPSByZWplY3Q7XG4gIH07XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIGEgbmV3IFdlYnNvY2tldCBjb25uZWN0aW9uIGlzIG9wZW5lZC5cbiAgICpcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLm9uQ29ubmVjdGlvbk9wZW4gPSBmdW5jdGlvbiBvbkNvbm5lY3Rpb25PcGVuKCkge1xuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCBDb25uZWN0ZWQgJyk7XG5cbiAgICB0aGlzLmNvbm5lY3RlZCA9IHRydWU7XG5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5jb25uZWN0aW9uVGltZW91dCk7XG4gICAgdGhpcy5jb25uZWN0aW9uVGltZW91dCA9IG51bGw7XG5cbiAgICAvLyBUaGlzIHdpbGwgdHJpZ2dlciB0aGUgbG9naW4gcHJvY2VzcyBhcyB3ZWxsIGFzIHNvbWUgYWRkaXRpb25hbCBzZXR1cCBpbiBBcGlJbnN0YW5jZXNcbiAgICBpZiAodGhpcy5vbl9yZWNvbm5lY3QpIHtcbiAgICAgIHRoaXMub25fcmVjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY3VycmVudFJlc29sdmUpIHtcbiAgICAgIHRoaXMuY3VycmVudFJlc29sdmUoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGF0dXNDYikge1xuICAgICAgdGhpcy5zdGF0dXNDYihDaGFpbldlYlNvY2tldC5zdGF0dXMuT1BFTik7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBjYWxsZWQgd2hlbiB0aGUgY29ubmVjdGlvbiBhdHRlbXB0IHRpbWVzIG91dC5cbiAgICpcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLm9uQ29ubmVjdGlvblRpbWVvdXQgPSBmdW5jdGlvbiBvbkNvbm5lY3Rpb25UaW1lb3V0KCkge1xuICAgIHRoaXMuZGVidWcoJyEhISBDaGFpbldlYlNvY2tldCB0aW1lb3V0Jyk7XG4gICAgdGhpcy5vbkNvbm5lY3Rpb25DbG9zZShuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gdGltZWQgb3V0LicpKTtcbiAgfTtcblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gdGhlIFdlYnNvY2tldCBpcyBub3QgcmVzcG9uZGluZyB0byB0aGUgaGVhbHRoIGNoZWNrcy5cbiAgICpcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLm9uQ29ubmVjdGlvblRlcm1pbmF0ZSA9IGZ1bmN0aW9uIG9uQ29ubmVjdGlvblRlcm1pbmF0ZSgpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgdGVybWluYXRlJyk7XG4gICAgdGhpcy5vbkNvbm5lY3Rpb25DbG9zZShuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gd2FzIHRlcm1pbmF0ZWQuJykpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDYWxsZWQgd2hlbiB0aGUgY29ubmVjdGlvbiB0byB0aGUgQmxvY2tjaGFpbiBpcyBjbG9zZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gZXJyb3JcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLm9uQ29ubmVjdGlvbkNsb3NlID0gZnVuY3Rpb24gb25Db25uZWN0aW9uQ2xvc2UoZXJyb3IpIHtcbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgQ2xvc2UgJywgZXJyb3IpO1xuXG4gICAgdGhpcy5yZXNldENvbm5lY3Rpb24oKTtcblxuICAgIGlmICh0aGlzLnN0YXR1c0NiKSB7XG4gICAgICB0aGlzLnN0YXR1c0NiKENoYWluV2ViU29ja2V0LnN0YXR1cy5DTE9TRUQpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gdGhlIFdlYnNvY2tldCBlbmNvdW50ZXJzIGFuIGVycm9yLlxuICAgKlxuICAgKiBAcGFyYW0geyp9IGVycm9yXG4gICAqIEBtZW1iZXJvZiBDaGFpbldlYlNvY2tldFxuICAgKi9cblxuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5vbkNvbm5lY3Rpb25FcnJvciA9IGZ1bmN0aW9uIG9uQ29ubmVjdGlvbkVycm9yKGVycm9yKSB7XG4gICAgdGhpcy5kZWJ1ZygnISEhIENoYWluV2ViU29ja2V0IE9uIENvbm5lY3Rpb24gRXJyb3IgJywgZXJyb3IpO1xuXG4gICAgdGhpcy5yZXNldENvbm5lY3Rpb24oKTtcblxuICAgIGlmICh0aGlzLnN0YXR1c0NiKSB7XG4gICAgICB0aGlzLnN0YXR1c0NiKENoYWluV2ViU29ja2V0LnN0YXR1cy5FUlJPUik7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBFbnRyeSBwb2ludCB0byBtYWtlIFJQQyBjYWxscyBvbiB0aGUgQmxvY2tDaGFpbi5cbiAgICpcbiAgICogQHBhcmFtIHthcnJheX0gcGFyYW1zIEFuIGFycmF5IG9mIHBhcmFtcyB0byBiZSBwYXNzZWQgdG8gdGhlIHJwYyBjYWxsLiBbbWV0aG9kLCAuLi5wYXJhbXNdXG4gICAqIEByZXR1cm5zIEEgbmV3IHByb21pc2UgZm9yIHRoaXMgc3BlY2lmaWMgY2FsbC5cbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLmNhbGwgPSBmdW5jdGlvbiBjYWxsKHBhcmFtcykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICBpZiAoIXRoaXMuY29ubmVjdGVkKSB7XG4gICAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgQ2FsbCBub3QgY29ubmVjdGVkLiAnKTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ0Rpc2Nvbm5lY3RlZCBmcm9tIHRoZSBCbG9ja0NoYWluLicpKTtcbiAgICB9XG5cbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgQ2FsbCBjb25uZWN0ZWQuICcsIHBhcmFtcyk7XG5cbiAgICB2YXIgcmVxdWVzdCA9IHtcbiAgICAgIG1ldGhvZDogcGFyYW1zWzFdLFxuICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICBpZDogdGhpcy5jYklkICsgMVxuICAgIH07XG5cbiAgICB0aGlzLmNiSWQgPSByZXF1ZXN0LmlkO1xuXG4gICAgaWYgKFNVQlNDUklCRV9PUEVSQVRJT05TLmluY2x1ZGVzKHJlcXVlc3QubWV0aG9kKSkge1xuICAgICAgLy8gU3RvcmUgY2FsbGJhY2sgaW4gc3VicyBtYXBcbiAgICAgIHRoaXMuc3Vic1tyZXF1ZXN0LmlkXSA9IHtcbiAgICAgICAgY2FsbGJhY2s6IHJlcXVlc3QucGFyYW1zWzJdWzBdXG4gICAgICB9O1xuXG4gICAgICAvLyBSZXBsYWNlIGNhbGxiYWNrIHdpdGggdGhlIGNhbGxiYWNrIGlkXG4gICAgICByZXF1ZXN0LnBhcmFtc1syXVswXSA9IHJlcXVlc3QuaWQ7XG4gICAgfVxuXG4gICAgaWYgKFVOU1VCU0NSSUJFX09QRVJBVElPTlMuaW5jbHVkZXMocmVxdWVzdC5tZXRob2QpKSB7XG4gICAgICBpZiAodHlwZW9mIHJlcXVlc3QucGFyYW1zWzJdWzBdICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRmlyc3QgcGFyYW1ldGVyIG9mIHVuc3ViIG11c3QgYmUgdGhlIG9yaWdpbmFsIGNhbGxiYWNrJyk7XG4gICAgICB9XG5cbiAgICAgIHZhciB1blN1YkNiID0gcmVxdWVzdC5wYXJhbXNbMl0uc3BsaWNlKDAsIDEpWzBdO1xuXG4gICAgICAvLyBGaW5kIHRoZSBjb3JyZXNwb25kaW5nIHN1YnNjcmlwdGlvblxuICAgICAgZm9yICh2YXIgaWQgaW4gdGhpcy5zdWJzKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICAgICAgaWYgKHRoaXMuc3Vic1tpZF0uY2FsbGJhY2sgPT09IHVuU3ViQ2IpIHtcbiAgICAgICAgICB0aGlzLnVuc3ViW3JlcXVlc3QuaWRdID0gaWQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuaGVhbHRoQ2hlY2spIHtcbiAgICAgIHRoaXMuaGVhbHRoQ2hlY2sgPSBzZXRUaW1lb3V0KHRoaXMub25Db25uZWN0aW9uVGVybWluYXRlLmJpbmQodGhpcyksIEhFQUxUSF9DSEVDS19JTlRFUlZBTCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIF90aGlzLmNic1tyZXF1ZXN0LmlkXSA9IHtcbiAgICAgICAgdGltZTogbmV3IERhdGUoKSxcbiAgICAgICAgcmVzb2x2ZTogcmVzb2x2ZSxcbiAgICAgICAgcmVqZWN0OiByZWplY3RcbiAgICAgIH07XG5cbiAgICAgIC8vIFNldCBhbGwgcmVxdWVzdHMgdG8gYmUgJ2NhbGwnIG1ldGhvZHMuXG4gICAgICByZXF1ZXN0Lm1ldGhvZCA9ICdjYWxsJztcblxuICAgICAgdHJ5IHtcbiAgICAgICAgX3RoaXMud3Muc2VuZChKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBfdGhpcy5kZWJ1ZygnQ2F1Z2h0IGEgbmFzdHkgZXJyb3IgOiAnLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIG1lc3NhZ2VzIGFyZSByZWNlaXZlZCBvbiB0aGUgV2Vic29ja2V0LlxuICAgKlxuICAgKiBAcGFyYW0geyp9IHJlc3BvbnNlIFRoZSBtZXNzYWdlIHJlY2VpdmVkLlxuICAgKiBAbWVtYmVyb2YgQ2hhaW5XZWJTb2NrZXRcbiAgICovXG5cblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUubGlzdGVuZXIgPSBmdW5jdGlvbiBsaXN0ZW5lcihyZXNwb25zZSkge1xuICAgIHZhciByZXNwb25zZUpTT04gPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgIHJlc3BvbnNlSlNPTiA9IEpTT04ucGFyc2UocmVzcG9uc2UuZGF0YSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJlc3BvbnNlSlNPTi5lcnJvciA9ICdFcnJvciBwYXJzaW5nIHJlc3BvbnNlOiAnICsgZXJyb3Iuc3RhY2s7XG4gICAgICB0aGlzLmRlYnVnKCdFcnJvciBwYXJzaW5nIHJlc3BvbnNlOiAnLCByZXNwb25zZSk7XG4gICAgfVxuXG4gICAgLy8gQ2xlYXIgdGhlIGhlYWx0aCBjaGVjayB0aW1lb3V0LCB3ZSd2ZSBqdXN0IHJlY2VpdmVkIGEgaGVhbHRoeSByZXNwb25zZSBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgaWYgKHRoaXMuaGVhbHRoQ2hlY2spIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLmhlYWx0aENoZWNrKTtcbiAgICAgIHRoaXMuaGVhbHRoQ2hlY2sgPSBudWxsO1xuICAgIH1cblxuICAgIHZhciBzdWIgPSBmYWxzZTtcbiAgICB2YXIgY2FsbGJhY2sgPSBudWxsO1xuXG4gICAgaWYgKHJlc3BvbnNlSlNPTi5tZXRob2QgPT09ICdub3RpY2UnKSB7XG4gICAgICBzdWIgPSB0cnVlO1xuICAgICAgcmVzcG9uc2VKU09OLmlkID0gcmVzcG9uc2VKU09OLnBhcmFtc1swXTtcbiAgICB9XG5cbiAgICBpZiAoIXN1Yikge1xuICAgICAgY2FsbGJhY2sgPSB0aGlzLmNic1tyZXNwb25zZUpTT04uaWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjayA9IHRoaXMuc3Vic1tyZXNwb25zZUpTT04uaWRdLmNhbGxiYWNrO1xuICAgIH1cblxuICAgIGlmIChjYWxsYmFjayAmJiAhc3ViKSB7XG4gICAgICBpZiAocmVzcG9uc2VKU09OLmVycm9yKSB7XG4gICAgICAgIHRoaXMuZGVidWcoJy0tLS0+IHJlc3BvbnNlSlNPTiA6ICcsIHJlc3BvbnNlSlNPTik7XG4gICAgICAgIGNhbGxiYWNrLnJlamVjdChyZXNwb25zZUpTT04uZXJyb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sucmVzb2x2ZShyZXNwb25zZUpTT04ucmVzdWx0KTtcbiAgICAgIH1cblxuICAgICAgZGVsZXRlIHRoaXMuY2JzW3Jlc3BvbnNlSlNPTi5pZF07XG5cbiAgICAgIGlmICh0aGlzLnVuc3ViW3Jlc3BvbnNlSlNPTi5pZF0pIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuc3Vic1t0aGlzLnVuc3ViW3Jlc3BvbnNlSlNPTi5pZF1dO1xuICAgICAgICBkZWxldGUgdGhpcy51bnN1YltyZXNwb25zZUpTT04uaWRdO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY2FsbGJhY2sgJiYgc3ViKSB7XG4gICAgICBjYWxsYmFjayhyZXNwb25zZUpTT04ucGFyYW1zWzFdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZWJ1ZygnV2FybmluZzogdW5rbm93biB3ZWJzb2NrZXQgcmVzcG9uc2VKU09OOiAnLCByZXNwb25zZUpTT04pO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogTG9naW4gdG8gdGhlIEJsb2NrY2hhaW4uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VyIFVzZXJuYW1lXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCBQYXNzd29yZFxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCBpcyBmdWxmaWxsZWQgYWZ0ZXIgbG9naW4uXG4gICAqIEBtZW1iZXJvZiBDaGFpbldlYlNvY2tldFxuICAgKi9cblxuXG4gIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5sb2dpbiA9IGZ1bmN0aW9uIGxvZ2luKHVzZXIsIHBhc3N3b3JkKSB7XG4gICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICB0aGlzLmRlYnVnKCchISEgQ2hhaW5XZWJTb2NrZXQgbG9naW4uJywgdXNlciwgcGFzc3dvcmQpO1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3RfcHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBfdGhpczIuY2FsbChbMSwgJ2xvZ2luJywgW3VzZXIsIHBhc3N3b3JkXV0pO1xuICAgIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDbG9zZSB0aGUgY29ubmVjdGlvbiB0byB0aGUgQmxvY2tjaGFpbi5cbiAgICpcbiAgICogQG1lbWJlcm9mIENoYWluV2ViU29ja2V0XG4gICAqL1xuXG5cbiAgQ2hhaW5XZWJTb2NrZXQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMud3MpIHtcbiAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcblxuICAgICAgLy8gVHJ5IGFuZCBmaXJlIGNsb3NlIG9uIHRoZSBjb25uZWN0aW9uLlxuICAgICAgdGhpcy53cy5jbG9zZSgpO1xuXG4gICAgICAvLyBDbGVhciBvdXIgcmVmZXJlbmNlcyBzbyB0aGF0IGl0IGNhbiBiZSBnYXJiYWdlIGNvbGxlY3RlZC5cbiAgICAgIHRoaXMud3MgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIENsZWFyIG91ciB0aW1lb3V0cyBmb3IgY29ubmVjdGlvbiB0aW1lb3V0IGFuZCBoZWFsdGggY2hlY2suXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuY29ubmVjdGlvblRpbWVvdXQpO1xuICAgIHRoaXMuY29ubmVjdGlvblRpbWVvdXQgPSBudWxsO1xuXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGVhbHRoQ2hlY2spO1xuICAgIHRoaXMuaGVhbHRoQ2hlY2sgPSBudWxsO1xuXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucmVjb25uZWN0VGltZW91dCk7XG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lb3V0ID0gbnVsbDtcblxuICAgIC8vIFRvZ2dsZSB0aGUgY29ubmVjdGVkIGZsYWcuXG4gICAgdGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgfTtcblxuICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuZGVidWcgPSBmdW5jdGlvbiBkZWJ1ZygpIHtcbiAgICBpZiAoU09DS0VUX0RFQlVHKSB7XG4gICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgcGFyYW1zID0gQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgIHBhcmFtc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgIH1cblxuICAgICAgY29uc29sZS5sb2cuYXBwbHkobnVsbCwgcGFyYW1zKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIENoYWluV2ViU29ja2V0O1xufSgpO1xuXG4vLyBDb25zdGFudHMgZm9yIFNUQVRFXG5cblxuQ2hhaW5XZWJTb2NrZXQuc3RhdHVzID0ge1xuICBSRUNPTk5FQ1RFRDogJ3JlY29ubmVjdGVkJyxcbiAgT1BFTjogJ29wZW4nLFxuICBDTE9TRUQ6ICdjbG9zZWQnLFxuICBFUlJPUjogJ2Vycm9yJ1xufTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gQ2hhaW5XZWJTb2NrZXQ7IiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX0FwaUluc3RhbmNlcyA9IHJlcXVpcmUoJy4vQXBpSW5zdGFuY2VzJyk7XG5cbnZhciBfQXBpSW5zdGFuY2VzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0FwaUluc3RhbmNlcyk7XG5cbnZhciBfQ2hhaW5XZWJTb2NrZXQgPSByZXF1aXJlKCcuL0NoYWluV2ViU29ja2V0Jyk7XG5cbnZhciBfQ2hhaW5XZWJTb2NrZXQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2hhaW5XZWJTb2NrZXQpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgTWFuYWdlciA9IGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gTWFuYWdlcihfcmVmKSB7XG4gICAgdmFyIHVybCA9IF9yZWYudXJsLFxuICAgICAgICB1cmxzID0gX3JlZi51cmxzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIE1hbmFnZXIpO1xuXG4gICAgdGhpcy51cmwgPSB1cmw7XG4gICAgdGhpcy51cmxzID0gdXJscy5maWx0ZXIoZnVuY3Rpb24gKGEpIHtcbiAgICAgIHJldHVybiBhICE9PSB1cmw7XG4gICAgfSk7XG4gIH1cblxuICBNYW5hZ2VyLnByb3RvdHlwZS5sb2dGYWlsdXJlID0gZnVuY3Rpb24gbG9nRmFpbHVyZSh1cmwpIHtcbiAgICBjb25zb2xlLmVycm9yKCdVbmFibGUgdG8gY29ubmVjdCB0bycsIHVybCArICcsIHNraXBwaW5nIHRvIG5leHQgZnVsbCBub2RlIEFQSSBzZXJ2ZXInKTtcbiAgfTtcblxuICBNYW5hZ2VyLnByb3RvdHlwZS5jb25uZWN0ID0gZnVuY3Rpb24gY29ubmVjdCgpIHtcbiAgICB2YXIgX2Nvbm5lY3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRydWU7XG5cbiAgICB2YXIgdXJsID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB0aGlzLnVybDtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBfQXBpSW5zdGFuY2VzMi5kZWZhdWx0Lmluc3RhbmNlKHVybCwgX2Nvbm5lY3QpLmluaXRfcHJvbWlzZS50aGVuKHJlc29sdmUpLmNhdGNoKGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBfQXBpSW5zdGFuY2VzMi5kZWZhdWx0Lmluc3RhbmNlKCkuY2xvc2UoKTtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIE1hbmFnZXIucHJvdG90eXBlLmNvbm5lY3RXaXRoRmFsbGJhY2sgPSBmdW5jdGlvbiBjb25uZWN0V2l0aEZhbGxiYWNrKCkge1xuICAgIHZhciBjb25uZWN0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB0cnVlO1xuICAgIHZhciB1cmwgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHRoaXMudXJsO1xuICAgIHZhciBpbmRleCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogMDtcblxuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgcmVzb2x2ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogbnVsbDtcbiAgICB2YXIgcmVqZWN0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDQgJiYgYXJndW1lbnRzWzRdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbNF0gOiBudWxsO1xuXG4gICAgaWYgKHJlamVjdCAmJiBpbmRleCA+IHRoaXMudXJscy5sZW5ndGggLSAxKSB7XG4gICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignVHJpZWQgJyArIChpbmRleCArIDEpICsgJyBjb25uZWN0aW9ucywgbm9uZSBvZiB3aGljaCB3b3JrZWQ6ICcgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnVybHMuY29uY2F0KHRoaXMudXJsKSkpKTtcbiAgICB9XG5cbiAgICB2YXIgZmFsbGJhY2sgPSBmdW5jdGlvbiBmYWxsYmFjayhyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIF90aGlzLmxvZ0ZhaWx1cmUodXJsKTtcbiAgICAgIHJldHVybiBfdGhpcy5jb25uZWN0V2l0aEZhbGxiYWNrKGNvbm5lY3QsIF90aGlzLnVybHNbaW5kZXhdLCBpbmRleCArIDEsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgfTtcblxuICAgIGlmIChyZXNvbHZlICYmIHJlamVjdCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdChjb25uZWN0LCB1cmwpLnRoZW4ocmVzb2x2ZSkuY2F0Y2goZnVuY3Rpb24gKCkge1xuICAgICAgICBmYWxsYmFjayhyZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIF90aGlzLmNvbm5lY3QoY29ubmVjdCkudGhlbihyZXNvbHZlKS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZhbGxiYWNrKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBNYW5hZ2VyLnByb3RvdHlwZS5jaGVja0Nvbm5lY3Rpb25zID0gZnVuY3Rpb24gY2hlY2tDb25uZWN0aW9ucygpIHtcbiAgICB2YXIgcnBjX3VzZXIgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6ICcnO1xuICAgIHZhciBycGNfcGFzc3dvcmQgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6ICcnO1xuXG4gICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICB2YXIgcmVzb2x2ZSA9IGFyZ3VtZW50c1syXTtcbiAgICB2YXIgcmVqZWN0ID0gYXJndW1lbnRzWzNdO1xuXG4gICAgdmFyIGNvbm5lY3Rpb25TdGFydFRpbWVzID0ge307XG5cbiAgICB2YXIgY2hlY2tGdW5jdGlvbiA9IGZ1bmN0aW9uIGNoZWNrRnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgZnVsbExpc3QgPSBfdGhpczIudXJscy5jb25jYXQoX3RoaXMyLnVybCk7XG4gICAgICB2YXIgY29ubmVjdGlvblByb21pc2VzID0gW107XG5cbiAgICAgIGZ1bGxMaXN0LmZvckVhY2goZnVuY3Rpb24gKHVybCkge1xuICAgICAgICB2YXIgY29ubiA9IG5ldyBfQ2hhaW5XZWJTb2NrZXQyLmRlZmF1bHQodXJsLCBmdW5jdGlvbiAoKSB7fSk7XG4gICAgICAgIGNvbm5lY3Rpb25TdGFydFRpbWVzW3VybF0gPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgY29ubmVjdGlvblByb21pc2VzLnB1c2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBjb25uLmxvZ2luKHJwY191c2VyLCBycGNfcGFzc3dvcmQpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIF9yZWYyO1xuXG4gICAgICAgICAgICBjb25uLmNsb3NlKCk7XG4gICAgICAgICAgICByZXR1cm4gX3JlZjIgPSB7fSwgX3JlZjJbdXJsXSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gY29ubmVjdGlvblN0YXJ0VGltZXNbdXJsXSwgX3JlZjI7XG4gICAgICAgICAgfSkuY2F0Y2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHVybCA9PT0gX3RoaXMyLnVybCkge1xuICAgICAgICAgICAgICBfdGhpczIudXJsID0gX3RoaXMyLnVybHNbMF07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBfdGhpczIudXJscyA9IF90aGlzMi51cmxzLmZpbHRlcihmdW5jdGlvbiAoYSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhICE9PSB1cmw7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25uLmNsb3NlKCk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgUHJvbWlzZS5hbGwoY29ubmVjdGlvblByb21pc2VzLm1hcChmdW5jdGlvbiAoYSkge1xuICAgICAgICByZXR1cm4gYSgpO1xuICAgICAgfSkpLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICByZXNvbHZlKHJlcy5maWx0ZXIoZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICByZXR1cm4gISFhO1xuICAgICAgICB9KS5yZWR1Y2UoZnVuY3Rpb24gKGYsIGEpIHtcbiAgICAgICAgICB2YXIga2V5ID0gT2JqZWN0LmtleXMoYSlbMF07XG4gICAgICAgICAgZltrZXldID0gYVtrZXldO1xuICAgICAgICAgIHJldHVybiBmO1xuICAgICAgICB9LCB7fSkpO1xuICAgICAgfSkuY2F0Y2goZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gX3RoaXMyLmNoZWNrQ29ubmVjdGlvbnMocnBjX3VzZXIsIHJwY19wYXNzd29yZCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBpZiAocmVzb2x2ZSAmJiByZWplY3QpIHtcbiAgICAgIGNoZWNrRnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGNoZWNrRnVuY3Rpb24pO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gTWFuYWdlcjtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gTWFuYWdlcjsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBHcmFwaGVuZUFwaSA9IGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gR3JhcGhlbmVBcGkod3NfcnBjLCBhcGlfbmFtZSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBHcmFwaGVuZUFwaSk7XG5cbiAgICB0aGlzLndzX3JwYyA9IHdzX3JwYztcbiAgICB0aGlzLmFwaV9uYW1lID0gYXBpX25hbWU7XG4gIH1cblxuICBHcmFwaGVuZUFwaS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uIGluaXQoKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHJldHVybiB0aGlzLndzX3JwYy5jYWxsKFsxLCB0aGlzLmFwaV9uYW1lLCBbXV0pLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICBfdGhpcy5hcGlfaWQgPSByZXNwb25zZTtcbiAgICAgIHJldHVybiBfdGhpcztcbiAgICB9KTtcbiAgfTtcblxuICBHcmFwaGVuZUFwaS5wcm90b3R5cGUuZXhlYyA9IGZ1bmN0aW9uIGV4ZWMobWV0aG9kLCBwYXJhbXMpIHtcbiAgICByZXR1cm4gdGhpcy53c19ycGMuY2FsbChbdGhpcy5hcGlfaWQsIG1ldGhvZCwgcGFyYW1zXSkuY2F0Y2goZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmxvZygnISEhIEdyYXBoZW5lQXBpIGVycm9yOiAnLCBtZXRob2QsIHBhcmFtcywgZXJyb3IsIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gR3JhcGhlbmVBcGk7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEdyYXBoZW5lQXBpOyIsIid1c2Ugc3RyaWN0JztcblxuaWYgKCFwcm9jZXNzLnZlcnNpb24gfHxcbiAgICBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjAuJykgPT09IDAgfHxcbiAgICBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuJykgPT09IDAgJiYgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YxLjguJykgIT09IDApIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSB7IG5leHRUaWNrOiBuZXh0VGljayB9O1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBwcm9jZXNzXG59XG5cbmZ1bmN0aW9uIG5leHRUaWNrKGZuLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImNhbGxiYWNrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cbiAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBhcmdzLCBpO1xuICBzd2l0Y2ggKGxlbikge1xuICBjYXNlIDA6XG4gIGNhc2UgMTpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmbik7XG4gIGNhc2UgMjpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tPbmUoKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEpO1xuICAgIH0pO1xuICBjYXNlIDM6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVHdvKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyKTtcbiAgICB9KTtcbiAgY2FzZSA0OlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1RocmVlKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgICB9KTtcbiAgZGVmYXVsdDpcbiAgICBhcmdzID0gbmV3IEFycmF5KGxlbiAtIDEpO1xuICAgIGkgPSAwO1xuICAgIHdoaWxlIChpIDwgYXJncy5sZW5ndGgpIHtcbiAgICAgIGFyZ3NbaSsrXSA9IGFyZ3VtZW50c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrKCkge1xuICAgICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgfSk7XG4gIH1cbn1cblxuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9kdXBsZXguanMnKTtcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBwbmEgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGtleXMucHVzaChrZXkpO1xuICB9cmV0dXJuIGtleXM7XG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbm1vZHVsZS5leHBvcnRzID0gRHVwbGV4O1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV9yZWFkYWJsZScpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3dyaXRhYmxlJyk7XG5cbnV0aWwuaW5oZXJpdHMoRHVwbGV4LCBSZWFkYWJsZSk7XG5cbntcbiAgLy8gYXZvaWQgc2NvcGUgY3JlZXAsIHRoZSBrZXlzIGFycmF5IGNhbiB0aGVuIGJlIGNvbGxlY3RlZFxuICB2YXIga2V5cyA9IG9iamVjdEtleXMoV3JpdGFibGUucHJvdG90eXBlKTtcbiAgZm9yICh2YXIgdiA9IDA7IHYgPCBrZXlzLmxlbmd0aDsgdisrKSB7XG4gICAgdmFyIG1ldGhvZCA9IGtleXNbdl07XG4gICAgaWYgKCFEdXBsZXgucHJvdG90eXBlW21ldGhvZF0pIER1cGxleC5wcm90b3R5cGVbbWV0aG9kXSA9IFdyaXRhYmxlLnByb3RvdHlwZVttZXRob2RdO1xuICB9XG59XG5cbmZ1bmN0aW9uIER1cGxleChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKSByZXR1cm4gbmV3IER1cGxleChvcHRpb25zKTtcblxuICBSZWFkYWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBXcml0YWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucmVhZGFibGUgPT09IGZhbHNlKSB0aGlzLnJlYWRhYmxlID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy53cml0YWJsZSA9PT0gZmFsc2UpIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcblxuICB0aGlzLmFsbG93SGFsZk9wZW4gPSB0cnVlO1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmFsbG93SGFsZk9wZW4gPT09IGZhbHNlKSB0aGlzLmFsbG93SGFsZk9wZW4gPSBmYWxzZTtcblxuICB0aGlzLm9uY2UoJ2VuZCcsIG9uZW5kKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KER1cGxleC5wcm90b3R5cGUsICd3cml0YWJsZUhpZ2hXYXRlck1hcmsnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl93cml0YWJsZVN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIH1cbn0pO1xuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gaWYgd2UgYWxsb3cgaGFsZi1vcGVuIHN0YXRlLCBvciBpZiB0aGUgd3JpdGFibGUgc2lkZSBlbmRlZCxcbiAgLy8gdGhlbiB3ZSdyZSBvay5cbiAgaWYgKHRoaXMuYWxsb3dIYWxmT3BlbiB8fCB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKSByZXR1cm47XG5cbiAgLy8gbm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuLlxuICAvLyBCdXQgYWxsb3cgbW9yZSB3cml0ZXMgdG8gaGFwcGVuIGluIHRoaXMgdGljay5cbiAgcG5hLm5leHRUaWNrKG9uRW5kTlQsIHRoaXMpO1xufVxuXG5mdW5jdGlvbiBvbkVuZE5UKHNlbGYpIHtcbiAgc2VsZi5lbmQoKTtcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KER1cGxleC5wcm90b3R5cGUsICdkZXN0cm95ZWQnLCB7XG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlID09PSB1bmRlZmluZWQgfHwgdGhpcy5fd3JpdGFibGVTdGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlc3Ryb3llZCAmJiB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZDtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAvLyB3ZSBpZ25vcmUgdGhlIHZhbHVlIGlmIHRoZSBzdHJlYW1cbiAgICAvLyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0XG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCB8fCB0aGlzLl93cml0YWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB0aGUgdXNlciBpcyBleHBsaWNpdGx5XG4gICAgLy8gbWFuYWdpbmcgZGVzdHJveWVkXG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB2YWx1ZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTtcblxuRHVwbGV4LnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIChlcnIsIGNiKSB7XG4gIHRoaXMucHVzaChudWxsKTtcbiAgdGhpcy5lbmQoKTtcblxuICBwbmEubmV4dFRpY2soY2IsIGVycik7XG59OyIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIHBhc3N0aHJvdWdoIHN0cmVhbS5cbi8vIGJhc2ljYWxseSBqdXN0IHRoZSBtb3N0IG1pbmltYWwgc29ydCBvZiBUcmFuc2Zvcm0gc3RyZWFtLlxuLy8gRXZlcnkgd3JpdHRlbiBjaHVuayBnZXRzIG91dHB1dCBhcy1pcy5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhc3NUaHJvdWdoO1xuXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnLi9fc3RyZWFtX3RyYW5zZm9ybScpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoUGFzc1Rocm91Z2gsIFRyYW5zZm9ybSk7XG5cbmZ1bmN0aW9uIFBhc3NUaHJvdWdoKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFBhc3NUaHJvdWdoKSkgcmV0dXJuIG5ldyBQYXNzVGhyb3VnaChvcHRpb25zKTtcblxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBvcHRpb25zKTtcbn1cblxuUGFzc1Rocm91Z2gucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihudWxsLCBjaHVuayk7XG59OyIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBwbmEgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbm1vZHVsZS5leHBvcnRzID0gUmVhZGFibGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIER1cGxleDtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5SZWFkYWJsZS5SZWFkYWJsZVN0YXRlID0gUmVhZGFibGVTdGF0ZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcblxudmFyIEVFbGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uIChlbWl0dGVyLCB0eXBlKSB7XG4gIHJldHVybiBlbWl0dGVyLmxpc3RlbmVycyh0eXBlKS5sZW5ndGg7XG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgU3RyZWFtID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL3N0cmVhbScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlcjtcbnZhciBPdXJVaW50OEFycmF5ID0gZ2xvYmFsLlVpbnQ4QXJyYXkgfHwgZnVuY3Rpb24gKCkge307XG5mdW5jdGlvbiBfdWludDhBcnJheVRvQnVmZmVyKGNodW5rKSB7XG4gIHJldHVybiBCdWZmZXIuZnJvbShjaHVuayk7XG59XG5mdW5jdGlvbiBfaXNVaW50OEFycmF5KG9iaikge1xuICByZXR1cm4gQnVmZmVyLmlzQnVmZmVyKG9iaikgfHwgb2JqIGluc3RhbmNlb2YgT3VyVWludDhBcnJheTtcbn1cblxuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBkZWJ1Z1V0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgZGVidWcgPSB2b2lkIDA7XG5pZiAoZGVidWdVdGlsICYmIGRlYnVnVXRpbC5kZWJ1Z2xvZykge1xuICBkZWJ1ZyA9IGRlYnVnVXRpbC5kZWJ1Z2xvZygnc3RyZWFtJyk7XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9O1xufVxuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QnKTtcbnZhciBkZXN0cm95SW1wbCA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9kZXN0cm95Jyk7XG52YXIgU3RyaW5nRGVjb2RlcjtcblxudXRpbC5pbmhlcml0cyhSZWFkYWJsZSwgU3RyZWFtKTtcblxudmFyIGtQcm94eUV2ZW50cyA9IFsnZXJyb3InLCAnY2xvc2UnLCAnZGVzdHJveScsICdwYXVzZScsICdyZXN1bWUnXTtcblxuZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKGVtaXR0ZXIsIGV2ZW50LCBmbikge1xuICAvLyBTYWRseSB0aGlzIGlzIG5vdCBjYWNoZWFibGUgYXMgc29tZSBsaWJyYXJpZXMgYnVuZGxlIHRoZWlyIG93blxuICAvLyBldmVudCBlbWl0dGVyIGltcGxlbWVudGF0aW9uIHdpdGggdGhlbS5cbiAgaWYgKHR5cGVvZiBlbWl0dGVyLnByZXBlbmRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykgcmV0dXJuIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyKGV2ZW50LCBmbik7XG5cbiAgLy8gVGhpcyBpcyBhIGhhY2sgdG8gbWFrZSBzdXJlIHRoYXQgb3VyIGVycm9yIGhhbmRsZXIgaXMgYXR0YWNoZWQgYmVmb3JlIGFueVxuICAvLyB1c2VybGFuZCBvbmVzLiAgTkVWRVIgRE8gVEhJUy4gVGhpcyBpcyBoZXJlIG9ubHkgYmVjYXVzZSB0aGlzIGNvZGUgbmVlZHNcbiAgLy8gdG8gY29udGludWUgdG8gd29yayB3aXRoIG9sZGVyIHZlcnNpb25zIG9mIE5vZGUuanMgdGhhdCBkbyBub3QgaW5jbHVkZVxuICAvLyB0aGUgcHJlcGVuZExpc3RlbmVyKCkgbWV0aG9kLiBUaGUgZ29hbCBpcyB0byBldmVudHVhbGx5IHJlbW92ZSB0aGlzIGhhY2suXG4gIGlmICghZW1pdHRlci5fZXZlbnRzIHx8ICFlbWl0dGVyLl9ldmVudHNbZXZlbnRdKSBlbWl0dGVyLm9uKGV2ZW50LCBmbik7ZWxzZSBpZiAoaXNBcnJheShlbWl0dGVyLl9ldmVudHNbZXZlbnRdKSkgZW1pdHRlci5fZXZlbnRzW2V2ZW50XS51bnNoaWZ0KGZuKTtlbHNlIGVtaXR0ZXIuX2V2ZW50c1tldmVudF0gPSBbZm4sIGVtaXR0ZXIuX2V2ZW50c1tldmVudF1dO1xufVxuXG5mdW5jdGlvbiBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIER1cGxleCBzdHJlYW1zIGFyZSBib3RoIHJlYWRhYmxlIGFuZCB3cml0YWJsZSwgYnV0IHNoYXJlXG4gIC8vIHRoZSBzYW1lIG9wdGlvbnMgb2JqZWN0LlxuICAvLyBIb3dldmVyLCBzb21lIGNhc2VzIHJlcXVpcmUgc2V0dGluZyBvcHRpb25zIHRvIGRpZmZlcmVudFxuICAvLyB2YWx1ZXMgZm9yIHRoZSByZWFkYWJsZSBhbmQgdGhlIHdyaXRhYmxlIHNpZGVzIG9mIHRoZSBkdXBsZXggc3RyZWFtLlxuICAvLyBUaGVzZSBvcHRpb25zIGNhbiBiZSBwcm92aWRlZCBzZXBhcmF0ZWx5IGFzIHJlYWRhYmxlWFhYIGFuZCB3cml0YWJsZVhYWC5cbiAgdmFyIGlzRHVwbGV4ID0gc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZy4gVXNlZCB0byBtYWtlIHJlYWQobikgaWdub3JlIG4gYW5kIHRvXG4gIC8vIG1ha2UgYWxsIHRoZSBidWZmZXIgbWVyZ2luZyBhbmQgbGVuZ3RoIGNoZWNrcyBnbyBhd2F5XG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChpc0R1cGxleCkgdGhpcy5vYmplY3RNb2RlID0gdGhpcy5vYmplY3RNb2RlIHx8ICEhb3B0aW9ucy5yZWFkYWJsZU9iamVjdE1vZGU7XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIGl0IHN0b3BzIGNhbGxpbmcgX3JlYWQoKSB0byBmaWxsIHRoZSBidWZmZXJcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyBcImRvbid0IGNhbGwgX3JlYWQgcHJlZW1wdGl2ZWx5IGV2ZXJcIlxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB2YXIgcmVhZGFibGVId20gPSBvcHRpb25zLnJlYWRhYmxlSGlnaFdhdGVyTWFyaztcbiAgdmFyIGRlZmF1bHRId20gPSB0aGlzLm9iamVjdE1vZGUgPyAxNiA6IDE2ICogMTAyNDtcblxuICBpZiAoaHdtIHx8IGh3bSA9PT0gMCkgdGhpcy5oaWdoV2F0ZXJNYXJrID0gaHdtO2Vsc2UgaWYgKGlzRHVwbGV4ICYmIChyZWFkYWJsZUh3bSB8fCByZWFkYWJsZUh3bSA9PT0gMCkpIHRoaXMuaGlnaFdhdGVyTWFyayA9IHJlYWRhYmxlSHdtO2Vsc2UgdGhpcy5oaWdoV2F0ZXJNYXJrID0gZGVmYXVsdEh3bTtcblxuICAvLyBjYXN0IHRvIGludHMuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IE1hdGguZmxvb3IodGhpcy5oaWdoV2F0ZXJNYXJrKTtcblxuICAvLyBBIGxpbmtlZCBsaXN0IGlzIHVzZWQgdG8gc3RvcmUgZGF0YSBjaHVua3MgaW5zdGVhZCBvZiBhbiBhcnJheSBiZWNhdXNlIHRoZVxuICAvLyBsaW5rZWQgbGlzdCBjYW4gcmVtb3ZlIGVsZW1lbnRzIGZyb20gdGhlIGJlZ2lubmluZyBmYXN0ZXIgdGhhblxuICAvLyBhcnJheS5zaGlmdCgpXG4gIHRoaXMuYnVmZmVyID0gbmV3IEJ1ZmZlckxpc3QoKTtcbiAgdGhpcy5sZW5ndGggPSAwO1xuICB0aGlzLnBpcGVzID0gbnVsbDtcbiAgdGhpcy5waXBlc0NvdW50ID0gMDtcbiAgdGhpcy5mbG93aW5nID0gbnVsbDtcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICB0aGlzLmVuZEVtaXR0ZWQgPSBmYWxzZTtcbiAgdGhpcy5yZWFkaW5nID0gZmFsc2U7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgZXZlbnQgJ3JlYWRhYmxlJy8nZGF0YScgaXMgZW1pdHRlZFxuICAvLyBpbW1lZGlhdGVseSwgb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZVxuICAvLyBhbnkgYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3QgcmVhZCBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIHdoZW5ldmVyIHdlIHJldHVybiBudWxsLCB0aGVuIHdlIHNldCBhIGZsYWcgdG8gc2F5XG4gIC8vIHRoYXQgd2UncmUgYXdhaXRpbmcgYSAncmVhZGFibGUnIGV2ZW50IGVtaXNzaW9uLlxuICB0aGlzLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlTGlzdGVuaW5nID0gZmFsc2U7XG4gIHRoaXMucmVzdW1lU2NoZWR1bGVkID0gZmFsc2U7XG5cbiAgLy8gaGFzIGl0IGJlZW4gZGVzdHJveWVkXG4gIHRoaXMuZGVzdHJveWVkID0gZmFsc2U7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gdGhlIG51bWJlciBvZiB3cml0ZXJzIHRoYXQgYXJlIGF3YWl0aW5nIGEgZHJhaW4gZXZlbnQgaW4gLnBpcGUoKXNcbiAgdGhpcy5hd2FpdERyYWluID0gMDtcblxuICAvLyBpZiB0cnVlLCBhIG1heWJlUmVhZE1vcmUgaGFzIGJlZW4gc2NoZWR1bGVkXG4gIHRoaXMucmVhZGluZ01vcmUgPSBmYWxzZTtcblxuICB0aGlzLmRlY29kZXIgPSBudWxsO1xuICB0aGlzLmVuY29kaW5nID0gbnVsbDtcbiAgaWYgKG9wdGlvbnMuZW5jb2RpbmcpIHtcbiAgICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICAgIHRoaXMuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKG9wdGlvbnMuZW5jb2RpbmcpO1xuICAgIHRoaXMuZW5jb2RpbmcgPSBvcHRpb25zLmVuY29kaW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIFJlYWRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKSByZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSBuZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3lcbiAgdGhpcy5yZWFkYWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMucmVhZCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fcmVhZCA9IG9wdGlvbnMucmVhZDtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSB0aGlzLl9kZXN0cm95ID0gb3B0aW9ucy5kZXN0cm95O1xuICB9XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZS5wcm90b3R5cGUsICdkZXN0cm95ZWQnLCB7XG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIC8vIHdlIGlnbm9yZSB0aGUgdmFsdWUgaWYgdGhlIHN0cmVhbVxuICAgIC8vIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCB5ZXRcbiAgICBpZiAoIXRoaXMuX3JlYWRhYmxlU3RhdGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB0aGUgdXNlciBpcyBleHBsaWNpdGx5XG4gICAgLy8gbWFuYWdpbmcgZGVzdHJveWVkXG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB2YWx1ZTtcbiAgfVxufSk7XG5cblJlYWRhYmxlLnByb3RvdHlwZS5kZXN0cm95ID0gZGVzdHJveUltcGwuZGVzdHJveTtcblJlYWRhYmxlLnByb3RvdHlwZS5fdW5kZXN0cm95ID0gZGVzdHJveUltcGwudW5kZXN0cm95O1xuUmVhZGFibGUucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKGVyciwgY2IpIHtcbiAgdGhpcy5wdXNoKG51bGwpO1xuICBjYihlcnIpO1xufTtcblxuLy8gTWFudWFsbHkgc2hvdmUgc29tZXRoaW5nIGludG8gdGhlIHJlYWQoKSBidWZmZXIuXG4vLyBUaGlzIHJldHVybnMgdHJ1ZSBpZiB0aGUgaGlnaFdhdGVyTWFyayBoYXMgbm90IGJlZW4gaGl0IHlldCxcbi8vIHNpbWlsYXIgdG8gaG93IFdyaXRhYmxlLndyaXRlKCkgcmV0dXJucyB0cnVlIGlmIHlvdSBzaG91bGRcbi8vIHdyaXRlKCkgc29tZSBtb3JlLlxuUmVhZGFibGUucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBza2lwQ2h1bmtDaGVjaztcblxuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBpZiAodHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBlbmNvZGluZyB8fCBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG4gICAgICBpZiAoZW5jb2RpbmcgIT09IHN0YXRlLmVuY29kaW5nKSB7XG4gICAgICAgIGNodW5rID0gQnVmZmVyLmZyb20oY2h1bmssIGVuY29kaW5nKTtcbiAgICAgICAgZW5jb2RpbmcgPSAnJztcbiAgICAgIH1cbiAgICAgIHNraXBDaHVua0NoZWNrID0gdHJ1ZTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc2tpcENodW5rQ2hlY2sgPSB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgY2h1bmssIGVuY29kaW5nLCBmYWxzZSwgc2tpcENodW5rQ2hlY2spO1xufTtcblxuLy8gVW5zaGlmdCBzaG91bGQgKmFsd2F5cyogYmUgc29tZXRoaW5nIGRpcmVjdGx5IG91dCBvZiByZWFkKClcblJlYWRhYmxlLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIGNodW5rLCBudWxsLCB0cnVlLCBmYWxzZSk7XG59O1xuXG5mdW5jdGlvbiByZWFkYWJsZUFkZENodW5rKHN0cmVhbSwgY2h1bmssIGVuY29kaW5nLCBhZGRUb0Zyb250LCBza2lwQ2h1bmtDaGVjaykge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpO1xuICB9IGVsc2Uge1xuICAgIHZhciBlcjtcbiAgICBpZiAoIXNraXBDaHVua0NoZWNrKSBlciA9IGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspO1xuICAgIGlmIChlcikge1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUub2JqZWN0TW9kZSB8fCBjaHVuayAmJiBjaHVuay5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAodHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiAhc3RhdGUub2JqZWN0TW9kZSAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY2h1bmspICE9PSBCdWZmZXIucHJvdG90eXBlKSB7XG4gICAgICAgIGNodW5rID0gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuayk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhZGRUb0Zyb250KSB7XG4gICAgICAgIGlmIChzdGF0ZS5lbmRFbWl0dGVkKSBzdHJlYW0uZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ3N0cmVhbS51bnNoaWZ0KCkgYWZ0ZXIgZW5kIGV2ZW50JykpO2Vsc2UgYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIHRydWUpO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5lbmRlZCkge1xuICAgICAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ3N0cmVhbS5wdXNoKCkgYWZ0ZXIgRU9GJykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhZW5jb2RpbmcpIHtcbiAgICAgICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuICAgICAgICAgIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rLmxlbmd0aCAhPT0gMCkgYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGZhbHNlKTtlbHNlIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWFkZFRvRnJvbnQpIHtcbiAgICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmVlZE1vcmVEYXRhKHN0YXRlKTtcbn1cblxuZnVuY3Rpb24gYWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGFkZFRvRnJvbnQpIHtcbiAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5zeW5jKSB7XG4gICAgc3RyZWFtLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gdXBkYXRlIHRoZSBidWZmZXIgaW5mby5cbiAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgaWYgKGFkZFRvRnJvbnQpIHN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcblxuICAgIGlmIChzdGF0ZS5uZWVkUmVhZGFibGUpIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuICB9XG4gIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbmZ1bmN0aW9uIGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspIHtcbiAgdmFyIGVyO1xuICBpZiAoIV9pc1VpbnQ4QXJyYXkoY2h1bmspICYmIHR5cGVvZiBjaHVuayAhPT0gJ3N0cmluZycgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCAmJiAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGVyID0gbmV3IFR5cGVFcnJvcignSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVuaycpO1xuICB9XG4gIHJldHVybiBlcjtcbn1cblxuLy8gaWYgaXQncyBwYXN0IHRoZSBoaWdoIHdhdGVyIG1hcmssIHdlIGNhbiBwdXNoIGluIHNvbWUgbW9yZS5cbi8vIEFsc28sIGlmIHdlIGhhdmUgbm8gZGF0YSB5ZXQsIHdlIGNhbiBzdGFuZCBzb21lXG4vLyBtb3JlIGJ5dGVzLiAgVGhpcyBpcyB0byB3b3JrIGFyb3VuZCBjYXNlcyB3aGVyZSBod209MCxcbi8vIHN1Y2ggYXMgdGhlIHJlcGwuICBBbHNvLCBpZiB0aGUgcHVzaCgpIHRyaWdnZXJlZCBhXG4vLyByZWFkYWJsZSBldmVudCwgYW5kIHRoZSB1c2VyIGNhbGxlZCByZWFkKGxhcmdlTnVtYmVyKSBzdWNoIHRoYXRcbi8vIG5lZWRSZWFkYWJsZSB3YXMgc2V0LCB0aGVuIHdlIG91Z2h0IHRvIHB1c2ggbW9yZSwgc28gdGhhdCBhbm90aGVyXG4vLyAncmVhZGFibGUnIGV2ZW50IHdpbGwgYmUgdHJpZ2dlcmVkLlxuZnVuY3Rpb24gbmVlZE1vcmVEYXRhKHN0YXRlKSB7XG4gIHJldHVybiAhc3RhdGUuZW5kZWQgJiYgKHN0YXRlLm5lZWRSZWFkYWJsZSB8fCBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmxlbmd0aCA9PT0gMCk7XG59XG5cblJlYWRhYmxlLnByb3RvdHlwZS5pc1BhdXNlZCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyA9PT0gZmFsc2U7XG59O1xuXG4vLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cblJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZyA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKTtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZyA9IGVuYztcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBEb24ndCByYWlzZSB0aGUgaHdtID4gOE1CXG52YXIgTUFYX0hXTSA9IDB4ODAwMDAwO1xuZnVuY3Rpb24gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobikge1xuICBpZiAobiA+PSBNQVhfSFdNKSB7XG4gICAgbiA9IE1BWF9IV007XG4gIH0gZWxzZSB7XG4gICAgLy8gR2V0IHRoZSBuZXh0IGhpZ2hlc3QgcG93ZXIgb2YgMiB0byBwcmV2ZW50IGluY3JlYXNpbmcgaHdtIGV4Y2Vzc2l2ZWx5IGluXG4gICAgLy8gdGlueSBhbW91bnRzXG4gICAgbi0tO1xuICAgIG4gfD0gbiA+Pj4gMTtcbiAgICBuIHw9IG4gPj4+IDI7XG4gICAgbiB8PSBuID4+PiA0O1xuICAgIG4gfD0gbiA+Pj4gODtcbiAgICBuIHw9IG4gPj4+IDE2O1xuICAgIG4rKztcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKSB7XG4gIGlmIChuIDw9IDAgfHwgc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSByZXR1cm4gMDtcbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpIHJldHVybiAxO1xuICBpZiAobiAhPT0gbikge1xuICAgIC8vIE9ubHkgZmxvdyBvbmUgYnVmZmVyIGF0IGEgdGltZVxuICAgIGlmIChzdGF0ZS5mbG93aW5nICYmIHN0YXRlLmxlbmd0aCkgcmV0dXJuIHN0YXRlLmJ1ZmZlci5oZWFkLmRhdGEubGVuZ3RoO2Vsc2UgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbiAgfVxuICAvLyBJZiB3ZSdyZSBhc2tpbmcgZm9yIG1vcmUgdGhhbiB0aGUgY3VycmVudCBod20sIHRoZW4gcmFpc2UgdGhlIGh3bS5cbiAgaWYgKG4gPiBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSBzdGF0ZS5oaWdoV2F0ZXJNYXJrID0gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobik7XG4gIGlmIChuIDw9IHN0YXRlLmxlbmd0aCkgcmV0dXJuIG47XG4gIC8vIERvbid0IGhhdmUgZW5vdWdoXG4gIGlmICghc3RhdGUuZW5kZWQpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIHJldHVybiAwO1xuICB9XG4gIHJldHVybiBzdGF0ZS5sZW5ndGg7XG59XG5cbi8vIHlvdSBjYW4gb3ZlcnJpZGUgZWl0aGVyIHRoaXMgbWV0aG9kLCBvciB0aGUgYXN5bmMgX3JlYWQobikgYmVsb3cuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIGRlYnVnKCdyZWFkJywgbik7XG4gIG4gPSBwYXJzZUludChuLCAxMCk7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBuT3JpZyA9IG47XG5cbiAgaWYgKG4gIT09IDApIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGlmIHdlJ3JlIGRvaW5nIHJlYWQoMCkgdG8gdHJpZ2dlciBhIHJlYWRhYmxlIGV2ZW50LCBidXQgd2VcbiAgLy8gYWxyZWFkeSBoYXZlIGEgYnVuY2ggb2YgZGF0YSBpbiB0aGUgYnVmZmVyLCB0aGVuIGp1c3QgdHJpZ2dlclxuICAvLyB0aGUgJ3JlYWRhYmxlJyBldmVudCBhbmQgbW92ZSBvbi5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUubmVlZFJlYWRhYmxlICYmIChzdGF0ZS5sZW5ndGggPj0gc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5lbmRlZCkpIHtcbiAgICBkZWJ1ZygncmVhZDogZW1pdFJlYWRhYmxlJywgc3RhdGUubGVuZ3RoLCBzdGF0ZS5lbmRlZCk7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7ZWxzZSBlbWl0UmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBuID0gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSk7XG5cbiAgLy8gaWYgd2UndmUgZW5kZWQsIGFuZCB3ZSdyZSBub3cgY2xlYXIsIHRoZW4gZmluaXNoIGl0IHVwLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkge1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIGVuZFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQWxsIHRoZSBhY3R1YWwgY2h1bmsgZ2VuZXJhdGlvbiBsb2dpYyBuZWVkcyB0byBiZVxuICAvLyAqYmVsb3cqIHRoZSBjYWxsIHRvIF9yZWFkLiAgVGhlIHJlYXNvbiBpcyB0aGF0IGluIGNlcnRhaW5cbiAgLy8gc3ludGhldGljIHN0cmVhbSBjYXNlcywgc3VjaCBhcyBwYXNzdGhyb3VnaCBzdHJlYW1zLCBfcmVhZFxuICAvLyBtYXkgYmUgYSBjb21wbGV0ZWx5IHN5bmNocm9ub3VzIG9wZXJhdGlvbiB3aGljaCBtYXkgY2hhbmdlXG4gIC8vIHRoZSBzdGF0ZSBvZiB0aGUgcmVhZCBidWZmZXIsIHByb3ZpZGluZyBlbm91Z2ggZGF0YSB3aGVuXG4gIC8vIGJlZm9yZSB0aGVyZSB3YXMgKm5vdCogZW5vdWdoLlxuICAvL1xuICAvLyBTbywgdGhlIHN0ZXBzIGFyZTpcbiAgLy8gMS4gRmlndXJlIG91dCB3aGF0IHRoZSBzdGF0ZSBvZiB0aGluZ3Mgd2lsbCBiZSBhZnRlciB3ZSBkb1xuICAvLyBhIHJlYWQgZnJvbSB0aGUgYnVmZmVyLlxuICAvL1xuICAvLyAyLiBJZiB0aGF0IHJlc3VsdGluZyBzdGF0ZSB3aWxsIHRyaWdnZXIgYSBfcmVhZCwgdGhlbiBjYWxsIF9yZWFkLlxuICAvLyBOb3RlIHRoYXQgdGhpcyBtYXkgYmUgYXN5bmNocm9ub3VzLCBvciBzeW5jaHJvbm91cy4gIFllcywgaXQgaXNcbiAgLy8gZGVlcGx5IHVnbHkgdG8gd3JpdGUgQVBJcyB0aGlzIHdheSwgYnV0IHRoYXQgc3RpbGwgZG9lc24ndCBtZWFuXG4gIC8vIHRoYXQgdGhlIFJlYWRhYmxlIGNsYXNzIHNob3VsZCBiZWhhdmUgaW1wcm9wZXJseSwgYXMgc3RyZWFtcyBhcmVcbiAgLy8gZGVzaWduZWQgdG8gYmUgc3luYy9hc3luYyBhZ25vc3RpYy5cbiAgLy8gVGFrZSBub3RlIGlmIHRoZSBfcmVhZCBjYWxsIGlzIHN5bmMgb3IgYXN5bmMgKGllLCBpZiB0aGUgcmVhZCBjYWxsXG4gIC8vIGhhcyByZXR1cm5lZCB5ZXQpLCBzbyB0aGF0IHdlIGtub3cgd2hldGhlciBvciBub3QgaXQncyBzYWZlIHRvIGVtaXRcbiAgLy8gJ3JlYWRhYmxlJyBldGMuXG4gIC8vXG4gIC8vIDMuIEFjdHVhbGx5IHB1bGwgdGhlIHJlcXVlc3RlZCBjaHVua3Mgb3V0IG9mIHRoZSBidWZmZXIgYW5kIHJldHVybi5cblxuICAvLyBpZiB3ZSBuZWVkIGEgcmVhZGFibGUgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byBkbyBzb21lIHJlYWRpbmcuXG4gIHZhciBkb1JlYWQgPSBzdGF0ZS5uZWVkUmVhZGFibGU7XG4gIGRlYnVnKCduZWVkIHJlYWRhYmxlJywgZG9SZWFkKTtcblxuICAvLyBpZiB3ZSBjdXJyZW50bHkgaGF2ZSBsZXNzIHRoYW4gdGhlIGhpZ2hXYXRlck1hcmssIHRoZW4gYWxzbyByZWFkIHNvbWVcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCB8fCBzdGF0ZS5sZW5ndGggLSBuIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRvUmVhZCA9IHRydWU7XG4gICAgZGVidWcoJ2xlbmd0aCBsZXNzIHRoYW4gd2F0ZXJtYXJrJywgZG9SZWFkKTtcbiAgfVxuXG4gIC8vIGhvd2V2ZXIsIGlmIHdlJ3ZlIGVuZGVkLCB0aGVuIHRoZXJlJ3Mgbm8gcG9pbnQsIGFuZCBpZiB3ZSdyZSBhbHJlYWR5XG4gIC8vIHJlYWRpbmcsIHRoZW4gaXQncyB1bm5lY2Vzc2FyeS5cbiAgaWYgKHN0YXRlLmVuZGVkIHx8IHN0YXRlLnJlYWRpbmcpIHtcbiAgICBkb1JlYWQgPSBmYWxzZTtcbiAgICBkZWJ1ZygncmVhZGluZyBvciBlbmRlZCcsIGRvUmVhZCk7XG4gIH0gZWxzZSBpZiAoZG9SZWFkKSB7XG4gICAgZGVidWcoJ2RvIHJlYWQnKTtcbiAgICBzdGF0ZS5yZWFkaW5nID0gdHJ1ZTtcbiAgICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgICAvLyBpZiB0aGUgbGVuZ3RoIGlzIGN1cnJlbnRseSB6ZXJvLCB0aGVuIHdlICpuZWVkKiBhIHJlYWRhYmxlIGV2ZW50LlxuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgLy8gY2FsbCBpbnRlcm5hbCByZWFkIG1ldGhvZFxuICAgIHRoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7XG4gICAgc3RhdGUuc3luYyA9IGZhbHNlO1xuICAgIC8vIElmIF9yZWFkIHB1c2hlZCBkYXRhIHN5bmNocm9ub3VzbHksIHRoZW4gYHJlYWRpbmdgIHdpbGwgYmUgZmFsc2UsXG4gICAgLy8gYW5kIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgaG93IG11Y2ggZGF0YSB3ZSBjYW4gcmV0dXJuIHRvIHRoZSB1c2VyLlxuICAgIGlmICghc3RhdGUucmVhZGluZykgbiA9IGhvd011Y2hUb1JlYWQobk9yaWcsIHN0YXRlKTtcbiAgfVxuXG4gIHZhciByZXQ7XG4gIGlmIChuID4gMCkgcmV0ID0gZnJvbUxpc3Qobiwgc3RhdGUpO2Vsc2UgcmV0ID0gbnVsbDtcblxuICBpZiAocmV0ID09PSBudWxsKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBuID0gMDtcbiAgfSBlbHNlIHtcbiAgICBzdGF0ZS5sZW5ndGggLT0gbjtcbiAgfVxuXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICAvLyBJZiB3ZSBoYXZlIG5vdGhpbmcgaW4gdGhlIGJ1ZmZlciwgdGhlbiB3ZSB3YW50IHRvIGtub3dcbiAgICAvLyBhcyBzb29uIGFzIHdlICpkbyogZ2V0IHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIuXG4gICAgaWYgKCFzdGF0ZS5lbmRlZCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAgIC8vIElmIHdlIHRyaWVkIHRvIHJlYWQoKSBwYXN0IHRoZSBFT0YsIHRoZW4gZW1pdCBlbmQgb24gdGhlIG5leHQgdGljay5cbiAgICBpZiAobk9yaWcgIT09IG4gJiYgc3RhdGUuZW5kZWQpIGVuZFJlYWRhYmxlKHRoaXMpO1xuICB9XG5cbiAgaWYgKHJldCAhPT0gbnVsbCkgdGhpcy5lbWl0KCdkYXRhJywgcmV0KTtcblxuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5lbmRlZCkgcmV0dXJuO1xuICBpZiAoc3RhdGUuZGVjb2Rlcikge1xuICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgc3RhdGUubGVuZ3RoICs9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgIH1cbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG5cbiAgLy8gZW1pdCAncmVhZGFibGUnIG5vdyB0byBtYWtlIHN1cmUgaXQgZ2V0cyBwaWNrZWQgdXAuXG4gIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xufVxuXG4vLyBEb24ndCBlbWl0IHJlYWRhYmxlIHJpZ2h0IGF3YXkgaW4gc3luYyBtb2RlLCBiZWNhdXNlIHRoaXMgY2FuIHRyaWdnZXJcbi8vIGFub3RoZXIgcmVhZCgpIGNhbGwgPT4gc3RhY2sgb3ZlcmZsb3cuICBUaGlzIHdheSwgaXQgbWlnaHQgdHJpZ2dlclxuLy8gYSBuZXh0VGljayByZWN1cnNpb24gd2FybmluZywgYnV0IHRoYXQncyBub3Qgc28gYmFkLlxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHN0YXRlLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICBpZiAoIXN0YXRlLmVtaXR0ZWRSZWFkYWJsZSkge1xuICAgIGRlYnVnKCdlbWl0UmVhZGFibGUnLCBzdGF0ZS5mbG93aW5nKTtcbiAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSB0cnVlO1xuICAgIGlmIChzdGF0ZS5zeW5jKSBwbmEubmV4dFRpY2soZW1pdFJlYWRhYmxlXywgc3RyZWFtKTtlbHNlIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGVfKHN0cmVhbSkge1xuICBkZWJ1ZygnZW1pdCByZWFkYWJsZScpO1xuICBzdHJlYW0uZW1pdCgncmVhZGFibGUnKTtcbiAgZmxvdyhzdHJlYW0pO1xufVxuXG4vLyBhdCB0aGlzIHBvaW50LCB0aGUgdXNlciBoYXMgcHJlc3VtYWJseSBzZWVuIHRoZSAncmVhZGFibGUnIGV2ZW50LFxuLy8gYW5kIGNhbGxlZCByZWFkKCkgdG8gY29uc3VtZSBzb21lIGRhdGEuICB0aGF0IG1heSBoYXZlIHRyaWdnZXJlZFxuLy8gaW4gdHVybiBhbm90aGVyIF9yZWFkKG4pIGNhbGwsIGluIHdoaWNoIGNhc2UgcmVhZGluZyA9IHRydWUgaWZcbi8vIGl0J3MgaW4gcHJvZ3Jlc3MuXG4vLyBIb3dldmVyLCBpZiB3ZSdyZSBub3QgZW5kZWQsIG9yIHJlYWRpbmcsIGFuZCB0aGUgbGVuZ3RoIDwgaHdtLFxuLy8gdGhlbiBnbyBhaGVhZCBhbmQgdHJ5IHRvIHJlYWQgc29tZSBtb3JlIHByZWVtcHRpdmVseS5cbmZ1bmN0aW9uIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoIXN0YXRlLnJlYWRpbmdNb3JlKSB7XG4gICAgc3RhdGUucmVhZGluZ01vcmUgPSB0cnVlO1xuICAgIHBuYS5uZXh0VGljayhtYXliZVJlYWRNb3JlXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB3aGlsZSAoIXN0YXRlLnJlYWRpbmcgJiYgIXN0YXRlLmZsb3dpbmcgJiYgIXN0YXRlLmVuZGVkICYmIHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmspIHtcbiAgICBkZWJ1ZygnbWF5YmVSZWFkTW9yZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgICBpZiAobGVuID09PSBzdGF0ZS5sZW5ndGgpXG4gICAgICAvLyBkaWRuJ3QgZ2V0IGFueSBkYXRhLCBzdG9wIHNwaW5uaW5nLlxuICAgICAgYnJlYWs7ZWxzZSBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIH1cbiAgc3RhdGUucmVhZGluZ01vcmUgPSBmYWxzZTtcbn1cblxuLy8gYWJzdHJhY3QgbWV0aG9kLiAgdG8gYmUgb3ZlcnJpZGRlbiBpbiBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gY2FsbCBjYihlciwgZGF0YSkgd2hlcmUgZGF0YSBpcyA8PSBuIGluIGxlbmd0aC5cbi8vIGZvciB2aXJ0dWFsIChub24tc3RyaW5nLCBub24tYnVmZmVyKSBzdHJlYW1zLCBcImxlbmd0aFwiIGlzIHNvbWV3aGF0XG4vLyBhcmJpdHJhcnksIGFuZCBwZXJoYXBzIG5vdCB2ZXJ5IG1lYW5pbmdmdWwuXG5SZWFkYWJsZS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdfcmVhZCgpIGlzIG5vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cblJlYWRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24gKGRlc3QsIHBpcGVPcHRzKSB7XG4gIHZhciBzcmMgPSB0aGlzO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIHN3aXRjaCAoc3RhdGUucGlwZXNDb3VudCkge1xuICAgIGNhc2UgMDpcbiAgICAgIHN0YXRlLnBpcGVzID0gZGVzdDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIHN0YXRlLnBpcGVzID0gW3N0YXRlLnBpcGVzLCBkZXN0XTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBzdGF0ZS5waXBlcy5wdXNoKGRlc3QpO1xuICAgICAgYnJlYWs7XG4gIH1cbiAgc3RhdGUucGlwZXNDb3VudCArPSAxO1xuICBkZWJ1ZygncGlwZSBjb3VudD0lZCBvcHRzPSVqJywgc3RhdGUucGlwZXNDb3VudCwgcGlwZU9wdHMpO1xuXG4gIHZhciBkb0VuZCA9ICghcGlwZU9wdHMgfHwgcGlwZU9wdHMuZW5kICE9PSBmYWxzZSkgJiYgZGVzdCAhPT0gcHJvY2Vzcy5zdGRvdXQgJiYgZGVzdCAhPT0gcHJvY2Vzcy5zdGRlcnI7XG5cbiAgdmFyIGVuZEZuID0gZG9FbmQgPyBvbmVuZCA6IHVucGlwZTtcbiAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIHBuYS5uZXh0VGljayhlbmRGbik7ZWxzZSBzcmMub25jZSgnZW5kJywgZW5kRm4pO1xuXG4gIGRlc3Qub24oJ3VucGlwZScsIG9udW5waXBlKTtcbiAgZnVuY3Rpb24gb251bnBpcGUocmVhZGFibGUsIHVucGlwZUluZm8pIHtcbiAgICBkZWJ1Zygnb251bnBpcGUnKTtcbiAgICBpZiAocmVhZGFibGUgPT09IHNyYykge1xuICAgICAgaWYgKHVucGlwZUluZm8gJiYgdW5waXBlSW5mby5oYXNVbnBpcGVkID09PSBmYWxzZSkge1xuICAgICAgICB1bnBpcGVJbmZvLmhhc1VucGlwZWQgPSB0cnVlO1xuICAgICAgICBjbGVhbnVwKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgZGVidWcoJ29uZW5kJyk7XG4gICAgZGVzdC5lbmQoKTtcbiAgfVxuXG4gIC8vIHdoZW4gdGhlIGRlc3QgZHJhaW5zLCBpdCByZWR1Y2VzIHRoZSBhd2FpdERyYWluIGNvdW50ZXJcbiAgLy8gb24gdGhlIHNvdXJjZS4gIFRoaXMgd291bGQgYmUgbW9yZSBlbGVnYW50IHdpdGggYSAub25jZSgpXG4gIC8vIGhhbmRsZXIgaW4gZmxvdygpLCBidXQgYWRkaW5nIGFuZCByZW1vdmluZyByZXBlYXRlZGx5IGlzXG4gIC8vIHRvbyBzbG93LlxuICB2YXIgb25kcmFpbiA9IHBpcGVPbkRyYWluKHNyYyk7XG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgdmFyIGNsZWFuZWRVcCA9IGZhbHNlO1xuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIGRlYnVnKCdjbGVhbnVwJyk7XG4gICAgLy8gY2xlYW51cCBldmVudCBoYW5kbGVycyBvbmNlIHRoZSBwaXBlIGlzIGJyb2tlblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCB1bnBpcGUpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG5cbiAgICBjbGVhbmVkVXAgPSB0cnVlO1xuXG4gICAgLy8gaWYgdGhlIHJlYWRlciBpcyB3YWl0aW5nIGZvciBhIGRyYWluIGV2ZW50IGZyb20gdGhpc1xuICAgIC8vIHNwZWNpZmljIHdyaXRlciwgdGhlbiBpdCB3b3VsZCBjYXVzZSBpdCB0byBuZXZlciBzdGFydFxuICAgIC8vIGZsb3dpbmcgYWdhaW4uXG4gICAgLy8gU28sIGlmIHRoaXMgaXMgYXdhaXRpbmcgYSBkcmFpbiwgdGhlbiB3ZSBqdXN0IGNhbGwgaXQgbm93LlxuICAgIC8vIElmIHdlIGRvbid0IGtub3csIHRoZW4gYXNzdW1lIHRoYXQgd2UgYXJlIHdhaXRpbmcgZm9yIG9uZS5cbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiAmJiAoIWRlc3QuX3dyaXRhYmxlU3RhdGUgfHwgZGVzdC5fd3JpdGFibGVTdGF0ZS5uZWVkRHJhaW4pKSBvbmRyYWluKCk7XG4gIH1cblxuICAvLyBJZiB0aGUgdXNlciBwdXNoZXMgbW9yZSBkYXRhIHdoaWxlIHdlJ3JlIHdyaXRpbmcgdG8gZGVzdCB0aGVuIHdlJ2xsIGVuZCB1cFxuICAvLyBpbiBvbmRhdGEgYWdhaW4uIEhvd2V2ZXIsIHdlIG9ubHkgd2FudCB0byBpbmNyZWFzZSBhd2FpdERyYWluIG9uY2UgYmVjYXVzZVxuICAvLyBkZXN0IHdpbGwgb25seSBlbWl0IG9uZSAnZHJhaW4nIGV2ZW50IGZvciB0aGUgbXVsdGlwbGUgd3JpdGVzLlxuICAvLyA9PiBJbnRyb2R1Y2UgYSBndWFyZCBvbiBpbmNyZWFzaW5nIGF3YWl0RHJhaW4uXG4gIHZhciBpbmNyZWFzZWRBd2FpdERyYWluID0gZmFsc2U7XG4gIHNyYy5vbignZGF0YScsIG9uZGF0YSk7XG4gIGZ1bmN0aW9uIG9uZGF0YShjaHVuaykge1xuICAgIGRlYnVnKCdvbmRhdGEnKTtcbiAgICBpbmNyZWFzZWRBd2FpdERyYWluID0gZmFsc2U7XG4gICAgdmFyIHJldCA9IGRlc3Qud3JpdGUoY2h1bmspO1xuICAgIGlmIChmYWxzZSA9PT0gcmV0ICYmICFpbmNyZWFzZWRBd2FpdERyYWluKSB7XG4gICAgICAvLyBJZiB0aGUgdXNlciB1bnBpcGVkIGR1cmluZyBgZGVzdC53cml0ZSgpYCwgaXQgaXMgcG9zc2libGVcbiAgICAgIC8vIHRvIGdldCBzdHVjayBpbiBhIHBlcm1hbmVudGx5IHBhdXNlZCBzdGF0ZSBpZiB0aGF0IHdyaXRlXG4gICAgICAvLyBhbHNvIHJldHVybmVkIGZhbHNlLlxuICAgICAgLy8gPT4gQ2hlY2sgd2hldGhlciBgZGVzdGAgaXMgc3RpbGwgYSBwaXBpbmcgZGVzdGluYXRpb24uXG4gICAgICBpZiAoKHN0YXRlLnBpcGVzQ291bnQgPT09IDEgJiYgc3RhdGUucGlwZXMgPT09IGRlc3QgfHwgc3RhdGUucGlwZXNDb3VudCA+IDEgJiYgaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCkgIT09IC0xKSAmJiAhY2xlYW5lZFVwKSB7XG4gICAgICAgIGRlYnVnKCdmYWxzZSB3cml0ZSByZXNwb25zZSwgcGF1c2UnLCBzcmMuX3JlYWRhYmxlU3RhdGUuYXdhaXREcmFpbik7XG4gICAgICAgIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKys7XG4gICAgICAgIGluY3JlYXNlZEF3YWl0RHJhaW4gPSB0cnVlO1xuICAgICAgfVxuICAgICAgc3JjLnBhdXNlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgdGhlIGRlc3QgaGFzIGFuIGVycm9yLCB0aGVuIHN0b3AgcGlwaW5nIGludG8gaXQuXG4gIC8vIGhvd2V2ZXIsIGRvbid0IHN1cHByZXNzIHRoZSB0aHJvd2luZyBiZWhhdmlvciBmb3IgdGhpcy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGRlYnVnKCdvbmVycm9yJywgZXIpO1xuICAgIHVucGlwZSgpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgaWYgKEVFbGlzdGVuZXJDb3VudChkZXN0LCAnZXJyb3InKSA9PT0gMCkgZGVzdC5lbWl0KCdlcnJvcicsIGVyKTtcbiAgfVxuXG4gIC8vIE1ha2Ugc3VyZSBvdXIgZXJyb3IgaGFuZGxlciBpcyBhdHRhY2hlZCBiZWZvcmUgdXNlcmxhbmQgb25lcy5cbiAgcHJlcGVuZExpc3RlbmVyKGRlc3QsICdlcnJvcicsIG9uZXJyb3IpO1xuXG4gIC8vIEJvdGggY2xvc2UgYW5kIGZpbmlzaCBzaG91bGQgdHJpZ2dlciB1bnBpcGUsIGJ1dCBvbmx5IG9uY2UuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnY2xvc2UnLCBvbmNsb3NlKTtcbiAgZnVuY3Rpb24gb25maW5pc2goKSB7XG4gICAgZGVidWcoJ29uZmluaXNoJyk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcblxuICBmdW5jdGlvbiB1bnBpcGUoKSB7XG4gICAgZGVidWcoJ3VucGlwZScpO1xuICAgIHNyYy51bnBpcGUoZGVzdCk7XG4gIH1cblxuICAvLyB0ZWxsIHRoZSBkZXN0IHRoYXQgaXQncyBiZWluZyBwaXBlZCB0b1xuICBkZXN0LmVtaXQoJ3BpcGUnLCBzcmMpO1xuXG4gIC8vIHN0YXJ0IHRoZSBmbG93IGlmIGl0IGhhc24ndCBiZWVuIHN0YXJ0ZWQgYWxyZWFkeS5cbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3BpcGUgcmVzdW1lJyk7XG4gICAgc3JjLnJlc3VtZSgpO1xuICB9XG5cbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG5mdW5jdGlvbiBwaXBlT25EcmFpbihzcmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhdGUgPSBzcmMuX3JlYWRhYmxlU3RhdGU7XG4gICAgZGVidWcoJ3BpcGVPbkRyYWluJywgc3RhdGUuYXdhaXREcmFpbik7XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4pIHN0YXRlLmF3YWl0RHJhaW4tLTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiA9PT0gMCAmJiBFRWxpc3RlbmVyQ291bnQoc3JjLCAnZGF0YScpKSB7XG4gICAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICAgIGZsb3coc3JjKTtcbiAgICB9XG4gIH07XG59XG5cblJlYWRhYmxlLnByb3RvdHlwZS51bnBpcGUgPSBmdW5jdGlvbiAoZGVzdCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgdW5waXBlSW5mbyA9IHsgaGFzVW5waXBlZDogZmFsc2UgfTtcblxuICAvLyBpZiB3ZSdyZSBub3QgcGlwaW5nIGFueXdoZXJlLCB0aGVuIGRvIG5vdGhpbmcuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAwKSByZXR1cm4gdGhpcztcblxuICAvLyBqdXN0IG9uZSBkZXN0aW5hdGlvbi4gIG1vc3QgY29tbW9uIGNhc2UuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSB7XG4gICAgLy8gcGFzc2VkIGluIG9uZSwgYnV0IGl0J3Mgbm90IHRoZSByaWdodCBvbmUuXG4gICAgaWYgKGRlc3QgJiYgZGVzdCAhPT0gc3RhdGUucGlwZXMpIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKCFkZXN0KSBkZXN0ID0gc3RhdGUucGlwZXM7XG5cbiAgICAvLyBnb3QgYSBtYXRjaC5cbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIGlmIChkZXN0KSBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMsIHVucGlwZUluZm8pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc2xvdyBjYXNlLiBtdWx0aXBsZSBwaXBlIGRlc3RpbmF0aW9ucy5cblxuICBpZiAoIWRlc3QpIHtcbiAgICAvLyByZW1vdmUgYWxsLlxuICAgIHZhciBkZXN0cyA9IHN0YXRlLnBpcGVzO1xuICAgIHZhciBsZW4gPSBzdGF0ZS5waXBlc0NvdW50O1xuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBkZXN0c1tpXS5lbWl0KCd1bnBpcGUnLCB0aGlzLCB1bnBpcGVJbmZvKTtcbiAgICB9cmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyB0cnkgdG8gZmluZCB0aGUgcmlnaHQgb25lLlxuICB2YXIgaW5kZXggPSBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KTtcbiAgaWYgKGluZGV4ID09PSAtMSkgcmV0dXJuIHRoaXM7XG5cbiAgc3RhdGUucGlwZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgc3RhdGUucGlwZXNDb3VudCAtPSAxO1xuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkgc3RhdGUucGlwZXMgPSBzdGF0ZS5waXBlc1swXTtcblxuICBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMsIHVucGlwZUluZm8pO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gc2V0IHVwIGRhdGEgZXZlbnRzIGlmIHRoZXkgYXJlIGFza2VkIGZvclxuLy8gRW5zdXJlIHJlYWRhYmxlIGxpc3RlbmVycyBldmVudHVhbGx5IGdldCBzb21ldGhpbmdcblJlYWRhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldiwgZm4pIHtcbiAgdmFyIHJlcyA9IFN0cmVhbS5wcm90b3R5cGUub24uY2FsbCh0aGlzLCBldiwgZm4pO1xuXG4gIGlmIChldiA9PT0gJ2RhdGEnKSB7XG4gICAgLy8gU3RhcnQgZmxvd2luZyBvbiBuZXh0IHRpY2sgaWYgc3RyZWFtIGlzbid0IGV4cGxpY2l0bHkgcGF1c2VkXG4gICAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyAhPT0gZmFsc2UpIHRoaXMucmVzdW1lKCk7XG4gIH0gZWxzZSBpZiAoZXYgPT09ICdyZWFkYWJsZScpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICAgIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiAhc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcpIHtcbiAgICAgIHN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nID0gc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICAgICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgICAgIHBuYS5uZXh0VGljayhuUmVhZGluZ05leHRUaWNrLCB0aGlzKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGVuZ3RoKSB7XG4gICAgICAgIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblJlYWRhYmxlLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IFJlYWRhYmxlLnByb3RvdHlwZS5vbjtcblxuZnVuY3Rpb24gblJlYWRpbmdOZXh0VGljayhzZWxmKSB7XG4gIGRlYnVnKCdyZWFkYWJsZSBuZXh0dGljayByZWFkIDAnKTtcbiAgc2VsZi5yZWFkKDApO1xufVxuXG4vLyBwYXVzZSgpIGFuZCByZXN1bWUoKSBhcmUgcmVtbmFudHMgb2YgdGhlIGxlZ2FjeSByZWFkYWJsZSBzdHJlYW0gQVBJXG4vLyBJZiB0aGUgdXNlciB1c2VzIHRoZW0sIHRoZW4gc3dpdGNoIGludG8gb2xkIG1vZGUuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncmVzdW1lJyk7XG4gICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgcmVzdW1lKHRoaXMsIHN0YXRlKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHJlc3VtZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVzdW1lU2NoZWR1bGVkKSB7XG4gICAgc3RhdGUucmVzdW1lU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICBwbmEubmV4dFRpY2socmVzdW1lXywgc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzdW1lXyhzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZykge1xuICAgIGRlYnVnKCdyZXN1bWUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gIH1cblxuICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcbiAgc3RhdGUuYXdhaXREcmFpbiA9IDA7XG4gIHN0cmVhbS5lbWl0KCdyZXN1bWUnKTtcbiAgZmxvdyhzdHJlYW0pO1xuICBpZiAoc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUucmVhZGluZykgc3RyZWFtLnJlYWQoMCk7XG59XG5cblJlYWRhYmxlLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ2NhbGwgcGF1c2UgZmxvd2luZz0laicsIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyk7XG4gIGlmIChmYWxzZSAhPT0gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKSB7XG4gICAgZGVidWcoJ3BhdXNlJyk7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0KCdwYXVzZScpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gZmxvdyhzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBkZWJ1ZygnZmxvdycsIHN0YXRlLmZsb3dpbmcpO1xuICB3aGlsZSAoc3RhdGUuZmxvd2luZyAmJiBzdHJlYW0ucmVhZCgpICE9PSBudWxsKSB7fVxufVxuXG4vLyB3cmFwIGFuIG9sZC1zdHlsZSBzdHJlYW0gYXMgdGhlIGFzeW5jIGRhdGEgc291cmNlLlxuLy8gVGhpcyBpcyAqbm90KiBwYXJ0IG9mIHRoZSByZWFkYWJsZSBzdHJlYW0gaW50ZXJmYWNlLlxuLy8gSXQgaXMgYW4gdWdseSB1bmZvcnR1bmF0ZSBtZXNzIG9mIGhpc3RvcnkuXG5SZWFkYWJsZS5wcm90b3R5cGUud3JhcCA9IGZ1bmN0aW9uIChzdHJlYW0pIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgcGF1c2VkID0gZmFsc2U7XG5cbiAgc3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZW5kJyk7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIXN0YXRlLmVuZGVkKSB7XG4gICAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkgX3RoaXMucHVzaChjaHVuayk7XG4gICAgfVxuXG4gICAgX3RoaXMucHVzaChudWxsKTtcbiAgfSk7XG5cbiAgc3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZGF0YScpO1xuICAgIGlmIChzdGF0ZS5kZWNvZGVyKSBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuXG4gICAgLy8gZG9uJ3Qgc2tpcCBvdmVyIGZhbHN5IHZhbHVlcyBpbiBvYmplY3RNb2RlXG4gICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgJiYgKGNodW5rID09PSBudWxsIHx8IGNodW5rID09PSB1bmRlZmluZWQpKSByZXR1cm47ZWxzZSBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgKCFjaHVuayB8fCAhY2h1bmsubGVuZ3RoKSkgcmV0dXJuO1xuXG4gICAgdmFyIHJldCA9IF90aGlzLnB1c2goY2h1bmspO1xuICAgIGlmICghcmV0KSB7XG4gICAgICBwYXVzZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLnBhdXNlKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBwcm94eSBhbGwgdGhlIG90aGVyIG1ldGhvZHMuXG4gIC8vIGltcG9ydGFudCB3aGVuIHdyYXBwaW5nIGZpbHRlcnMgYW5kIGR1cGxleGVzLlxuICBmb3IgKHZhciBpIGluIHN0cmVhbSkge1xuICAgIGlmICh0aGlzW2ldID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIHN0cmVhbVtpXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpc1tpXSA9IGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gc3RyZWFtW21ldGhvZF0uYXBwbHkoc3RyZWFtLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgICAgfShpKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm94eSBjZXJ0YWluIGltcG9ydGFudCBldmVudHMuXG4gIGZvciAodmFyIG4gPSAwOyBuIDwga1Byb3h5RXZlbnRzLmxlbmd0aDsgbisrKSB7XG4gICAgc3RyZWFtLm9uKGtQcm94eUV2ZW50c1tuXSwgdGhpcy5lbWl0LmJpbmQodGhpcywga1Byb3h5RXZlbnRzW25dKSk7XG4gIH1cblxuICAvLyB3aGVuIHdlIHRyeSB0byBjb25zdW1lIHNvbWUgbW9yZSBieXRlcywgc2ltcGx5IHVucGF1c2UgdGhlXG4gIC8vIHVuZGVybHlpbmcgc3RyZWFtLlxuICB0aGlzLl9yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBfcmVhZCcsIG4pO1xuICAgIGlmIChwYXVzZWQpIHtcbiAgICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgICAgc3RyZWFtLnJlc3VtZSgpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZS5wcm90b3R5cGUsICdyZWFkYWJsZUhpZ2hXYXRlck1hcmsnLCB7XG4gIC8vIG1ha2luZyBpdCBleHBsaWNpdCB0aGlzIHByb3BlcnR5IGlzIG5vdCBlbnVtZXJhYmxlXG4gIC8vIGJlY2F1c2Ugb3RoZXJ3aXNlIHNvbWUgcHJvdG90eXBlIG1hbmlwdWxhdGlvbiBpblxuICAvLyB1c2VybGFuZCB3aWxsIGZhaWxcbiAgZW51bWVyYWJsZTogZmFsc2UsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZVN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIH1cbn0pO1xuXG4vLyBleHBvc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkuXG5SZWFkYWJsZS5fZnJvbUxpc3QgPSBmcm9tTGlzdDtcblxuLy8gUGx1Y2sgb2ZmIG4gYnl0ZXMgZnJvbSBhbiBhcnJheSBvZiBidWZmZXJzLlxuLy8gTGVuZ3RoIGlzIHRoZSBjb21iaW5lZCBsZW5ndGhzIG9mIGFsbCB0aGUgYnVmZmVycyBpbiB0aGUgbGlzdC5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gZnJvbUxpc3Qobiwgc3RhdGUpIHtcbiAgLy8gbm90aGluZyBidWZmZXJlZFxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcblxuICB2YXIgcmV0O1xuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0ID0gc3RhdGUuYnVmZmVyLnNoaWZ0KCk7ZWxzZSBpZiAoIW4gfHwgbiA+PSBzdGF0ZS5sZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGxpc3RcbiAgICBpZiAoc3RhdGUuZGVjb2RlcikgcmV0ID0gc3RhdGUuYnVmZmVyLmpvaW4oJycpO2Vsc2UgaWYgKHN0YXRlLmJ1ZmZlci5sZW5ndGggPT09IDEpIHJldCA9IHN0YXRlLmJ1ZmZlci5oZWFkLmRhdGE7ZWxzZSByZXQgPSBzdGF0ZS5idWZmZXIuY29uY2F0KHN0YXRlLmxlbmd0aCk7XG4gICAgc3RhdGUuYnVmZmVyLmNsZWFyKCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVhZCBwYXJ0IG9mIGxpc3RcbiAgICByZXQgPSBmcm9tTGlzdFBhcnRpYWwobiwgc3RhdGUuYnVmZmVyLCBzdGF0ZS5kZWNvZGVyKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbi8vIEV4dHJhY3RzIG9ubHkgZW5vdWdoIGJ1ZmZlcmVkIGRhdGEgdG8gc2F0aXNmeSB0aGUgYW1vdW50IHJlcXVlc3RlZC5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gZnJvbUxpc3RQYXJ0aWFsKG4sIGxpc3QsIGhhc1N0cmluZ3MpIHtcbiAgdmFyIHJldDtcbiAgaWYgKG4gPCBsaXN0LmhlYWQuZGF0YS5sZW5ndGgpIHtcbiAgICAvLyBzbGljZSBpcyB0aGUgc2FtZSBmb3IgYnVmZmVycyBhbmQgc3RyaW5nc1xuICAgIHJldCA9IGxpc3QuaGVhZC5kYXRhLnNsaWNlKDAsIG4pO1xuICAgIGxpc3QuaGVhZC5kYXRhID0gbGlzdC5oZWFkLmRhdGEuc2xpY2Uobik7XG4gIH0gZWxzZSBpZiAobiA9PT0gbGlzdC5oZWFkLmRhdGEubGVuZ3RoKSB7XG4gICAgLy8gZmlyc3QgY2h1bmsgaXMgYSBwZXJmZWN0IG1hdGNoXG4gICAgcmV0ID0gbGlzdC5zaGlmdCgpO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlc3VsdCBzcGFucyBtb3JlIHRoYW4gb25lIGJ1ZmZlclxuICAgIHJldCA9IGhhc1N0cmluZ3MgPyBjb3B5RnJvbUJ1ZmZlclN0cmluZyhuLCBsaXN0KSA6IGNvcHlGcm9tQnVmZmVyKG4sIGxpc3QpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbi8vIENvcGllcyBhIHNwZWNpZmllZCBhbW91bnQgb2YgY2hhcmFjdGVycyBmcm9tIHRoZSBsaXN0IG9mIGJ1ZmZlcmVkIGRhdGFcbi8vIGNodW5rcy5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gY29weUZyb21CdWZmZXJTdHJpbmcobiwgbGlzdCkge1xuICB2YXIgcCA9IGxpc3QuaGVhZDtcbiAgdmFyIGMgPSAxO1xuICB2YXIgcmV0ID0gcC5kYXRhO1xuICBuIC09IHJldC5sZW5ndGg7XG4gIHdoaWxlIChwID0gcC5uZXh0KSB7XG4gICAgdmFyIHN0ciA9IHAuZGF0YTtcbiAgICB2YXIgbmIgPSBuID4gc3RyLmxlbmd0aCA/IHN0ci5sZW5ndGggOiBuO1xuICAgIGlmIChuYiA9PT0gc3RyLmxlbmd0aCkgcmV0ICs9IHN0cjtlbHNlIHJldCArPSBzdHIuc2xpY2UoMCwgbik7XG4gICAgbiAtPSBuYjtcbiAgICBpZiAobiA9PT0gMCkge1xuICAgICAgaWYgKG5iID09PSBzdHIubGVuZ3RoKSB7XG4gICAgICAgICsrYztcbiAgICAgICAgaWYgKHAubmV4dCkgbGlzdC5oZWFkID0gcC5uZXh0O2Vsc2UgbGlzdC5oZWFkID0gbGlzdC50YWlsID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpc3QuaGVhZCA9IHA7XG4gICAgICAgIHAuZGF0YSA9IHN0ci5zbGljZShuYik7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgKytjO1xuICB9XG4gIGxpc3QubGVuZ3RoIC09IGM7XG4gIHJldHVybiByZXQ7XG59XG5cbi8vIENvcGllcyBhIHNwZWNpZmllZCBhbW91bnQgb2YgYnl0ZXMgZnJvbSB0aGUgbGlzdCBvZiBidWZmZXJlZCBkYXRhIGNodW5rcy5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgaW5saW5hYmxlLCBzbyBwbGVhc2UgdGFrZSBjYXJlIHdoZW4gbWFraW5nXG4vLyBjaGFuZ2VzIHRvIHRoZSBmdW5jdGlvbiBib2R5LlxuZnVuY3Rpb24gY29weUZyb21CdWZmZXIobiwgbGlzdCkge1xuICB2YXIgcmV0ID0gQnVmZmVyLmFsbG9jVW5zYWZlKG4pO1xuICB2YXIgcCA9IGxpc3QuaGVhZDtcbiAgdmFyIGMgPSAxO1xuICBwLmRhdGEuY29weShyZXQpO1xuICBuIC09IHAuZGF0YS5sZW5ndGg7XG4gIHdoaWxlIChwID0gcC5uZXh0KSB7XG4gICAgdmFyIGJ1ZiA9IHAuZGF0YTtcbiAgICB2YXIgbmIgPSBuID4gYnVmLmxlbmd0aCA/IGJ1Zi5sZW5ndGggOiBuO1xuICAgIGJ1Zi5jb3B5KHJldCwgcmV0Lmxlbmd0aCAtIG4sIDAsIG5iKTtcbiAgICBuIC09IG5iO1xuICAgIGlmIChuID09PSAwKSB7XG4gICAgICBpZiAobmIgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICAgICAgKytjO1xuICAgICAgICBpZiAocC5uZXh0KSBsaXN0LmhlYWQgPSBwLm5leHQ7ZWxzZSBsaXN0LmhlYWQgPSBsaXN0LnRhaWwgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGlzdC5oZWFkID0gcDtcbiAgICAgICAgcC5kYXRhID0gYnVmLnNsaWNlKG5iKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICArK2M7XG4gIH1cbiAgbGlzdC5sZW5ndGggLT0gYztcbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcblxuICAvLyBJZiB3ZSBnZXQgaGVyZSBiZWZvcmUgY29uc3VtaW5nIGFsbCB0aGUgYnl0ZXMsIHRoZW4gdGhhdCBpcyBhXG4gIC8vIGJ1ZyBpbiBub2RlLiAgU2hvdWxkIG5ldmVyIGhhcHBlbi5cbiAgaWYgKHN0YXRlLmxlbmd0aCA+IDApIHRocm93IG5ldyBFcnJvcignXCJlbmRSZWFkYWJsZSgpXCIgY2FsbGVkIG9uIG5vbi1lbXB0eSBzdHJlYW0nKTtcblxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQpIHtcbiAgICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gICAgcG5hLm5leHRUaWNrKGVuZFJlYWRhYmxlTlQsIHN0YXRlLCBzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlTlQoc3RhdGUsIHN0cmVhbSkge1xuICAvLyBDaGVjayB0aGF0IHdlIGRpZG4ndCBnZXQgb25lIGxhc3QgdW5zaGlmdC5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIHN0YXRlLmVuZEVtaXR0ZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5yZWFkYWJsZSA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdlbmQnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbmRleE9mKHhzLCB4KSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKHhzW2ldID09PSB4KSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIGEgdHJhbnNmb3JtIHN0cmVhbSBpcyBhIHJlYWRhYmxlL3dyaXRhYmxlIHN0cmVhbSB3aGVyZSB5b3UgZG9cbi8vIHNvbWV0aGluZyB3aXRoIHRoZSBkYXRhLiAgU29tZXRpbWVzIGl0J3MgY2FsbGVkIGEgXCJmaWx0ZXJcIixcbi8vIGJ1dCB0aGF0J3Mgbm90IGEgZ3JlYXQgbmFtZSBmb3IgaXQsIHNpbmNlIHRoYXQgaW1wbGllcyBhIHRoaW5nIHdoZXJlXG4vLyBzb21lIGJpdHMgcGFzcyB0aHJvdWdoLCBhbmQgb3RoZXJzIGFyZSBzaW1wbHkgaWdub3JlZC4gIChUaGF0IHdvdWxkXG4vLyBiZSBhIHZhbGlkIGV4YW1wbGUgb2YgYSB0cmFuc2Zvcm0sIG9mIGNvdXJzZS4pXG4vL1xuLy8gV2hpbGUgdGhlIG91dHB1dCBpcyBjYXVzYWxseSByZWxhdGVkIHRvIHRoZSBpbnB1dCwgaXQncyBub3QgYVxuLy8gbmVjZXNzYXJpbHkgc3ltbWV0cmljIG9yIHN5bmNocm9ub3VzIHRyYW5zZm9ybWF0aW9uLiAgRm9yIGV4YW1wbGUsXG4vLyBhIHpsaWIgc3RyZWFtIG1pZ2h0IHRha2UgbXVsdGlwbGUgcGxhaW4tdGV4dCB3cml0ZXMoKSwgYW5kIHRoZW5cbi8vIGVtaXQgYSBzaW5nbGUgY29tcHJlc3NlZCBjaHVuayBzb21lIHRpbWUgaW4gdGhlIGZ1dHVyZS5cbi8vXG4vLyBIZXJlJ3MgaG93IHRoaXMgd29ya3M6XG4vL1xuLy8gVGhlIFRyYW5zZm9ybSBzdHJlYW0gaGFzIGFsbCB0aGUgYXNwZWN0cyBvZiB0aGUgcmVhZGFibGUgYW5kIHdyaXRhYmxlXG4vLyBzdHJlYW0gY2xhc3Nlcy4gIFdoZW4geW91IHdyaXRlKGNodW5rKSwgdGhhdCBjYWxscyBfd3JpdGUoY2h1bmssY2IpXG4vLyBpbnRlcm5hbGx5LCBhbmQgcmV0dXJucyBmYWxzZSBpZiB0aGVyZSdzIGEgbG90IG9mIHBlbmRpbmcgd3JpdGVzXG4vLyBidWZmZXJlZCB1cC4gIFdoZW4geW91IGNhbGwgcmVhZCgpLCB0aGF0IGNhbGxzIF9yZWFkKG4pIHVudGlsXG4vLyB0aGVyZSdzIGVub3VnaCBwZW5kaW5nIHJlYWRhYmxlIGRhdGEgYnVmZmVyZWQgdXAuXG4vL1xuLy8gSW4gYSB0cmFuc2Zvcm0gc3RyZWFtLCB0aGUgd3JpdHRlbiBkYXRhIGlzIHBsYWNlZCBpbiBhIGJ1ZmZlci4gIFdoZW5cbi8vIF9yZWFkKG4pIGlzIGNhbGxlZCwgaXQgdHJhbnNmb3JtcyB0aGUgcXVldWVkIHVwIGRhdGEsIGNhbGxpbmcgdGhlXG4vLyBidWZmZXJlZCBfd3JpdGUgY2IncyBhcyBpdCBjb25zdW1lcyBjaHVua3MuICBJZiBjb25zdW1pbmcgYSBzaW5nbGVcbi8vIHdyaXR0ZW4gY2h1bmsgd291bGQgcmVzdWx0IGluIG11bHRpcGxlIG91dHB1dCBjaHVua3MsIHRoZW4gdGhlIGZpcnN0XG4vLyBvdXRwdXR0ZWQgYml0IGNhbGxzIHRoZSByZWFkY2IsIGFuZCBzdWJzZXF1ZW50IGNodW5rcyBqdXN0IGdvIGludG9cbi8vIHRoZSByZWFkIGJ1ZmZlciwgYW5kIHdpbGwgY2F1c2UgaXQgdG8gZW1pdCAncmVhZGFibGUnIGlmIG5lY2Vzc2FyeS5cbi8vXG4vLyBUaGlzIHdheSwgYmFjay1wcmVzc3VyZSBpcyBhY3R1YWxseSBkZXRlcm1pbmVkIGJ5IHRoZSByZWFkaW5nIHNpZGUsXG4vLyBzaW5jZSBfcmVhZCBoYXMgdG8gYmUgY2FsbGVkIHRvIHN0YXJ0IHByb2Nlc3NpbmcgYSBuZXcgY2h1bmsuICBIb3dldmVyLFxuLy8gYSBwYXRob2xvZ2ljYWwgaW5mbGF0ZSB0eXBlIG9mIHRyYW5zZm9ybSBjYW4gY2F1c2UgZXhjZXNzaXZlIGJ1ZmZlcmluZ1xuLy8gaGVyZS4gIEZvciBleGFtcGxlLCBpbWFnaW5lIGEgc3RyZWFtIHdoZXJlIGV2ZXJ5IGJ5dGUgb2YgaW5wdXQgaXNcbi8vIGludGVycHJldGVkIGFzIGFuIGludGVnZXIgZnJvbSAwLTI1NSwgYW5kIHRoZW4gcmVzdWx0cyBpbiB0aGF0IG1hbnlcbi8vIGJ5dGVzIG9mIG91dHB1dC4gIFdyaXRpbmcgdGhlIDQgYnl0ZXMge2ZmLGZmLGZmLGZmfSB3b3VsZCByZXN1bHQgaW5cbi8vIDFrYiBvZiBkYXRhIGJlaW5nIG91dHB1dC4gIEluIHRoaXMgY2FzZSwgeW91IGNvdWxkIHdyaXRlIGEgdmVyeSBzbWFsbFxuLy8gYW1vdW50IG9mIGlucHV0LCBhbmQgZW5kIHVwIHdpdGggYSB2ZXJ5IGxhcmdlIGFtb3VudCBvZiBvdXRwdXQuICBJblxuLy8gc3VjaCBhIHBhdGhvbG9naWNhbCBpbmZsYXRpbmcgbWVjaGFuaXNtLCB0aGVyZSdkIGJlIG5vIHdheSB0byB0ZWxsXG4vLyB0aGUgc3lzdGVtIHRvIHN0b3AgZG9pbmcgdGhlIHRyYW5zZm9ybS4gIEEgc2luZ2xlIDRNQiB3cml0ZSBjb3VsZFxuLy8gY2F1c2UgdGhlIHN5c3RlbSB0byBydW4gb3V0IG9mIG1lbW9yeS5cbi8vXG4vLyBIb3dldmVyLCBldmVuIGluIHN1Y2ggYSBwYXRob2xvZ2ljYWwgY2FzZSwgb25seSBhIHNpbmdsZSB3cml0dGVuIGNodW5rXG4vLyB3b3VsZCBiZSBjb25zdW1lZCwgYW5kIHRoZW4gdGhlIHJlc3Qgd291bGQgd2FpdCAodW4tdHJhbnNmb3JtZWQpIHVudGlsXG4vLyB0aGUgcmVzdWx0cyBvZiB0aGUgcHJldmlvdXMgdHJhbnNmb3JtZWQgY2h1bmsgd2VyZSBjb25zdW1lZC5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zZm9ybTtcblxudmFyIER1cGxleCA9IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG51dGlsLmluaGVyaXRzKFRyYW5zZm9ybSwgRHVwbGV4KTtcblxuZnVuY3Rpb24gYWZ0ZXJUcmFuc2Zvcm0oZXIsIGRhdGEpIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG4gIHRzLnRyYW5zZm9ybWluZyA9IGZhbHNlO1xuXG4gIHZhciBjYiA9IHRzLndyaXRlY2I7XG5cbiAgaWYgKCFjYikge1xuICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCd3cml0ZSBjYWxsYmFjayBjYWxsZWQgbXVsdGlwbGUgdGltZXMnKSk7XG4gIH1cblxuICB0cy53cml0ZWNodW5rID0gbnVsbDtcbiAgdHMud3JpdGVjYiA9IG51bGw7XG5cbiAgaWYgKGRhdGEgIT0gbnVsbCkgLy8gc2luZ2xlIGVxdWFscyBjaGVjayBmb3IgYm90aCBgbnVsbGAgYW5kIGB1bmRlZmluZWRgXG4gICAgdGhpcy5wdXNoKGRhdGEpO1xuXG4gIGNiKGVyKTtcblxuICB2YXIgcnMgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBycy5yZWFkaW5nID0gZmFsc2U7XG4gIGlmIChycy5uZWVkUmVhZGFibGUgfHwgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaykge1xuICAgIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn1cblxuZnVuY3Rpb24gVHJhbnNmb3JtKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFRyYW5zZm9ybSkpIHJldHVybiBuZXcgVHJhbnNmb3JtKG9wdGlvbnMpO1xuXG4gIER1cGxleC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlID0ge1xuICAgIGFmdGVyVHJhbnNmb3JtOiBhZnRlclRyYW5zZm9ybS5iaW5kKHRoaXMpLFxuICAgIG5lZWRUcmFuc2Zvcm06IGZhbHNlLFxuICAgIHRyYW5zZm9ybWluZzogZmFsc2UsXG4gICAgd3JpdGVjYjogbnVsbCxcbiAgICB3cml0ZWNodW5rOiBudWxsLFxuICAgIHdyaXRlZW5jb2Rpbmc6IG51bGxcbiAgfTtcblxuICAvLyBzdGFydCBvdXQgYXNraW5nIGZvciBhIHJlYWRhYmxlIGV2ZW50IG9uY2UgZGF0YSBpcyB0cmFuc2Zvcm1lZC5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIHdlIGhhdmUgaW1wbGVtZW50ZWQgdGhlIF9yZWFkIG1ldGhvZCwgYW5kIGRvbmUgdGhlIG90aGVyIHRoaW5nc1xuICAvLyB0aGF0IFJlYWRhYmxlIHdhbnRzIGJlZm9yZSB0aGUgZmlyc3QgX3JlYWQgY2FsbCwgc28gdW5zZXQgdGhlXG4gIC8vIHN5bmMgZ3VhcmQgZmxhZy5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5zeW5jID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMudHJhbnNmb3JtID09PSAnZnVuY3Rpb24nKSB0aGlzLl90cmFuc2Zvcm0gPSBvcHRpb25zLnRyYW5zZm9ybTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5mbHVzaCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmx1c2ggPSBvcHRpb25zLmZsdXNoO1xuICB9XG5cbiAgLy8gV2hlbiB0aGUgd3JpdGFibGUgc2lkZSBmaW5pc2hlcywgdGhlbiBmbHVzaCBvdXQgYW55dGhpbmcgcmVtYWluaW5nLlxuICB0aGlzLm9uKCdwcmVmaW5pc2gnLCBwcmVmaW5pc2gpO1xufVxuXG5mdW5jdGlvbiBwcmVmaW5pc2goKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgaWYgKHR5cGVvZiB0aGlzLl9mbHVzaCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMuX2ZsdXNoKGZ1bmN0aW9uIChlciwgZGF0YSkge1xuICAgICAgZG9uZShfdGhpcywgZXIsIGRhdGEpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGRvbmUodGhpcywgbnVsbCwgbnVsbCk7XG4gIH1cbn1cblxuVHJhbnNmb3JtLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZykge1xuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZS5uZWVkVHJhbnNmb3JtID0gZmFsc2U7XG4gIHJldHVybiBEdXBsZXgucHJvdG90eXBlLnB1c2guY2FsbCh0aGlzLCBjaHVuaywgZW5jb2RpbmcpO1xufTtcblxuLy8gVGhpcyBpcyB0aGUgcGFydCB3aGVyZSB5b3UgZG8gc3R1ZmYhXG4vLyBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uIGluIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyAnY2h1bmsnIGlzIGFuIGlucHV0IGNodW5rLlxuLy9cbi8vIENhbGwgYHB1c2gobmV3Q2h1bmspYCB0byBwYXNzIGFsb25nIHRyYW5zZm9ybWVkIG91dHB1dFxuLy8gdG8gdGhlIHJlYWRhYmxlIHNpZGUuICBZb3UgbWF5IGNhbGwgJ3B1c2gnIHplcm8gb3IgbW9yZSB0aW1lcy5cbi8vXG4vLyBDYWxsIGBjYihlcnIpYCB3aGVuIHlvdSBhcmUgZG9uZSB3aXRoIHRoaXMgY2h1bmsuICBJZiB5b3UgcGFzc1xuLy8gYW4gZXJyb3IsIHRoZW4gdGhhdCdsbCBwdXQgdGhlIGh1cnQgb24gdGhlIHdob2xlIG9wZXJhdGlvbi4gIElmIHlvdVxuLy8gbmV2ZXIgY2FsbCBjYigpLCB0aGVuIHlvdSdsbCBuZXZlciBnZXQgYW5vdGhlciBjaHVuay5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcignX3RyYW5zZm9ybSgpIGlzIG5vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuVHJhbnNmb3JtLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMud3JpdGVjYiA9IGNiO1xuICB0cy53cml0ZWNodW5rID0gY2h1bms7XG4gIHRzLndyaXRlZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgaWYgKCF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB2YXIgcnMgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICAgIGlmICh0cy5uZWVkVHJhbnNmb3JtIHx8IHJzLm5lZWRSZWFkYWJsZSB8fCBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKSB0aGlzLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59O1xuXG4vLyBEb2Vzbid0IG1hdHRlciB3aGF0IHRoZSBhcmdzIGFyZSBoZXJlLlxuLy8gX3RyYW5zZm9ybSBkb2VzIGFsbCB0aGUgd29yay5cbi8vIFRoYXQgd2UgZ290IGhlcmUgbWVhbnMgdGhhdCB0aGUgcmVhZGFibGUgc2lkZSB3YW50cyBtb3JlIGRhdGEuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG5cbiAgaWYgKHRzLndyaXRlY2h1bmsgIT09IG51bGwgJiYgdHMud3JpdGVjYiAmJiAhdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdHMudHJhbnNmb3JtaW5nID0gdHJ1ZTtcbiAgICB0aGlzLl90cmFuc2Zvcm0odHMud3JpdGVjaHVuaywgdHMud3JpdGVlbmNvZGluZywgdHMuYWZ0ZXJUcmFuc2Zvcm0pO1xuICB9IGVsc2Uge1xuICAgIC8vIG1hcmsgdGhhdCB3ZSBuZWVkIGEgdHJhbnNmb3JtLCBzbyB0aGF0IGFueSBkYXRhIHRoYXQgY29tZXMgaW5cbiAgICAvLyB3aWxsIGdldCBwcm9jZXNzZWQsIG5vdyB0aGF0IHdlJ3ZlIGFza2VkIGZvciBpdC5cbiAgICB0cy5uZWVkVHJhbnNmb3JtID0gdHJ1ZTtcbiAgfVxufTtcblxuVHJhbnNmb3JtLnByb3RvdHlwZS5fZGVzdHJveSA9IGZ1bmN0aW9uIChlcnIsIGNiKSB7XG4gIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gIER1cGxleC5wcm90b3R5cGUuX2Rlc3Ryb3kuY2FsbCh0aGlzLCBlcnIsIGZ1bmN0aW9uIChlcnIyKSB7XG4gICAgY2IoZXJyMik7XG4gICAgX3RoaXMyLmVtaXQoJ2Nsb3NlJyk7XG4gIH0pO1xufTtcblxuZnVuY3Rpb24gZG9uZShzdHJlYW0sIGVyLCBkYXRhKSB7XG4gIGlmIChlcikgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcblxuICBpZiAoZGF0YSAhPSBudWxsKSAvLyBzaW5nbGUgZXF1YWxzIGNoZWNrIGZvciBib3RoIGBudWxsYCBhbmQgYHVuZGVmaW5lZGBcbiAgICBzdHJlYW0ucHVzaChkYXRhKTtcblxuICAvLyBpZiB0aGVyZSdzIG5vdGhpbmcgaW4gdGhlIHdyaXRlIGJ1ZmZlciwgdGhlbiB0aGF0IG1lYW5zXG4gIC8vIHRoYXQgbm90aGluZyBtb3JlIHdpbGwgZXZlciBiZSBwcm92aWRlZFxuICBpZiAoc3RyZWFtLl93cml0YWJsZVN0YXRlLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gd3MubGVuZ3RoICE9IDAnKTtcblxuICBpZiAoc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZS50cmFuc2Zvcm1pbmcpIHRocm93IG5ldyBFcnJvcignQ2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHN0aWxsIHRyYW5zZm9ybWluZycpO1xuXG4gIHJldHVybiBzdHJlYW0ucHVzaChudWxsKTtcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gQSBiaXQgc2ltcGxlciB0aGFuIHJlYWRhYmxlIHN0cmVhbXMuXG4vLyBJbXBsZW1lbnQgYW4gYXN5bmMgLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIGNiKSwgYW5kIGl0J2xsIGhhbmRsZSBhbGxcbi8vIHRoZSBkcmFpbiBldmVudCBlbWlzc2lvbiBhbmQgYnVmZmVyaW5nLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBwbmEgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbm1vZHVsZS5leHBvcnRzID0gV3JpdGFibGU7XG5cbi8qIDxyZXBsYWNlbWVudD4gKi9cbmZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhpcy5jaHVuayA9IGNodW5rO1xuICB0aGlzLmVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHRoaXMuY2FsbGJhY2sgPSBjYjtcbiAgdGhpcy5uZXh0ID0gbnVsbDtcbn1cblxuLy8gSXQgc2VlbXMgYSBsaW5rZWQgbGlzdCBidXQgaXQgaXMgbm90XG4vLyB0aGVyZSB3aWxsIGJlIG9ubHkgMiBvZiB0aGVzZSBmb3IgZWFjaCBzdHJlYW1cbmZ1bmN0aW9uIENvcmtlZFJlcXVlc3Qoc3RhdGUpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICB0aGlzLm5leHQgPSBudWxsO1xuICB0aGlzLmVudHJ5ID0gbnVsbDtcbiAgdGhpcy5maW5pc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgb25Db3JrZWRGaW5pc2goX3RoaXMsIHN0YXRlKTtcbiAgfTtcbn1cbi8qIDwvcmVwbGFjZW1lbnQ+ICovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgYXN5bmNXcml0ZSA9ICFwcm9jZXNzLmJyb3dzZXIgJiYgWyd2MC4xMCcsICd2MC45LiddLmluZGV4T2YocHJvY2Vzcy52ZXJzaW9uLnNsaWNlKDAsIDUpKSA+IC0xID8gc2V0SW1tZWRpYXRlIDogcG5hLm5leHRUaWNrO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRHVwbGV4O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbldyaXRhYmxlLldyaXRhYmxlU3RhdGUgPSBXcml0YWJsZVN0YXRlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgaW50ZXJuYWxVdGlsID0ge1xuICBkZXByZWNhdGU6IHJlcXVpcmUoJ3V0aWwtZGVwcmVjYXRlJylcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW0gPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvc3RyZWFtJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyO1xudmFyIE91clVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheSB8fCBmdW5jdGlvbiAoKSB7fTtcbmZ1bmN0aW9uIF91aW50OEFycmF5VG9CdWZmZXIoY2h1bmspIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKGNodW5rKTtcbn1cbmZ1bmN0aW9uIF9pc1VpbnQ4QXJyYXkob2JqKSB7XG4gIHJldHVybiBCdWZmZXIuaXNCdWZmZXIob2JqKSB8fCBvYmogaW5zdGFuY2VvZiBPdXJVaW50OEFycmF5O1xufVxuXG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIGRlc3Ryb3lJbXBsID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL2Rlc3Ryb3knKTtcblxudXRpbC5pbmhlcml0cyhXcml0YWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gbm9wKCkge31cblxuZnVuY3Rpb24gV3JpdGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBEdXBsZXggc3RyZWFtcyBhcmUgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUsIGJ1dCBzaGFyZVxuICAvLyB0aGUgc2FtZSBvcHRpb25zIG9iamVjdC5cbiAgLy8gSG93ZXZlciwgc29tZSBjYXNlcyByZXF1aXJlIHNldHRpbmcgb3B0aW9ucyB0byBkaWZmZXJlbnRcbiAgLy8gdmFsdWVzIGZvciB0aGUgcmVhZGFibGUgYW5kIHRoZSB3cml0YWJsZSBzaWRlcyBvZiB0aGUgZHVwbGV4IHN0cmVhbS5cbiAgLy8gVGhlc2Ugb3B0aW9ucyBjYW4gYmUgcHJvdmlkZWQgc2VwYXJhdGVseSBhcyByZWFkYWJsZVhYWCBhbmQgd3JpdGFibGVYWFguXG4gIHZhciBpc0R1cGxleCA9IHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleDtcblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcgdG8gaW5kaWNhdGUgd2hldGhlciBvciBub3QgdGhpcyBzdHJlYW1cbiAgLy8gY29udGFpbnMgYnVmZmVycyBvciBvYmplY3RzLlxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICBpZiAoaXNEdXBsZXgpIHRoaXMub2JqZWN0TW9kZSA9IHRoaXMub2JqZWN0TW9kZSB8fCAhIW9wdGlvbnMud3JpdGFibGVPYmplY3RNb2RlO1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCB3cml0ZSgpIHN0YXJ0cyByZXR1cm5pbmcgZmFsc2VcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyB0aGF0IHdlIGFsd2F5cyByZXR1cm4gZmFsc2UgaWZcbiAgLy8gdGhlIGVudGlyZSBidWZmZXIgaXMgbm90IGZsdXNoZWQgaW1tZWRpYXRlbHkgb24gd3JpdGUoKVxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB2YXIgd3JpdGFibGVId20gPSBvcHRpb25zLndyaXRhYmxlSGlnaFdhdGVyTWFyaztcbiAgdmFyIGRlZmF1bHRId20gPSB0aGlzLm9iamVjdE1vZGUgPyAxNiA6IDE2ICogMTAyNDtcblxuICBpZiAoaHdtIHx8IGh3bSA9PT0gMCkgdGhpcy5oaWdoV2F0ZXJNYXJrID0gaHdtO2Vsc2UgaWYgKGlzRHVwbGV4ICYmICh3cml0YWJsZUh3bSB8fCB3cml0YWJsZUh3bSA9PT0gMCkpIHRoaXMuaGlnaFdhdGVyTWFyayA9IHdyaXRhYmxlSHdtO2Vsc2UgdGhpcy5oaWdoV2F0ZXJNYXJrID0gZGVmYXVsdEh3bTtcblxuICAvLyBjYXN0IHRvIGludHMuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IE1hdGguZmxvb3IodGhpcy5oaWdoV2F0ZXJNYXJrKTtcblxuICAvLyBpZiBfZmluYWwgaGFzIGJlZW4gY2FsbGVkXG4gIHRoaXMuZmluYWxDYWxsZWQgPSBmYWxzZTtcblxuICAvLyBkcmFpbiBldmVudCBmbGFnLlxuICB0aGlzLm5lZWREcmFpbiA9IGZhbHNlO1xuICAvLyBhdCB0aGUgc3RhcnQgb2YgY2FsbGluZyBlbmQoKVxuICB0aGlzLmVuZGluZyA9IGZhbHNlO1xuICAvLyB3aGVuIGVuZCgpIGhhcyBiZWVuIGNhbGxlZCwgYW5kIHJldHVybmVkXG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgLy8gd2hlbiAnZmluaXNoJyBpcyBlbWl0dGVkXG4gIHRoaXMuZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBoYXMgaXQgYmVlbiBkZXN0cm95ZWRcbiAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZTtcblxuICAvLyBzaG91bGQgd2UgZGVjb2RlIHN0cmluZ3MgaW50byBidWZmZXJzIGJlZm9yZSBwYXNzaW5nIHRvIF93cml0ZT9cbiAgLy8gdGhpcyBpcyBoZXJlIHNvIHRoYXQgc29tZSBub2RlLWNvcmUgc3RyZWFtcyBjYW4gb3B0aW1pemUgc3RyaW5nXG4gIC8vIGhhbmRsaW5nIGF0IGEgbG93ZXIgbGV2ZWwuXG4gIHZhciBub0RlY29kZSA9IG9wdGlvbnMuZGVjb2RlU3RyaW5ncyA9PT0gZmFsc2U7XG4gIHRoaXMuZGVjb2RlU3RyaW5ncyA9ICFub0RlY29kZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyBub3QgYW4gYWN0dWFsIGJ1ZmZlciB3ZSBrZWVwIHRyYWNrIG9mLCBidXQgYSBtZWFzdXJlbWVudFxuICAvLyBvZiBob3cgbXVjaCB3ZSdyZSB3YWl0aW5nIHRvIGdldCBwdXNoZWQgdG8gc29tZSB1bmRlcmx5aW5nXG4gIC8vIHNvY2tldCBvciBmaWxlLlxuICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIHNlZSB3aGVuIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSB3cml0ZS5cbiAgdGhpcy53cml0aW5nID0gZmFsc2U7XG5cbiAgLy8gd2hlbiB0cnVlIGFsbCB3cml0ZXMgd2lsbCBiZSBidWZmZXJlZCB1bnRpbCAudW5jb3JrKCkgY2FsbFxuICB0aGlzLmNvcmtlZCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gYSBmbGFnIHRvIGtub3cgaWYgd2UncmUgcHJvY2Vzc2luZyBwcmV2aW91c2x5IGJ1ZmZlcmVkIGl0ZW1zLCB3aGljaFxuICAvLyBtYXkgY2FsbCB0aGUgX3dyaXRlKCkgY2FsbGJhY2sgaW4gdGhlIHNhbWUgdGljaywgc28gdGhhdCB3ZSBkb24ndFxuICAvLyBlbmQgdXAgaW4gYW4gb3ZlcmxhcHBlZCBvbndyaXRlIHNpdHVhdGlvbi5cbiAgdGhpcy5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQncyBwYXNzZWQgdG8gX3dyaXRlKGNodW5rLGNiKVxuICB0aGlzLm9ud3JpdGUgPSBmdW5jdGlvbiAoZXIpIHtcbiAgICBvbndyaXRlKHN0cmVhbSwgZXIpO1xuICB9O1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0IHRoZSB1c2VyIHN1cHBsaWVzIHRvIHdyaXRlKGNodW5rLGVuY29kaW5nLGNiKVxuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuXG4gIC8vIHRoZSBhbW91bnQgdGhhdCBpcyBiZWluZyB3cml0dGVuIHdoZW4gX3dyaXRlIGlzIGNhbGxlZC5cbiAgdGhpcy53cml0ZWxlbiA9IDA7XG5cbiAgdGhpcy5idWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICB0aGlzLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuXG4gIC8vIG51bWJlciBvZiBwZW5kaW5nIHVzZXItc3VwcGxpZWQgd3JpdGUgY2FsbGJhY2tzXG4gIC8vIHRoaXMgbXVzdCBiZSAwIGJlZm9yZSAnZmluaXNoJyBjYW4gYmUgZW1pdHRlZFxuICB0aGlzLnBlbmRpbmdjYiA9IDA7XG5cbiAgLy8gZW1pdCBwcmVmaW5pc2ggaWYgdGhlIG9ubHkgdGhpbmcgd2UncmUgd2FpdGluZyBmb3IgaXMgX3dyaXRlIGNic1xuICAvLyBUaGlzIGlzIHJlbGV2YW50IGZvciBzeW5jaHJvbm91cyBUcmFuc2Zvcm0gc3RyZWFtc1xuICB0aGlzLnByZWZpbmlzaGVkID0gZmFsc2U7XG5cbiAgLy8gVHJ1ZSBpZiB0aGUgZXJyb3Igd2FzIGFscmVhZHkgZW1pdHRlZCBhbmQgc2hvdWxkIG5vdCBiZSB0aHJvd24gYWdhaW5cbiAgdGhpcy5lcnJvckVtaXR0ZWQgPSBmYWxzZTtcblxuICAvLyBjb3VudCBidWZmZXJlZCByZXF1ZXN0c1xuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdENvdW50ID0gMDtcblxuICAvLyBhbGxvY2F0ZSB0aGUgZmlyc3QgQ29ya2VkUmVxdWVzdCwgdGhlcmUgaXMgYWx3YXlzXG4gIC8vIG9uZSBhbGxvY2F0ZWQgYW5kIGZyZWUgdG8gdXNlLCBhbmQgd2UgbWFpbnRhaW4gYXQgbW9zdCB0d29cbiAgdGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBuZXcgQ29ya2VkUmVxdWVzdCh0aGlzKTtcbn1cblxuV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUuZ2V0QnVmZmVyID0gZnVuY3Rpb24gZ2V0QnVmZmVyKCkge1xuICB2YXIgY3VycmVudCA9IHRoaXMuYnVmZmVyZWRSZXF1ZXN0O1xuICB2YXIgb3V0ID0gW107XG4gIHdoaWxlIChjdXJyZW50KSB7XG4gICAgb3V0LnB1c2goY3VycmVudCk7XG4gICAgY3VycmVudCA9IGN1cnJlbnQubmV4dDtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcblxuKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUsICdidWZmZXInLCB7XG4gICAgICBnZXQ6IGludGVybmFsVXRpbC5kZXByZWNhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRCdWZmZXIoKTtcbiAgICAgIH0sICdfd3JpdGFibGVTdGF0ZS5idWZmZXIgaXMgZGVwcmVjYXRlZC4gVXNlIF93cml0YWJsZVN0YXRlLmdldEJ1ZmZlciAnICsgJ2luc3RlYWQuJywgJ0RFUDAwMDMnKVxuICAgIH0pO1xuICB9IGNhdGNoIChfKSB7fVxufSkoKTtcblxuLy8gVGVzdCBfd3JpdGFibGVTdGF0ZSBmb3IgaW5oZXJpdGFuY2UgdG8gYWNjb3VudCBmb3IgRHVwbGV4IHN0cmVhbXMsXG4vLyB3aG9zZSBwcm90b3R5cGUgY2hhaW4gb25seSBwb2ludHMgdG8gUmVhZGFibGUuXG52YXIgcmVhbEhhc0luc3RhbmNlO1xuaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLmhhc0luc3RhbmNlICYmIHR5cGVvZiBGdW5jdGlvbi5wcm90b3R5cGVbU3ltYm9sLmhhc0luc3RhbmNlXSA9PT0gJ2Z1bmN0aW9uJykge1xuICByZWFsSGFzSW5zdGFuY2UgPSBGdW5jdGlvbi5wcm90b3R5cGVbU3ltYm9sLmhhc0luc3RhbmNlXTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlLCBTeW1ib2wuaGFzSW5zdGFuY2UsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24gKG9iamVjdCkge1xuICAgICAgaWYgKHJlYWxIYXNJbnN0YW5jZS5jYWxsKHRoaXMsIG9iamVjdCkpIHJldHVybiB0cnVlO1xuICAgICAgaWYgKHRoaXMgIT09IFdyaXRhYmxlKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIHJldHVybiBvYmplY3QgJiYgb2JqZWN0Ll93cml0YWJsZVN0YXRlIGluc3RhbmNlb2YgV3JpdGFibGVTdGF0ZTtcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgcmVhbEhhc0luc3RhbmNlID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiB0aGlzO1xuICB9O1xufVxuXG5mdW5jdGlvbiBXcml0YWJsZShvcHRpb25zKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgLy8gV3JpdGFibGUgY3RvciBpcyBhcHBsaWVkIHRvIER1cGxleGVzLCB0b28uXG4gIC8vIGByZWFsSGFzSW5zdGFuY2VgIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHVzaW5nIHBsYWluIGBpbnN0YW5jZW9mYFxuICAvLyB3b3VsZCByZXR1cm4gZmFsc2UsIGFzIG5vIGBfd3JpdGFibGVTdGF0ZWAgcHJvcGVydHkgaXMgYXR0YWNoZWQuXG5cbiAgLy8gVHJ5aW5nIHRvIHVzZSB0aGUgY3VzdG9tIGBpbnN0YW5jZW9mYCBmb3IgV3JpdGFibGUgaGVyZSB3aWxsIGFsc28gYnJlYWsgdGhlXG4gIC8vIE5vZGUuanMgTGF6eVRyYW5zZm9ybSBpbXBsZW1lbnRhdGlvbiwgd2hpY2ggaGFzIGEgbm9uLXRyaXZpYWwgZ2V0dGVyIGZvclxuICAvLyBgX3dyaXRhYmxlU3RhdGVgIHRoYXQgd291bGQgbGVhZCB0byBpbmZpbml0ZSByZWN1cnNpb24uXG4gIGlmICghcmVhbEhhc0luc3RhbmNlLmNhbGwoV3JpdGFibGUsIHRoaXMpICYmICEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpIHtcbiAgICByZXR1cm4gbmV3IFdyaXRhYmxlKG9wdGlvbnMpO1xuICB9XG5cbiAgdGhpcy5fd3JpdGFibGVTdGF0ZSA9IG5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeS5cbiAgdGhpcy53cml0YWJsZSA9IHRydWU7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGUgPT09ICdmdW5jdGlvbicpIHRoaXMuX3dyaXRlID0gb3B0aW9ucy53cml0ZTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53cml0ZXYgPT09ICdmdW5jdGlvbicpIHRoaXMuX3dyaXRldiA9IG9wdGlvbnMud3JpdGV2O1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIHRoaXMuX2Rlc3Ryb3kgPSBvcHRpb25zLmRlc3Ryb3k7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuZmluYWwgPT09ICdmdW5jdGlvbicpIHRoaXMuX2ZpbmFsID0gb3B0aW9ucy5maW5hbDtcbiAgfVxuXG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuXG4vLyBPdGhlcndpc2UgcGVvcGxlIGNhbiBwaXBlIFdyaXRhYmxlIHN0cmVhbXMsIHdoaWNoIGlzIGp1c3Qgd3JvbmcuXG5Xcml0YWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignQ2Fubm90IHBpcGUsIG5vdCByZWFkYWJsZScpKTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBjYikge1xuICB2YXIgZXIgPSBuZXcgRXJyb3IoJ3dyaXRlIGFmdGVyIGVuZCcpO1xuICAvLyBUT0RPOiBkZWZlciBlcnJvciBldmVudHMgY29uc2lzdGVudGx5IGV2ZXJ5d2hlcmUsIG5vdCBqdXN0IHRoZSBjYlxuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIHBuYS5uZXh0VGljayhjYiwgZXIpO1xufVxuXG4vLyBDaGVja3MgdGhhdCBhIHVzZXItc3VwcGxpZWQgY2h1bmsgaXMgdmFsaWQsIGVzcGVjaWFsbHkgZm9yIHRoZSBwYXJ0aWN1bGFyXG4vLyBtb2RlIHRoZSBzdHJlYW0gaXMgaW4uIEN1cnJlbnRseSB0aGlzIG1lYW5zIHRoYXQgYG51bGxgIGlzIG5ldmVyIGFjY2VwdGVkXG4vLyBhbmQgdW5kZWZpbmVkL25vbi1zdHJpbmcgdmFsdWVzIGFyZSBvbmx5IGFsbG93ZWQgaW4gb2JqZWN0IG1vZGUuXG5mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBjYikge1xuICB2YXIgdmFsaWQgPSB0cnVlO1xuICB2YXIgZXIgPSBmYWxzZTtcblxuICBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICBlciA9IG5ldyBUeXBlRXJyb3IoJ01heSBub3Qgd3JpdGUgbnVsbCB2YWx1ZXMgdG8gc3RyZWFtJyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgaWYgKGVyKSB7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICAgIHBuYS5uZXh0VGljayhjYiwgZXIpO1xuICAgIHZhbGlkID0gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHZhbGlkO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICB2YXIgcmV0ID0gZmFsc2U7XG4gIHZhciBpc0J1ZiA9ICFzdGF0ZS5vYmplY3RNb2RlICYmIF9pc1VpbnQ4QXJyYXkoY2h1bmspO1xuXG4gIGlmIChpc0J1ZiAmJiAhQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkge1xuICAgIGNodW5rID0gX3VpbnQ4QXJyYXlUb0J1ZmZlcihjaHVuayk7XG4gIH1cblxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoaXNCdWYpIGVuY29kaW5nID0gJ2J1ZmZlcic7ZWxzZSBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcblxuICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKSBjYiA9IG5vcDtcblxuICBpZiAoc3RhdGUuZW5kZWQpIHdyaXRlQWZ0ZXJFbmQodGhpcywgY2IpO2Vsc2UgaWYgKGlzQnVmIHx8IHZhbGlkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBjYikpIHtcbiAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICByZXQgPSB3cml0ZU9yQnVmZmVyKHRoaXMsIHN0YXRlLCBpc0J1ZiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLmNvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgc3RhdGUuY29ya2VkKys7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUudW5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQtLTtcblxuICAgIGlmICghc3RhdGUud3JpdGluZyAmJiAhc3RhdGUuY29ya2VkICYmICFzdGF0ZS5maW5pc2hlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIGNsZWFyQnVmZmVyKHRoaXMsIHN0YXRlKTtcbiAgfVxufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnNldERlZmF1bHRFbmNvZGluZyA9IGZ1bmN0aW9uIHNldERlZmF1bHRFbmNvZGluZyhlbmNvZGluZykge1xuICAvLyBub2RlOjpQYXJzZUVuY29kaW5nKCkgcmVxdWlyZXMgbG93ZXIgY2FzZS5cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpIGVuY29kaW5nID0gZW5jb2RpbmcudG9Mb3dlckNhc2UoKTtcbiAgaWYgKCEoWydoZXgnLCAndXRmOCcsICd1dGYtOCcsICdhc2NpaScsICdiaW5hcnknLCAnYmFzZTY0JywgJ3VjczInLCAndWNzLTInLCAndXRmMTZsZScsICd1dGYtMTZsZScsICdyYXcnXS5pbmRleE9mKChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpKSA+IC0xKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKTtcbiAgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZWZhdWx0RW5jb2RpbmcgPSBlbmNvZGluZztcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKSB7XG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiBzdGF0ZS5kZWNvZGVTdHJpbmdzICE9PSBmYWxzZSAmJiB0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgY2h1bmsgPSBCdWZmZXIuZnJvbShjaHVuaywgZW5jb2RpbmcpO1xuICB9XG4gIHJldHVybiBjaHVuaztcbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlLnByb3RvdHlwZSwgJ3dyaXRhYmxlSGlnaFdhdGVyTWFyaycsIHtcbiAgLy8gbWFraW5nIGl0IGV4cGxpY2l0IHRoaXMgcHJvcGVydHkgaXMgbm90IGVudW1lcmFibGVcbiAgLy8gYmVjYXVzZSBvdGhlcndpc2Ugc29tZSBwcm90b3R5cGUgbWFuaXB1bGF0aW9uIGluXG4gIC8vIHVzZXJsYW5kIHdpbGwgZmFpbFxuICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlU3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgfVxufSk7XG5cbi8vIGlmIHdlJ3JlIGFscmVhZHkgd3JpdGluZyBzb21ldGhpbmcsIHRoZW4ganVzdCBwdXQgdGhpc1xuLy8gaW4gdGhlIHF1ZXVlLCBhbmQgd2FpdCBvdXIgdHVybi4gIE90aGVyd2lzZSwgY2FsbCBfd3JpdGVcbi8vIElmIHdlIHJldHVybiBmYWxzZSwgdGhlbiB3ZSBuZWVkIGEgZHJhaW4gZXZlbnQsIHNvIHNldCB0aGF0IGZsYWcuXG5mdW5jdGlvbiB3cml0ZU9yQnVmZmVyKHN0cmVhbSwgc3RhdGUsIGlzQnVmLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGlmICghaXNCdWYpIHtcbiAgICB2YXIgbmV3Q2h1bmsgPSBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKTtcbiAgICBpZiAoY2h1bmsgIT09IG5ld0NodW5rKSB7XG4gICAgICBpc0J1ZiA9IHRydWU7XG4gICAgICBlbmNvZGluZyA9ICdidWZmZXInO1xuICAgICAgY2h1bmsgPSBuZXdDaHVuaztcbiAgICB9XG4gIH1cbiAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gIHN0YXRlLmxlbmd0aCArPSBsZW47XG5cbiAgdmFyIHJldCA9IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIC8vIHdlIG11c3QgZW5zdXJlIHRoYXQgcHJldmlvdXMgbmVlZERyYWluIHdpbGwgbm90IGJlIHJlc2V0IHRvIGZhbHNlLlxuICBpZiAoIXJldCkgc3RhdGUubmVlZERyYWluID0gdHJ1ZTtcblxuICBpZiAoc3RhdGUud3JpdGluZyB8fCBzdGF0ZS5jb3JrZWQpIHtcbiAgICB2YXIgbGFzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IHtcbiAgICAgIGNodW5rOiBjaHVuayxcbiAgICAgIGVuY29kaW5nOiBlbmNvZGluZyxcbiAgICAgIGlzQnVmOiBpc0J1ZixcbiAgICAgIGNhbGxiYWNrOiBjYixcbiAgICAgIG5leHQ6IG51bGxcbiAgICB9O1xuICAgIGlmIChsYXN0KSB7XG4gICAgICBsYXN0Lm5leHQgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH1cbiAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudCArPSAxO1xuICB9IGVsc2Uge1xuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHdyaXRldiwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHN0YXRlLndyaXRlbGVuID0gbGVuO1xuICBzdGF0ZS53cml0ZWNiID0gY2I7XG4gIHN0YXRlLndyaXRpbmcgPSB0cnVlO1xuICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgaWYgKHdyaXRldikgc3RyZWFtLl93cml0ZXYoY2h1bmssIHN0YXRlLm9ud3JpdGUpO2Vsc2Ugc3RyZWFtLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIHN0YXRlLm9ud3JpdGUpO1xuICBzdGF0ZS5zeW5jID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpIHtcbiAgLS1zdGF0ZS5wZW5kaW5nY2I7XG5cbiAgaWYgKHN5bmMpIHtcbiAgICAvLyBkZWZlciB0aGUgY2FsbGJhY2sgaWYgd2UgYXJlIGJlaW5nIGNhbGxlZCBzeW5jaHJvbm91c2x5XG4gICAgLy8gdG8gYXZvaWQgcGlsaW5nIHVwIHRoaW5ncyBvbiB0aGUgc3RhY2tcbiAgICBwbmEubmV4dFRpY2soY2IsIGVyKTtcbiAgICAvLyB0aGlzIGNhbiBlbWl0IGZpbmlzaCwgYW5kIGl0IHdpbGwgYWx3YXlzIGhhcHBlblxuICAgIC8vIGFmdGVyIGVycm9yXG4gICAgcG5hLm5leHRUaWNrKGZpbmlzaE1heWJlLCBzdHJlYW0sIHN0YXRlKTtcbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIH0gZWxzZSB7XG4gICAgLy8gdGhlIGNhbGxlciBleHBlY3QgdGhpcyB0byBoYXBwZW4gYmVmb3JlIGlmXG4gICAgLy8gaXQgaXMgYXN5bmNcbiAgICBjYihlcik7XG4gICAgc3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICAgIC8vIHRoaXMgY2FuIGVtaXQgZmluaXNoLCBidXQgZmluaXNoIG11c3RcbiAgICAvLyBhbHdheXMgZm9sbG93IGVycm9yXG4gICAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKSB7XG4gIHN0YXRlLndyaXRpbmcgPSBmYWxzZTtcbiAgc3RhdGUud3JpdGVjYiA9IG51bGw7XG4gIHN0YXRlLmxlbmd0aCAtPSBzdGF0ZS53cml0ZWxlbjtcbiAgc3RhdGUud3JpdGVsZW4gPSAwO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlKHN0cmVhbSwgZXIpIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgc3luYyA9IHN0YXRlLnN5bmM7XG4gIHZhciBjYiA9IHN0YXRlLndyaXRlY2I7XG5cbiAgb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKTtcblxuICBpZiAoZXIpIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpO2Vsc2Uge1xuICAgIC8vIENoZWNrIGlmIHdlJ3JlIGFjdHVhbGx5IHJlYWR5IHRvIGZpbmlzaCwgYnV0IGRvbid0IGVtaXQgeWV0XG4gICAgdmFyIGZpbmlzaGVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG5cbiAgICBpZiAoIWZpbmlzaGVkICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSB7XG4gICAgICBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG5cbiAgICBpZiAoc3luYykge1xuICAgICAgLyo8cmVwbGFjZW1lbnQ+Ki9cbiAgICAgIGFzeW5jV3JpdGUoYWZ0ZXJXcml0ZSwgc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICAgIC8qPC9yZXBsYWNlbWVudD4qL1xuICAgIH0gZWxzZSB7XG4gICAgICBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKSB7XG4gIGlmICghZmluaXNoZWQpIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKTtcbiAgc3RhdGUucGVuZGluZ2NiLS07XG4gIGNiKCk7XG4gIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xufVxuXG4vLyBNdXN0IGZvcmNlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCBvbiBuZXh0VGljaywgc28gdGhhdCB3ZSBkb24ndFxuLy8gZW1pdCAnZHJhaW4nIGJlZm9yZSB0aGUgd3JpdGUoKSBjb25zdW1lciBnZXRzIHRoZSAnZmFsc2UnIHJldHVyblxuLy8gdmFsdWUsIGFuZCBoYXMgYSBjaGFuY2UgdG8gYXR0YWNoIGEgJ2RyYWluJyBsaXN0ZW5lci5cbmZ1bmN0aW9uIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUubmVlZERyYWluKSB7XG4gICAgc3RhdGUubmVlZERyYWluID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2RyYWluJyk7XG4gIH1cbn1cblxuLy8gaWYgdGhlcmUncyBzb21ldGhpbmcgaW4gdGhlIGJ1ZmZlciB3YWl0aW5nLCB0aGVuIHByb2Nlc3MgaXRcbmZ1bmN0aW9uIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpIHtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IHRydWU7XG4gIHZhciBlbnRyeSA9IHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdDtcblxuICBpZiAoc3RyZWFtLl93cml0ZXYgJiYgZW50cnkgJiYgZW50cnkubmV4dCkge1xuICAgIC8vIEZhc3QgY2FzZSwgd3JpdGUgZXZlcnl0aGluZyB1c2luZyBfd3JpdGV2KClcbiAgICB2YXIgbCA9IHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50O1xuICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXkobCk7XG4gICAgdmFyIGhvbGRlciA9IHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZTtcbiAgICBob2xkZXIuZW50cnkgPSBlbnRyeTtcblxuICAgIHZhciBjb3VudCA9IDA7XG4gICAgdmFyIGFsbEJ1ZmZlcnMgPSB0cnVlO1xuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgYnVmZmVyW2NvdW50XSA9IGVudHJ5O1xuICAgICAgaWYgKCFlbnRyeS5pc0J1ZikgYWxsQnVmZmVycyA9IGZhbHNlO1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgICAgY291bnQgKz0gMTtcbiAgICB9XG4gICAgYnVmZmVyLmFsbEJ1ZmZlcnMgPSBhbGxCdWZmZXJzO1xuXG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB0cnVlLCBzdGF0ZS5sZW5ndGgsIGJ1ZmZlciwgJycsIGhvbGRlci5maW5pc2gpO1xuXG4gICAgLy8gZG9Xcml0ZSBpcyBhbG1vc3QgYWx3YXlzIGFzeW5jLCBkZWZlciB0aGVzZSB0byBzYXZlIGEgYml0IG9mIHRpbWVcbiAgICAvLyBhcyB0aGUgaG90IHBhdGggZW5kcyB3aXRoIGRvV3JpdGVcbiAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgICBpZiAoaG9sZGVyLm5leHQpIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IGhvbGRlci5uZXh0O1xuICAgICAgaG9sZGVyLm5leHQgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBuZXcgQ29ya2VkUmVxdWVzdChzdGF0ZSk7XG4gICAgfVxuICAgIHN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBTbG93IGNhc2UsIHdyaXRlIGNodW5rcyBvbmUtYnktb25lXG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICB2YXIgY2h1bmsgPSBlbnRyeS5jaHVuaztcbiAgICAgIHZhciBlbmNvZGluZyA9IGVudHJ5LmVuY29kaW5nO1xuICAgICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudC0tO1xuICAgICAgLy8gaWYgd2UgZGlkbid0IGNhbGwgdGhlIG9ud3JpdGUgaW1tZWRpYXRlbHksIHRoZW5cbiAgICAgIC8vIGl0IG1lYW5zIHRoYXQgd2UgbmVlZCB0byB3YWl0IHVudGlsIGl0IGRvZXMuXG4gICAgICAvLyBhbHNvLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGNodW5rIGFuZCBjYiBhcmUgY3VycmVudGx5XG4gICAgICAvLyBiZWluZyBwcm9jZXNzZWQsIHNvIG1vdmUgdGhlIGJ1ZmZlciBjb3VudGVyIHBhc3QgdGhlbS5cbiAgICAgIGlmIChzdGF0ZS53cml0aW5nKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbnRyeSA9PT0gbnVsbCkgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIH1cblxuICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBlbnRyeTtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobmV3IEVycm9yKCdfd3JpdGUoKSBpcyBub3QgaW1wbGVtZW50ZWQnKSk7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRldiA9IG51bGw7XG5cbldyaXRhYmxlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmICh0eXBlb2YgY2h1bmsgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGNodW5rO1xuICAgIGNodW5rID0gbnVsbDtcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCkgdGhpcy53cml0ZShjaHVuaywgZW5jb2RpbmcpO1xuXG4gIC8vIC5lbmQoKSBmdWxseSB1bmNvcmtzXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQgPSAxO1xuICAgIHRoaXMudW5jb3JrKCk7XG4gIH1cblxuICAvLyBpZ25vcmUgdW5uZWNlc3NhcnkgZW5kKCkgY2FsbHMuXG4gIGlmICghc3RhdGUuZW5kaW5nICYmICFzdGF0ZS5maW5pc2hlZCkgZW5kV3JpdGFibGUodGhpcywgc3RhdGUsIGNiKTtcbn07XG5cbmZ1bmN0aW9uIG5lZWRGaW5pc2goc3RhdGUpIHtcbiAgcmV0dXJuIHN0YXRlLmVuZGluZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID09PSBudWxsICYmICFzdGF0ZS5maW5pc2hlZCAmJiAhc3RhdGUud3JpdGluZztcbn1cbmZ1bmN0aW9uIGNhbGxGaW5hbChzdHJlYW0sIHN0YXRlKSB7XG4gIHN0cmVhbS5fZmluYWwoZnVuY3Rpb24gKGVycikge1xuICAgIHN0YXRlLnBlbmRpbmdjYi0tO1xuICAgIGlmIChlcnIpIHtcbiAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgfVxuICAgIHN0YXRlLnByZWZpbmlzaGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgncHJlZmluaXNoJyk7XG4gICAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIH0pO1xufVxuZnVuY3Rpb24gcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5wcmVmaW5pc2hlZCAmJiAhc3RhdGUuZmluYWxDYWxsZWQpIHtcbiAgICBpZiAodHlwZW9mIHN0cmVhbS5fZmluYWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHN0YXRlLnBlbmRpbmdjYisrO1xuICAgICAgc3RhdGUuZmluYWxDYWxsZWQgPSB0cnVlO1xuICAgICAgcG5hLm5leHRUaWNrKGNhbGxGaW5hbCwgc3RyZWFtLCBzdGF0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLnByZWZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5lbWl0KCdwcmVmaW5pc2gnKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbmVlZCA9IG5lZWRGaW5pc2goc3RhdGUpO1xuICBpZiAobmVlZCkge1xuICAgIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgICBpZiAoc3RhdGUucGVuZGluZ2NiID09PSAwKSB7XG4gICAgICBzdGF0ZS5maW5pc2hlZCA9IHRydWU7XG4gICAgICBzdHJlYW0uZW1pdCgnZmluaXNoJyk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZWVkO1xufVxuXG5mdW5jdGlvbiBlbmRXcml0YWJsZShzdHJlYW0sIHN0YXRlLCBjYikge1xuICBzdGF0ZS5lbmRpbmcgPSB0cnVlO1xuICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgaWYgKGNiKSB7XG4gICAgaWYgKHN0YXRlLmZpbmlzaGVkKSBwbmEubmV4dFRpY2soY2IpO2Vsc2Ugc3RyZWFtLm9uY2UoJ2ZpbmlzaCcsIGNiKTtcbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gIHN0cmVhbS53cml0YWJsZSA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBvbkNvcmtlZEZpbmlzaChjb3JrUmVxLCBzdGF0ZSwgZXJyKSB7XG4gIHZhciBlbnRyeSA9IGNvcmtSZXEuZW50cnk7XG4gIGNvcmtSZXEuZW50cnkgPSBudWxsO1xuICB3aGlsZSAoZW50cnkpIHtcbiAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgICBjYihlcnIpO1xuICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgfVxuICBpZiAoc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlKSB7XG4gICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlLm5leHQgPSBjb3JrUmVxO1xuICB9IGVsc2Uge1xuICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IGNvcmtSZXE7XG4gIH1cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlLnByb3RvdHlwZSwgJ2Rlc3Ryb3llZCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX3dyaXRhYmxlU3RhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgLy8gd2UgaWdub3JlIHRoZSB2YWx1ZSBpZiB0aGUgc3RyZWFtXG4gICAgLy8gaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIHlldFxuICAgIGlmICghdGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHRoZSB1c2VyIGlzIGV4cGxpY2l0bHlcbiAgICAvLyBtYW5hZ2luZyBkZXN0cm95ZWRcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZCA9IHZhbHVlO1xuICB9XG59KTtcblxuV3JpdGFibGUucHJvdG90eXBlLmRlc3Ryb3kgPSBkZXN0cm95SW1wbC5kZXN0cm95O1xuV3JpdGFibGUucHJvdG90eXBlLl91bmRlc3Ryb3kgPSBkZXN0cm95SW1wbC51bmRlc3Ryb3k7XG5Xcml0YWJsZS5wcm90b3R5cGUuX2Rlc3Ryb3kgPSBmdW5jdGlvbiAoZXJyLCBjYikge1xuICB0aGlzLmVuZCgpO1xuICBjYihlcnIpO1xufTsiLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlcjtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG5mdW5jdGlvbiBjb3B5QnVmZmVyKHNyYywgdGFyZ2V0LCBvZmZzZXQpIHtcbiAgc3JjLmNvcHkodGFyZ2V0LCBvZmZzZXQpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gQnVmZmVyTGlzdCgpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQnVmZmVyTGlzdCk7XG5cbiAgICB0aGlzLmhlYWQgPSBudWxsO1xuICAgIHRoaXMudGFpbCA9IG51bGw7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgQnVmZmVyTGlzdC5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIHB1c2godikge1xuICAgIHZhciBlbnRyeSA9IHsgZGF0YTogdiwgbmV4dDogbnVsbCB9O1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IDApIHRoaXMudGFpbC5uZXh0ID0gZW50cnk7ZWxzZSB0aGlzLmhlYWQgPSBlbnRyeTtcbiAgICB0aGlzLnRhaWwgPSBlbnRyeTtcbiAgICArK3RoaXMubGVuZ3RoO1xuICB9O1xuXG4gIEJ1ZmZlckxpc3QucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbiB1bnNoaWZ0KHYpIHtcbiAgICB2YXIgZW50cnkgPSB7IGRhdGE6IHYsIG5leHQ6IHRoaXMuaGVhZCB9O1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgdGhpcy50YWlsID0gZW50cnk7XG4gICAgdGhpcy5oZWFkID0gZW50cnk7XG4gICAgKyt0aGlzLmxlbmd0aDtcbiAgfTtcblxuICBCdWZmZXJMaXN0LnByb3RvdHlwZS5zaGlmdCA9IGZ1bmN0aW9uIHNoaWZ0KCkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIHZhciByZXQgPSB0aGlzLmhlYWQuZGF0YTtcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDEpIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7ZWxzZSB0aGlzLmhlYWQgPSB0aGlzLmhlYWQubmV4dDtcbiAgICAtLXRoaXMubGVuZ3RoO1xuICAgIHJldHVybiByZXQ7XG4gIH07XG5cbiAgQnVmZmVyTGlzdC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiBjbGVhcigpIHtcbiAgICB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgfTtcblxuICBCdWZmZXJMaXN0LnByb3RvdHlwZS5qb2luID0gZnVuY3Rpb24gam9pbihzKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gICAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gICAgdmFyIHJldCA9ICcnICsgcC5kYXRhO1xuICAgIHdoaWxlIChwID0gcC5uZXh0KSB7XG4gICAgICByZXQgKz0gcyArIHAuZGF0YTtcbiAgICB9cmV0dXJuIHJldDtcbiAgfTtcblxuICBCdWZmZXJMaXN0LnByb3RvdHlwZS5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQobikge1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKTtcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDEpIHJldHVybiB0aGlzLmhlYWQuZGF0YTtcbiAgICB2YXIgcmV0ID0gQnVmZmVyLmFsbG9jVW5zYWZlKG4gPj4+IDApO1xuICAgIHZhciBwID0gdGhpcy5oZWFkO1xuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAocCkge1xuICAgICAgY29weUJ1ZmZlcihwLmRhdGEsIHJldCwgaSk7XG4gICAgICBpICs9IHAuZGF0YS5sZW5ndGg7XG4gICAgICBwID0gcC5uZXh0O1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9O1xuXG4gIHJldHVybiBCdWZmZXJMaXN0O1xufSgpO1xuXG5pZiAodXRpbCAmJiB1dGlsLmluc3BlY3QgJiYgdXRpbC5pbnNwZWN0LmN1c3RvbSkge1xuICBtb2R1bGUuZXhwb3J0cy5wcm90b3R5cGVbdXRpbC5pbnNwZWN0LmN1c3RvbV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG9iaiA9IHV0aWwuaW5zcGVjdCh7IGxlbmd0aDogdGhpcy5sZW5ndGggfSk7XG4gICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IubmFtZSArICcgJyArIG9iajtcbiAgfTtcbn0iLCIndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBwbmEgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8vIHVuZG9jdW1lbnRlZCBjYigpIEFQSSwgbmVlZGVkIGZvciBjb3JlLCBub3QgZm9yIHB1YmxpYyBBUElcbmZ1bmN0aW9uIGRlc3Ryb3koZXJyLCBjYikge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIHZhciByZWFkYWJsZURlc3Ryb3llZCA9IHRoaXMuX3JlYWRhYmxlU3RhdGUgJiYgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG4gIHZhciB3cml0YWJsZURlc3Ryb3llZCA9IHRoaXMuX3dyaXRhYmxlU3RhdGUgJiYgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZXN0cm95ZWQ7XG5cbiAgaWYgKHJlYWRhYmxlRGVzdHJveWVkIHx8IHdyaXRhYmxlRGVzdHJveWVkKSB7XG4gICAgaWYgKGNiKSB7XG4gICAgICBjYihlcnIpO1xuICAgIH0gZWxzZSBpZiAoZXJyICYmICghdGhpcy5fd3JpdGFibGVTdGF0ZSB8fCAhdGhpcy5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQpKSB7XG4gICAgICBwbmEubmV4dFRpY2soZW1pdEVycm9yTlQsIHRoaXMsIGVycik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gd2Ugc2V0IGRlc3Ryb3llZCB0byB0cnVlIGJlZm9yZSBmaXJpbmcgZXJyb3IgY2FsbGJhY2tzIGluIG9yZGVyXG4gIC8vIHRvIG1ha2UgaXQgcmUtZW50cmFuY2Ugc2FmZSBpbiBjYXNlIGRlc3Ryb3koKSBpcyBjYWxsZWQgd2l0aGluIGNhbGxiYWNrc1xuXG4gIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlKSB7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZXN0cm95ZWQgPSB0cnVlO1xuICB9XG5cbiAgLy8gaWYgdGhpcyBpcyBhIGR1cGxleCBzdHJlYW0gbWFyayB0aGUgd3JpdGFibGUgcGFydCBhcyBkZXN0cm95ZWQgYXMgd2VsbFxuICBpZiAodGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVzdHJveWVkID0gdHJ1ZTtcbiAgfVxuXG4gIHRoaXMuX2Rlc3Ryb3koZXJyIHx8IG51bGwsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBpZiAoIWNiICYmIGVycikge1xuICAgICAgcG5hLm5leHRUaWNrKGVtaXRFcnJvck5ULCBfdGhpcywgZXJyKTtcbiAgICAgIGlmIChfdGhpcy5fd3JpdGFibGVTdGF0ZSkge1xuICAgICAgICBfdGhpcy5fd3JpdGFibGVTdGF0ZS5lcnJvckVtaXR0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY2IpIHtcbiAgICAgIGNiKGVycik7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gdW5kZXN0cm95KCkge1xuICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZSkge1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZGVzdHJveWVkID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmRlZCA9IGZhbHNlO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKHRoaXMuX3dyaXRhYmxlU3RhdGUpIHtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmRlc3Ryb3llZCA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuX3dyaXRhYmxlU3RhdGUuZmluaXNoZWQgPSBmYWxzZTtcbiAgICB0aGlzLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRFcnJvck5UKHNlbGYsIGVycikge1xuICBzZWxmLmVtaXQoJ2Vycm9yJywgZXJyKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGRlc3Ryb3k6IGRlc3Ryb3ksXG4gIHVuZGVzdHJveTogdW5kZXN0cm95XG59OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL3JlYWRhYmxlJykuUGFzc1Rocm91Z2hcbiIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fcmVhZGFibGUuanMnKTtcbmV4cG9ydHMuU3RyZWFtID0gZXhwb3J0cztcbmV4cG9ydHMuUmVhZGFibGUgPSBleHBvcnRzO1xuZXhwb3J0cy5Xcml0YWJsZSA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fd3JpdGFibGUuanMnKTtcbmV4cG9ydHMuRHVwbGV4ID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9kdXBsZXguanMnKTtcbmV4cG9ydHMuVHJhbnNmb3JtID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanMnKTtcbmV4cG9ydHMuUGFzc1Rocm91Z2ggPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzJyk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vcmVhZGFibGUnKS5UcmFuc2Zvcm1cbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV93cml0YWJsZS5qcycpO1xuIiwiJ3VzZSBzdHJpY3QnXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaEJhc2UgPSByZXF1aXJlKCdoYXNoLWJhc2UnKVxuXG52YXIgQVJSQVkxNiA9IG5ldyBBcnJheSgxNilcblxudmFyIHpsID0gW1xuICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LFxuICA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LFxuICAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLFxuICAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLFxuICA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXG5dXG5cbnZhciB6ciA9IFtcbiAgNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMixcbiAgNiwgMTEsIDMsIDcsIDAsIDEzLCA1LCAxMCwgMTQsIDE1LCA4LCAxMiwgNCwgOSwgMSwgMixcbiAgMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxMyxcbiAgOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNCxcbiAgMTIsIDE1LCAxMCwgNCwgMSwgNSwgOCwgNywgNiwgMiwgMTMsIDE0LCAwLCAzLCA5LCAxMVxuXVxuXG52YXIgc2wgPSBbXG4gIDExLCAxNCwgMTUsIDEyLCA1LCA4LCA3LCA5LCAxMSwgMTMsIDE0LCAxNSwgNiwgNywgOSwgOCxcbiAgNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyLFxuICAxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDUsXG4gIDExLCAxMiwgMTQsIDE1LCAxNCwgMTUsIDksIDgsIDksIDE0LCA1LCA2LCA4LCA2LCA1LCAxMixcbiAgOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XG5dXG5cbnZhciBzciA9IFtcbiAgOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2LFxuICA5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTEsXG4gIDksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNSxcbiAgMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4LFxuICA4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFcbl1cblxudmFyIGhsID0gWzB4MDAwMDAwMDAsIDB4NWE4Mjc5OTksIDB4NmVkOWViYTEsIDB4OGYxYmJjZGMsIDB4YTk1M2ZkNGVdXG52YXIgaHIgPSBbMHg1MGEyOGJlNiwgMHg1YzRkZDEyNCwgMHg2ZDcwM2VmMywgMHg3YTZkNzZlOSwgMHgwMDAwMDAwMF1cblxuZnVuY3Rpb24gUklQRU1EMTYwICgpIHtcbiAgSGFzaEJhc2UuY2FsbCh0aGlzLCA2NClcblxuICAvLyBzdGF0ZVxuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxuICB0aGlzLl9lID0gMHhjM2QyZTFmMFxufVxuXG5pbmhlcml0cyhSSVBFTUQxNjAsIEhhc2hCYXNlKVxuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB3b3JkcyA9IEFSUkFZMTZcbiAgZm9yICh2YXIgaiA9IDA7IGogPCAxNjsgKytqKSB3b3Jkc1tqXSA9IHRoaXMuX2Jsb2NrLnJlYWRJbnQzMkxFKGogKiA0KVxuXG4gIHZhciBhbCA9IHRoaXMuX2EgfCAwXG4gIHZhciBibCA9IHRoaXMuX2IgfCAwXG4gIHZhciBjbCA9IHRoaXMuX2MgfCAwXG4gIHZhciBkbCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlbCA9IHRoaXMuX2UgfCAwXG5cbiAgdmFyIGFyID0gdGhpcy5fYSB8IDBcbiAgdmFyIGJyID0gdGhpcy5fYiB8IDBcbiAgdmFyIGNyID0gdGhpcy5fYyB8IDBcbiAgdmFyIGRyID0gdGhpcy5fZCB8IDBcbiAgdmFyIGVyID0gdGhpcy5fZSB8IDBcblxuICAvLyBjb21wdXRhdGlvblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDgwOyBpICs9IDEpIHtcbiAgICB2YXIgdGxcbiAgICB2YXIgdHJcbiAgICBpZiAoaSA8IDE2KSB7XG4gICAgICB0bCA9IGZuMShhbCwgYmwsIGNsLCBkbCwgZWwsIHdvcmRzW3psW2ldXSwgaGxbMF0sIHNsW2ldKVxuICAgICAgdHIgPSBmbjUoYXIsIGJyLCBjciwgZHIsIGVyLCB3b3Jkc1t6cltpXV0sIGhyWzBdLCBzcltpXSlcbiAgICB9IGVsc2UgaWYgKGkgPCAzMikge1xuICAgICAgdGwgPSBmbjIoYWwsIGJsLCBjbCwgZGwsIGVsLCB3b3Jkc1t6bFtpXV0sIGhsWzFdLCBzbFtpXSlcbiAgICAgIHRyID0gZm40KGFyLCBiciwgY3IsIGRyLCBlciwgd29yZHNbenJbaV1dLCBoclsxXSwgc3JbaV0pXG4gICAgfSBlbHNlIGlmIChpIDwgNDgpIHtcbiAgICAgIHRsID0gZm4zKGFsLCBibCwgY2wsIGRsLCBlbCwgd29yZHNbemxbaV1dLCBobFsyXSwgc2xbaV0pXG4gICAgICB0ciA9IGZuMyhhciwgYnIsIGNyLCBkciwgZXIsIHdvcmRzW3pyW2ldXSwgaHJbMl0sIHNyW2ldKVxuICAgIH0gZWxzZSBpZiAoaSA8IDY0KSB7XG4gICAgICB0bCA9IGZuNChhbCwgYmwsIGNsLCBkbCwgZWwsIHdvcmRzW3psW2ldXSwgaGxbM10sIHNsW2ldKVxuICAgICAgdHIgPSBmbjIoYXIsIGJyLCBjciwgZHIsIGVyLCB3b3Jkc1t6cltpXV0sIGhyWzNdLCBzcltpXSlcbiAgICB9IGVsc2UgeyAvLyBpZiAoaTw4MCkge1xuICAgICAgdGwgPSBmbjUoYWwsIGJsLCBjbCwgZGwsIGVsLCB3b3Jkc1t6bFtpXV0sIGhsWzRdLCBzbFtpXSlcbiAgICAgIHRyID0gZm4xKGFyLCBiciwgY3IsIGRyLCBlciwgd29yZHNbenJbaV1dLCBocls0XSwgc3JbaV0pXG4gICAgfVxuXG4gICAgYWwgPSBlbFxuICAgIGVsID0gZGxcbiAgICBkbCA9IHJvdGwoY2wsIDEwKVxuICAgIGNsID0gYmxcbiAgICBibCA9IHRsXG5cbiAgICBhciA9IGVyXG4gICAgZXIgPSBkclxuICAgIGRyID0gcm90bChjciwgMTApXG4gICAgY3IgPSBiclxuICAgIGJyID0gdHJcbiAgfVxuXG4gIC8vIHVwZGF0ZSBzdGF0ZVxuICB2YXIgdCA9ICh0aGlzLl9iICsgY2wgKyBkcikgfCAwXG4gIHRoaXMuX2IgPSAodGhpcy5fYyArIGRsICsgZXIpIHwgMFxuICB0aGlzLl9jID0gKHRoaXMuX2QgKyBlbCArIGFyKSB8IDBcbiAgdGhpcy5fZCA9ICh0aGlzLl9lICsgYWwgKyBicikgfCAwXG4gIHRoaXMuX2UgPSAodGhpcy5fYSArIGJsICsgY3IpIHwgMFxuICB0aGlzLl9hID0gdFxufVxuXG5SSVBFTUQxNjAucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIGNyZWF0ZSBwYWRkaW5nIGFuZCBoYW5kbGUgYmxvY2tzXG4gIHRoaXMuX2Jsb2NrW3RoaXMuX2Jsb2NrT2Zmc2V0KytdID0gMHg4MFxuICBpZiAodGhpcy5fYmxvY2tPZmZzZXQgPiA1Nikge1xuICAgIHRoaXMuX2Jsb2NrLmZpbGwoMCwgdGhpcy5fYmxvY2tPZmZzZXQsIDY0KVxuICAgIHRoaXMuX3VwZGF0ZSgpXG4gICAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIH1cblxuICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMF0sIDU2KVxuICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkxFKHRoaXMuX2xlbmd0aFsxXSwgNjApXG4gIHRoaXMuX3VwZGF0ZSgpXG5cbiAgLy8gcHJvZHVjZSByZXN1bHRcbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyA/IEJ1ZmZlci5hbGxvYygyMCkgOiBuZXcgQnVmZmVyKDIwKVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2EsIDApXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYiwgNClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9jLCA4KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2QsIDEyKVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2UsIDE2KVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIHJvdGwgKHgsIG4pIHtcbiAgcmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKVxufVxuXG5mdW5jdGlvbiBmbjEgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKGIgXiBjIF4gZCkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5mdW5jdGlvbiBmbjIgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiICYgYykgfCAoKH5iKSAmIGQpKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbmZ1bmN0aW9uIGZuMyAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgfCAofmMpKSBeIGQpICsgbSArIGspIHwgMCwgcykgKyBlKSB8IDBcbn1cblxuZnVuY3Rpb24gZm40IChhLCBiLCBjLCBkLCBlLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYiAmIGQpIHwgKGMgJiAofmQpKSkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5mdW5jdGlvbiBmbjUgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKGIgXiAoYyB8ICh+ZCkpKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUklQRU1EMTYwXG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBub2RlL25vLWRlcHJlY2F0ZWQtYXBpICovXG52YXIgYnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJylcbnZhciBCdWZmZXIgPSBidWZmZXIuQnVmZmVyXG5cbi8vIGFsdGVybmF0aXZlIHRvIHVzaW5nIE9iamVjdC5rZXlzIGZvciBvbGQgYnJvd3NlcnNcbmZ1bmN0aW9uIGNvcHlQcm9wcyAoc3JjLCBkc3QpIHtcbiAgZm9yICh2YXIga2V5IGluIHNyYykge1xuICAgIGRzdFtrZXldID0gc3JjW2tleV1cbiAgfVxufVxuaWYgKEJ1ZmZlci5mcm9tICYmIEJ1ZmZlci5hbGxvYyAmJiBCdWZmZXIuYWxsb2NVbnNhZmUgJiYgQnVmZmVyLmFsbG9jVW5zYWZlU2xvdykge1xuICBtb2R1bGUuZXhwb3J0cyA9IGJ1ZmZlclxufSBlbHNlIHtcbiAgLy8gQ29weSBwcm9wZXJ0aWVzIGZyb20gcmVxdWlyZSgnYnVmZmVyJylcbiAgY29weVByb3BzKGJ1ZmZlciwgZXhwb3J0cylcbiAgZXhwb3J0cy5CdWZmZXIgPSBTYWZlQnVmZmVyXG59XG5cbmZ1bmN0aW9uIFNhZmVCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIENvcHkgc3RhdGljIG1ldGhvZHMgZnJvbSBCdWZmZXJcbmNvcHlQcm9wcyhCdWZmZXIsIFNhZmVCdWZmZXIpXG5cblNhZmVCdWZmZXIuZnJvbSA9IGZ1bmN0aW9uIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuU2FmZUJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgdmFyIGJ1ZiA9IEJ1ZmZlcihzaXplKVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgIH0gZWxzZSB7XG4gICAgICBidWYuZmlsbChmaWxsKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBidWYuZmlsbCgwKVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKHNpemUpXG59XG5cblNhZmVCdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBidWZmZXIuU2xvd0J1ZmZlcihzaXplKVxufVxuIiwiIWZ1bmN0aW9uKGdsb2JhbHMpe1xuJ3VzZSBzdHJpY3QnXG5cbi8vKioqIFVNRCBCRUdJTlxuaWYgKHR5cGVvZiBkZWZpbmUgIT09ICd1bmRlZmluZWQnICYmIGRlZmluZS5hbWQpIHsgLy9yZXF1aXJlLmpzIC8gQU1EXG4gIGRlZmluZShbXSwgZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNlY3VyZVJhbmRvbVxuICB9KVxufSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykgeyAvL0NvbW1vbkpTXG4gIG1vZHVsZS5leHBvcnRzID0gc2VjdXJlUmFuZG9tXG59IGVsc2UgeyAvL3NjcmlwdCAvIGJyb3dzZXJcbiAgZ2xvYmFscy5zZWN1cmVSYW5kb20gPSBzZWN1cmVSYW5kb21cbn1cbi8vKioqIFVNRCBFTkRcblxuLy9vcHRpb25zLnR5cGUgaXMgdGhlIG9ubHkgdmFsaWQgb3B0aW9uXG5mdW5jdGlvbiBzZWN1cmVSYW5kb20oY291bnQsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge3R5cGU6ICdBcnJheSd9XG4gIC8vd2UgY2hlY2sgZm9yIHByb2Nlc3MucGlkIHRvIHByZXZlbnQgYnJvd3NlcmlmeSBmcm9tIHRyaWNraW5nIHVzXG4gIGlmICh0eXBlb2YgcHJvY2VzcyAhPSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgcHJvY2Vzcy5waWQgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gbm9kZVJhbmRvbShjb3VudCwgb3B0aW9ucylcbiAgfSBlbHNlIHtcbiAgICB2YXIgY3J5cHRvID0gd2luZG93LmNyeXB0byB8fCB3aW5kb3cubXNDcnlwdG9cbiAgICBpZiAoIWNyeXB0bykgdGhyb3cgbmV3IEVycm9yKFwiWW91ciBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgd2luZG93LmNyeXB0by5cIilcbiAgICByZXR1cm4gYnJvd3NlclJhbmRvbShjb3VudCwgb3B0aW9ucylcbiAgfVxufVxuXG5mdW5jdGlvbiBub2RlUmFuZG9tKGNvdW50LCBvcHRpb25zKSB7XG4gIHZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKVxuICB2YXIgYnVmID0gY3J5cHRvLnJhbmRvbUJ5dGVzKGNvdW50KVxuXG4gIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIFtdLnNsaWNlLmNhbGwoYnVmKVxuICAgIGNhc2UgJ0J1ZmZlcic6XG4gICAgICByZXR1cm4gYnVmXG4gICAgY2FzZSAnVWludDhBcnJheSc6XG4gICAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoY291bnQpXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsgYXJyW2ldID0gYnVmLnJlYWRVSW50OChpKSB9XG4gICAgICByZXR1cm4gYXJyXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihvcHRpb25zLnR5cGUgKyBcIiBpcyB1bnN1cHBvcnRlZC5cIilcbiAgfVxufVxuXG5mdW5jdGlvbiBicm93c2VyUmFuZG9tKGNvdW50LCBvcHRpb25zKSB7XG4gIHZhciBuYXRpdmVBcnIgPSBuZXcgVWludDhBcnJheShjb3VudClcbiAgdmFyIGNyeXB0byA9IHdpbmRvdy5jcnlwdG8gfHwgd2luZG93Lm1zQ3J5cHRvXG4gIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmF0aXZlQXJyKVxuXG4gIHN3aXRjaCAob3B0aW9ucy50eXBlKSB7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIFtdLnNsaWNlLmNhbGwobmF0aXZlQXJyKVxuICAgIGNhc2UgJ0J1ZmZlcic6XG4gICAgICB0cnkgeyB2YXIgYiA9IG5ldyBCdWZmZXIoMSkgfSBjYXRjaChlKSB7IHRocm93IG5ldyBFcnJvcignQnVmZmVyIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBlbnZpcm9ubWVudC4gVXNlIE5vZGUuanMgb3IgQnJvd3NlcmlmeSBmb3IgYnJvd3NlciBzdXBwb3J0LicpfVxuICAgICAgcmV0dXJuIG5ldyBCdWZmZXIobmF0aXZlQXJyKVxuICAgIGNhc2UgJ1VpbnQ4QXJyYXknOlxuICAgICAgcmV0dXJuIG5hdGl2ZUFyclxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3Iob3B0aW9ucy50eXBlICsgXCIgaXMgdW5zdXBwb3J0ZWQuXCIpXG4gIH1cbn1cblxuc2VjdXJlUmFuZG9tLnJhbmRvbUFycmF5ID0gZnVuY3Rpb24oYnl0ZUNvdW50KSB7XG4gIHJldHVybiBzZWN1cmVSYW5kb20oYnl0ZUNvdW50LCB7dHlwZTogJ0FycmF5J30pXG59XG5cbnNlY3VyZVJhbmRvbS5yYW5kb21VaW50OEFycmF5ID0gZnVuY3Rpb24oYnl0ZUNvdW50KSB7XG4gIHJldHVybiBzZWN1cmVSYW5kb20oYnl0ZUNvdW50LCB7dHlwZTogJ1VpbnQ4QXJyYXknfSlcbn1cblxuc2VjdXJlUmFuZG9tLnJhbmRvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ5dGVDb3VudCkge1xuICByZXR1cm4gc2VjdXJlUmFuZG9tKGJ5dGVDb3VudCwge3R5cGU6ICdCdWZmZXInfSlcbn1cblxuXG59KHRoaXMpO1xuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbi8vIHByb3RvdHlwZSBjbGFzcyBmb3IgaGFzaCBmdW5jdGlvbnNcbmZ1bmN0aW9uIEhhc2ggKGJsb2NrU2l6ZSwgZmluYWxTaXplKSB7XG4gIHRoaXMuX2Jsb2NrID0gQnVmZmVyLmFsbG9jKGJsb2NrU2l6ZSlcbiAgdGhpcy5fZmluYWxTaXplID0gZmluYWxTaXplXG4gIHRoaXMuX2Jsb2NrU2l6ZSA9IGJsb2NrU2l6ZVxuICB0aGlzLl9sZW4gPSAwXG59XG5cbkhhc2gucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBlbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGVuYyA9IGVuYyB8fCAndXRmOCdcbiAgICBkYXRhID0gQnVmZmVyLmZyb20oZGF0YSwgZW5jKVxuICB9XG5cbiAgdmFyIGJsb2NrID0gdGhpcy5fYmxvY2tcbiAgdmFyIGJsb2NrU2l6ZSA9IHRoaXMuX2Jsb2NrU2l6ZVxuICB2YXIgbGVuZ3RoID0gZGF0YS5sZW5ndGhcbiAgdmFyIGFjY3VtID0gdGhpcy5fbGVuXG5cbiAgZm9yICh2YXIgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgbGVuZ3RoOykge1xuICAgIHZhciBhc3NpZ25lZCA9IGFjY3VtICUgYmxvY2tTaXplXG4gICAgdmFyIHJlbWFpbmRlciA9IE1hdGgubWluKGxlbmd0aCAtIG9mZnNldCwgYmxvY2tTaXplIC0gYXNzaWduZWQpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlbWFpbmRlcjsgaSsrKSB7XG4gICAgICBibG9ja1thc3NpZ25lZCArIGldID0gZGF0YVtvZmZzZXQgKyBpXVxuICAgIH1cblxuICAgIGFjY3VtICs9IHJlbWFpbmRlclxuICAgIG9mZnNldCArPSByZW1haW5kZXJcblxuICAgIGlmICgoYWNjdW0gJSBibG9ja1NpemUpID09PSAwKSB7XG4gICAgICB0aGlzLl91cGRhdGUoYmxvY2spXG4gICAgfVxuICB9XG5cbiAgdGhpcy5fbGVuICs9IGxlbmd0aFxuICByZXR1cm4gdGhpc1xufVxuXG5IYXNoLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiAoZW5jKSB7XG4gIHZhciByZW0gPSB0aGlzLl9sZW4gJSB0aGlzLl9ibG9ja1NpemVcblxuICB0aGlzLl9ibG9ja1tyZW1dID0gMHg4MFxuXG4gIC8vIHplcm8gKHJlbSArIDEpIHRyYWlsaW5nIGJpdHMsIHdoZXJlIChyZW0gKyAxKSBpcyB0aGUgc21hbGxlc3RcbiAgLy8gbm9uLW5lZ2F0aXZlIHNvbHV0aW9uIHRvIHRoZSBlcXVhdGlvbiAobGVuZ3RoICsgMSArIChyZW0gKyAxKSkgPT09IGZpbmFsU2l6ZSBtb2QgYmxvY2tTaXplXG4gIHRoaXMuX2Jsb2NrLmZpbGwoMCwgcmVtICsgMSlcblxuICBpZiAocmVtID49IHRoaXMuX2ZpbmFsU2l6ZSkge1xuICAgIHRoaXMuX3VwZGF0ZSh0aGlzLl9ibG9jaylcbiAgICB0aGlzLl9ibG9jay5maWxsKDApXG4gIH1cblxuICB2YXIgYml0cyA9IHRoaXMuX2xlbiAqIDhcblxuICAvLyB1aW50MzJcbiAgaWYgKGJpdHMgPD0gMHhmZmZmZmZmZikge1xuICAgIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyQkUoYml0cywgdGhpcy5fYmxvY2tTaXplIC0gNClcblxuICAvLyB1aW50NjRcbiAgfSBlbHNlIHtcbiAgICB2YXIgbG93Qml0cyA9IChiaXRzICYgMHhmZmZmZmZmZikgPj4+IDBcbiAgICB2YXIgaGlnaEJpdHMgPSAoYml0cyAtIGxvd0JpdHMpIC8gMHgxMDAwMDAwMDBcblxuICAgIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyQkUoaGlnaEJpdHMsIHRoaXMuX2Jsb2NrU2l6ZSAtIDgpXG4gICAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJCRShsb3dCaXRzLCB0aGlzLl9ibG9ja1NpemUgLSA0KVxuICB9XG5cbiAgdGhpcy5fdXBkYXRlKHRoaXMuX2Jsb2NrKVxuICB2YXIgaGFzaCA9IHRoaXMuX2hhc2goKVxuXG4gIHJldHVybiBlbmMgPyBoYXNoLnRvU3RyaW5nKGVuYykgOiBoYXNoXG59XG5cbkhhc2gucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignX3VwZGF0ZSBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzJylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBIYXNoXG4iLCJ2YXIgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gU0hBIChhbGdvcml0aG0pIHtcbiAgYWxnb3JpdGhtID0gYWxnb3JpdGhtLnRvTG93ZXJDYXNlKClcblxuICB2YXIgQWxnb3JpdGhtID0gZXhwb3J0c1thbGdvcml0aG1dXG4gIGlmICghQWxnb3JpdGhtKSB0aHJvdyBuZXcgRXJyb3IoYWxnb3JpdGhtICsgJyBpcyBub3Qgc3VwcG9ydGVkICh3ZSBhY2NlcHQgcHVsbCByZXF1ZXN0cyknKVxuXG4gIHJldHVybiBuZXcgQWxnb3JpdGhtKClcbn1cblxuZXhwb3J0cy5zaGEgPSByZXF1aXJlKCcuL3NoYScpXG5leHBvcnRzLnNoYTEgPSByZXF1aXJlKCcuL3NoYTEnKVxuZXhwb3J0cy5zaGEyMjQgPSByZXF1aXJlKCcuL3NoYTIyNCcpXG5leHBvcnRzLnNoYTI1NiA9IHJlcXVpcmUoJy4vc2hhMjU2JylcbmV4cG9ydHMuc2hhMzg0ID0gcmVxdWlyZSgnLi9zaGEzODQnKVxuZXhwb3J0cy5zaGE1MTIgPSByZXF1aXJlKCcuL3NoYTUxMicpXG4iLCIvKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0wLCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIFBVQiAxODAtMVxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBkZXJpdmVkIGZyb20gc2hhMS5qcyBvZiB0aGUgc2FtZSByZXBvc2l0b3J5LlxuICogVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBTSEEtMCBhbmQgU0hBLTEgaXMganVzdCBhIGJpdHdpc2Ugcm90YXRlIGxlZnRcbiAqIG9wZXJhdGlvbiB3YXMgYWRkZWQuXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBLID0gW1xuICAweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjIHwgMCwgMHhjYTYyYzFkNiB8IDBcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoODApXG5cbmZ1bmN0aW9uIFNoYSAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhLCBIYXNoKVxuXG5TaGEucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDY3NDUyMzAxXG4gIHRoaXMuX2IgPSAweGVmY2RhYjg5XG4gIHRoaXMuX2MgPSAweDk4YmFkY2ZlXG4gIHRoaXMuX2QgPSAweDEwMzI1NDc2XG4gIHRoaXMuX2UgPSAweGMzZDJlMWYwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gcm90bDUgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCA1KSB8IChudW0gPj4+IDI3KVxufVxuXG5mdW5jdGlvbiByb3RsMzAgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCAzMCkgfCAobnVtID4+PiAyKVxufVxuXG5mdW5jdGlvbiBmdCAocywgYiwgYywgZCkge1xuICBpZiAocyA9PT0gMCkgcmV0dXJuIChiICYgYykgfCAoKH5iKSAmIGQpXG4gIGlmIChzID09PSAyKSByZXR1cm4gKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpXG4gIHJldHVybiBiIF4gYyBeIGRcbn1cblxuU2hhLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hIHwgMFxuICB2YXIgYiA9IHRoaXMuX2IgfCAwXG4gIHZhciBjID0gdGhpcy5fYyB8IDBcbiAgdmFyIGQgPSB0aGlzLl9kIHwgMFxuICB2YXIgZSA9IHRoaXMuX2UgfCAwXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgKytpKSBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgZm9yICg7IGkgPCA4MDsgKytpKSBXW2ldID0gV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XVxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7ICsraikge1xuICAgIHZhciBzID0gfn4oaiAvIDIwKVxuICAgIHZhciB0ID0gKHJvdGw1KGEpICsgZnQocywgYiwgYywgZCkgKyBlICsgV1tqXSArIEtbc10pIHwgMFxuXG4gICAgZSA9IGRcbiAgICBkID0gY1xuICAgIGMgPSByb3RsMzAoYilcbiAgICBiID0gYVxuICAgIGEgPSB0XG4gIH1cblxuICB0aGlzLl9hID0gKGEgKyB0aGlzLl9hKSB8IDBcbiAgdGhpcy5fYiA9IChiICsgdGhpcy5fYikgfCAwXG4gIHRoaXMuX2MgPSAoYyArIHRoaXMuX2MpIHwgMFxuICB0aGlzLl9kID0gKGQgKyB0aGlzLl9kKSB8IDBcbiAgdGhpcy5fZSA9IChlICsgdGhpcy5fZSkgfCAwXG59XG5cblNoYS5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDIwKVxuXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2EgfCAwLCAwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9iIHwgMCwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYyB8IDAsIDgpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2QgfCAwLCAxMilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZSB8IDAsIDE2KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhXG4iLCIvKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0xLCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIFBVQiAxODAtMVxuICogVmVyc2lvbiAyLjFhIENvcHlyaWdodCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDAyLlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlXG4gKiBTZWUgaHR0cDovL3BhamhvbWUub3JnLnVrL2NyeXB0L21kNSBmb3IgZGV0YWlscy5cbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxudmFyIEsgPSBbXG4gIDB4NWE4Mjc5OTksIDB4NmVkOWViYTEsIDB4OGYxYmJjZGMgfCAwLCAweGNhNjJjMWQ2IHwgMFxuXVxuXG52YXIgVyA9IG5ldyBBcnJheSg4MClcblxuZnVuY3Rpb24gU2hhMSAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhMSwgSGFzaClcblxuU2hhMS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4Njc0NTIzMDFcbiAgdGhpcy5fYiA9IDB4ZWZjZGFiODlcbiAgdGhpcy5fYyA9IDB4OThiYWRjZmVcbiAgdGhpcy5fZCA9IDB4MTAzMjU0NzZcbiAgdGhpcy5fZSA9IDB4YzNkMmUxZjBcblxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiByb3RsMSAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDEpIHwgKG51bSA+Pj4gMzEpXG59XG5cbmZ1bmN0aW9uIHJvdGw1IChudW0pIHtcbiAgcmV0dXJuIChudW0gPDwgNSkgfCAobnVtID4+PiAyNylcbn1cblxuZnVuY3Rpb24gcm90bDMwIChudW0pIHtcbiAgcmV0dXJuIChudW0gPDwgMzApIHwgKG51bSA+Pj4gMilcbn1cblxuZnVuY3Rpb24gZnQgKHMsIGIsIGMsIGQpIHtcbiAgaWYgKHMgPT09IDApIHJldHVybiAoYiAmIGMpIHwgKCh+YikgJiBkKVxuICBpZiAocyA9PT0gMikgcmV0dXJuIChiICYgYykgfCAoYiAmIGQpIHwgKGMgJiBkKVxuICByZXR1cm4gYiBeIGMgXiBkXG59XG5cblNoYTEucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYSA9IHRoaXMuX2EgfCAwXG4gIHZhciBiID0gdGhpcy5fYiB8IDBcbiAgdmFyIGMgPSB0aGlzLl9jIHwgMFxuICB2YXIgZCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlID0gdGhpcy5fZSB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIFdbaV0gPSBNLnJlYWRJbnQzMkJFKGkgKiA0KVxuICBmb3IgKDsgaSA8IDgwOyArK2kpIFdbaV0gPSByb3RsMShXW2kgLSAzXSBeIFdbaSAtIDhdIF4gV1tpIC0gMTRdIF4gV1tpIC0gMTZdKVxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7ICsraikge1xuICAgIHZhciBzID0gfn4oaiAvIDIwKVxuICAgIHZhciB0ID0gKHJvdGw1KGEpICsgZnQocywgYiwgYywgZCkgKyBlICsgV1tqXSArIEtbc10pIHwgMFxuXG4gICAgZSA9IGRcbiAgICBkID0gY1xuICAgIGMgPSByb3RsMzAoYilcbiAgICBiID0gYVxuICAgIGEgPSB0XG4gIH1cblxuICB0aGlzLl9hID0gKGEgKyB0aGlzLl9hKSB8IDBcbiAgdGhpcy5fYiA9IChiICsgdGhpcy5fYikgfCAwXG4gIHRoaXMuX2MgPSAoYyArIHRoaXMuX2MpIHwgMFxuICB0aGlzLl9kID0gKGQgKyB0aGlzLl9kKSB8IDBcbiAgdGhpcy5fZSA9IChlICsgdGhpcy5fZSkgfCAwXG59XG5cblNoYTEucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgyMClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hIHwgMCwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiB8IDAsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MgfCAwLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kIHwgMCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UgfCAwLCAxNilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTFcbiIsIi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgU2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEyNTYnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBXID0gbmV3IEFycmF5KDY0KVxuXG5mdW5jdGlvbiBTaGEyMjQgKCkge1xuICB0aGlzLmluaXQoKVxuXG4gIHRoaXMuX3cgPSBXIC8vIG5ldyBBcnJheSg2NClcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGEyMjQsIFNoYTI1NilcblxuU2hhMjI0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHhjMTA1OWVkOFxuICB0aGlzLl9iID0gMHgzNjdjZDUwN1xuICB0aGlzLl9jID0gMHgzMDcwZGQxN1xuICB0aGlzLl9kID0gMHhmNzBlNTkzOVxuICB0aGlzLl9lID0gMHhmZmMwMGIzMVxuICB0aGlzLl9mID0gMHg2ODU4MTUxMVxuICB0aGlzLl9nID0gMHg2NGY5OGZhN1xuICB0aGlzLl9oID0gMHhiZWZhNGZhNFxuXG4gIHJldHVybiB0aGlzXG59XG5cblNoYTIyNC5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDI4KVxuXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2EsIDApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2IsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MsIDgpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2QsIDEyKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9lLCAxNilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZiwgMjApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2csIDI0KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMjI0XG4iLCIvKipcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMjU2LCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIDE4MC0yXG4gKiBWZXJzaW9uIDIuMi1iZXRhIENvcHlyaWdodCBBbmdlbCBNYXJpbiwgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwOS5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBLID0gW1xuICAweDQyOEEyRjk4LCAweDcxMzc0NDkxLCAweEI1QzBGQkNGLCAweEU5QjVEQkE1LFxuICAweDM5NTZDMjVCLCAweDU5RjExMUYxLCAweDkyM0Y4MkE0LCAweEFCMUM1RUQ1LFxuICAweEQ4MDdBQTk4LCAweDEyODM1QjAxLCAweDI0MzE4NUJFLCAweDU1MEM3REMzLFxuICAweDcyQkU1RDc0LCAweDgwREVCMUZFLCAweDlCREMwNkE3LCAweEMxOUJGMTc0LFxuICAweEU0OUI2OUMxLCAweEVGQkU0Nzg2LCAweDBGQzE5REM2LCAweDI0MENBMUNDLFxuICAweDJERTkyQzZGLCAweDRBNzQ4NEFBLCAweDVDQjBBOURDLCAweDc2Rjk4OERBLFxuICAweDk4M0U1MTUyLCAweEE4MzFDNjZELCAweEIwMDMyN0M4LCAweEJGNTk3RkM3LFxuICAweEM2RTAwQkYzLCAweEQ1QTc5MTQ3LCAweDA2Q0E2MzUxLCAweDE0MjkyOTY3LFxuICAweDI3QjcwQTg1LCAweDJFMUIyMTM4LCAweDREMkM2REZDLCAweDUzMzgwRDEzLFxuICAweDY1MEE3MzU0LCAweDc2NkEwQUJCLCAweDgxQzJDOTJFLCAweDkyNzIyQzg1LFxuICAweEEyQkZFOEExLCAweEE4MUE2NjRCLCAweEMyNEI4QjcwLCAweEM3NkM1MUEzLFxuICAweEQxOTJFODE5LCAweEQ2OTkwNjI0LCAweEY0MEUzNTg1LCAweDEwNkFBMDcwLFxuICAweDE5QTRDMTE2LCAweDFFMzc2QzA4LCAweDI3NDg3NzRDLCAweDM0QjBCQ0I1LFxuICAweDM5MUMwQ0IzLCAweDRFRDhBQTRBLCAweDVCOUNDQTRGLCAweDY4MkU2RkYzLFxuICAweDc0OEY4MkVFLCAweDc4QTU2MzZGLCAweDg0Qzg3ODE0LCAweDhDQzcwMjA4LFxuICAweDkwQkVGRkZBLCAweEE0NTA2Q0VCLCAweEJFRjlBM0Y3LCAweEM2NzE3OEYyXG5dXG5cbnZhciBXID0gbmV3IEFycmF5KDY0KVxuXG5mdW5jdGlvbiBTaGEyNTYgKCkge1xuICB0aGlzLmluaXQoKVxuXG4gIHRoaXMuX3cgPSBXIC8vIG5ldyBBcnJheSg2NClcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGEyNTYsIEhhc2gpXG5cblNoYTI1Ni5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4NmEwOWU2NjdcbiAgdGhpcy5fYiA9IDB4YmI2N2FlODVcbiAgdGhpcy5fYyA9IDB4M2M2ZWYzNzJcbiAgdGhpcy5fZCA9IDB4YTU0ZmY1M2FcbiAgdGhpcy5fZSA9IDB4NTEwZTUyN2ZcbiAgdGhpcy5fZiA9IDB4OWIwNTY4OGNcbiAgdGhpcy5fZyA9IDB4MWY4M2Q5YWJcbiAgdGhpcy5faCA9IDB4NWJlMGNkMTlcblxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBjaCAoeCwgeSwgeikge1xuICByZXR1cm4geiBeICh4ICYgKHkgXiB6KSlcbn1cblxuZnVuY3Rpb24gbWFqICh4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIHwgKHogJiAoeCB8IHkpKVxufVxuXG5mdW5jdGlvbiBzaWdtYTAgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiAyIHwgeCA8PCAzMCkgXiAoeCA+Pj4gMTMgfCB4IDw8IDE5KSBeICh4ID4+PiAyMiB8IHggPDwgMTApXG59XG5cbmZ1bmN0aW9uIHNpZ21hMSAoeCkge1xuICByZXR1cm4gKHggPj4+IDYgfCB4IDw8IDI2KSBeICh4ID4+PiAxMSB8IHggPDwgMjEpIF4gKHggPj4+IDI1IHwgeCA8PCA3KVxufVxuXG5mdW5jdGlvbiBnYW1tYTAgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiA3IHwgeCA8PCAyNSkgXiAoeCA+Pj4gMTggfCB4IDw8IDE0KSBeICh4ID4+PiAzKVxufVxuXG5mdW5jdGlvbiBnYW1tYTEgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiAxNyB8IHggPDwgMTUpIF4gKHggPj4+IDE5IHwgeCA8PCAxMykgXiAoeCA+Pj4gMTApXG59XG5cblNoYTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYSB8IDBcbiAgdmFyIGIgPSB0aGlzLl9iIHwgMFxuICB2YXIgYyA9IHRoaXMuX2MgfCAwXG4gIHZhciBkID0gdGhpcy5fZCB8IDBcbiAgdmFyIGUgPSB0aGlzLl9lIHwgMFxuICB2YXIgZiA9IHRoaXMuX2YgfCAwXG4gIHZhciBnID0gdGhpcy5fZyB8IDBcbiAgdmFyIGggPSB0aGlzLl9oIHwgMFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7ICsraSkgV1tpXSA9IE0ucmVhZEludDMyQkUoaSAqIDQpXG4gIGZvciAoOyBpIDwgNjQ7ICsraSkgV1tpXSA9IChnYW1tYTEoV1tpIC0gMl0pICsgV1tpIC0gN10gKyBnYW1tYTAoV1tpIC0gMTVdKSArIFdbaSAtIDE2XSkgfCAwXG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCA2NDsgKytqKSB7XG4gICAgdmFyIFQxID0gKGggKyBzaWdtYTEoZSkgKyBjaChlLCBmLCBnKSArIEtbal0gKyBXW2pdKSB8IDBcbiAgICB2YXIgVDIgPSAoc2lnbWEwKGEpICsgbWFqKGEsIGIsIGMpKSB8IDBcblxuICAgIGggPSBnXG4gICAgZyA9IGZcbiAgICBmID0gZVxuICAgIGUgPSAoZCArIFQxKSB8IDBcbiAgICBkID0gY1xuICAgIGMgPSBiXG4gICAgYiA9IGFcbiAgICBhID0gKFQxICsgVDIpIHwgMFxuICB9XG5cbiAgdGhpcy5fYSA9IChhICsgdGhpcy5fYSkgfCAwXG4gIHRoaXMuX2IgPSAoYiArIHRoaXMuX2IpIHwgMFxuICB0aGlzLl9jID0gKGMgKyB0aGlzLl9jKSB8IDBcbiAgdGhpcy5fZCA9IChkICsgdGhpcy5fZCkgfCAwXG4gIHRoaXMuX2UgPSAoZSArIHRoaXMuX2UpIHwgMFxuICB0aGlzLl9mID0gKGYgKyB0aGlzLl9mKSB8IDBcbiAgdGhpcy5fZyA9IChnICsgdGhpcy5fZykgfCAwXG4gIHRoaXMuX2ggPSAoaCArIHRoaXMuX2gpIHwgMFxufVxuXG5TaGEyNTYucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgzMilcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hLCAwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9iLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kLCAxMilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZSwgMTYpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2YsIDIwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9nLCAyNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5faCwgMjgpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEyNTZcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBTSEE1MTIgPSByZXF1aXJlKCcuL3NoYTUxMicpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxudmFyIFcgPSBuZXcgQXJyYXkoMTYwKVxuXG5mdW5jdGlvbiBTaGEzODQgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCAxMjgsIDExMilcbn1cblxuaW5oZXJpdHMoU2hhMzg0LCBTSEE1MTIpXG5cblNoYTM4NC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYWggPSAweGNiYmI5ZDVkXG4gIHRoaXMuX2JoID0gMHg2MjlhMjkyYVxuICB0aGlzLl9jaCA9IDB4OTE1OTAxNWFcbiAgdGhpcy5fZGggPSAweDE1MmZlY2Q4XG4gIHRoaXMuX2VoID0gMHg2NzMzMjY2N1xuICB0aGlzLl9maCA9IDB4OGViNDRhODdcbiAgdGhpcy5fZ2ggPSAweGRiMGMyZTBkXG4gIHRoaXMuX2hoID0gMHg0N2I1NDgxZFxuXG4gIHRoaXMuX2FsID0gMHhjMTA1OWVkOFxuICB0aGlzLl9ibCA9IDB4MzY3Y2Q1MDdcbiAgdGhpcy5fY2wgPSAweDMwNzBkZDE3XG4gIHRoaXMuX2RsID0gMHhmNzBlNTkzOVxuICB0aGlzLl9lbCA9IDB4ZmZjMDBiMzFcbiAgdGhpcy5fZmwgPSAweDY4NTgxNTExXG4gIHRoaXMuX2dsID0gMHg2NGY5OGZhN1xuICB0aGlzLl9obCA9IDB4YmVmYTRmYTRcblxuICByZXR1cm4gdGhpc1xufVxuXG5TaGEzODQucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSg0OClcblxuICBmdW5jdGlvbiB3cml0ZUludDY0QkUgKGgsIGwsIG9mZnNldCkge1xuICAgIEgud3JpdGVJbnQzMkJFKGgsIG9mZnNldClcbiAgICBILndyaXRlSW50MzJCRShsLCBvZmZzZXQgKyA0KVxuICB9XG5cbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2FoLCB0aGlzLl9hbCwgMClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2JoLCB0aGlzLl9ibCwgOClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2NoLCB0aGlzLl9jbCwgMTYpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9kaCwgdGhpcy5fZGwsIDI0KVxuICB3cml0ZUludDY0QkUodGhpcy5fZWgsIHRoaXMuX2VsLCAzMilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2ZoLCB0aGlzLl9mbCwgNDApXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEzODRcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiwgMHg3MTM3NDQ5MSwgMHgyM2VmNjVjZCxcbiAgMHhiNWMwZmJjZiwgMHhlYzRkM2IyZiwgMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyxcbiAgMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCwgMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSxcbiAgMHg5MjNmODJhNCwgMHhhZjE5NGY5YiwgMHhhYjFjNWVkNSwgMHhkYTZkODExOCxcbiAgMHhkODA3YWE5OCwgMHhhMzAzMDI0MiwgMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSxcbiAgMHgyNDMxODViZSwgMHg0ZWU0YjI4YywgMHg1NTBjN2RjMywgMHhkNWZmYjRlMixcbiAgMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiwgMHg4MGRlYjFmZSwgMHgzYjE2OTZiMSxcbiAgMHg5YmRjMDZhNywgMHgyNWM3MTIzNSwgMHhjMTliZjE3NCwgMHhjZjY5MjY5NCxcbiAgMHhlNDliNjljMSwgMHg5ZWYxNGFkMiwgMHhlZmJlNDc4NiwgMHgzODRmMjVlMyxcbiAgMHgwZmMxOWRjNiwgMHg4YjhjZDViNSwgMHgyNDBjYTFjYywgMHg3N2FjOWM2NSxcbiAgMHgyZGU5MmM2ZiwgMHg1OTJiMDI3NSwgMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyxcbiAgMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCwgMHg3NmY5ODhkYSwgMHg4MzExNTNiNSxcbiAgMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiwgMHhhODMxYzY2ZCwgMHgyZGI0MzIxMCxcbiAgMHhiMDAzMjdjOCwgMHg5OGZiMjEzZiwgMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCxcbiAgMHhjNmUwMGJmMywgMHgzZGE4OGZjMiwgMHhkNWE3OTE0NywgMHg5MzBhYTcyNSxcbiAgMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiwgMHgxNDI5Mjk2NywgMHgwYTBlNmU3MCxcbiAgMHgyN2I3MGE4NSwgMHg0NmQyMmZmYywgMHgyZTFiMjEzOCwgMHg1YzI2YzkyNixcbiAgMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCwgMHg1MzM4MGQxMywgMHg5ZDk1YjNkZixcbiAgMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSwgMHg3NjZhMGFiYiwgMHgzYzc3YjJhOCxcbiAgMHg4MWMyYzkyZSwgMHg0N2VkYWVlNiwgMHg5MjcyMmM4NSwgMHgxNDgyMzUzYixcbiAgMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCwgMHhhODFhNjY0YiwgMHhiYzQyMzAwMSxcbiAgMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSwgMHhjNzZjNTFhMywgMHgwNjU0YmUzMCxcbiAgMHhkMTkyZTgxOSwgMHhkNmVmNTIxOCwgMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCxcbiAgMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSwgMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCxcbiAgMHgxOWE0YzExNiwgMHhiOGQyZDBjOCwgMHgxZTM3NmMwOCwgMHg1MTQxYWI1MyxcbiAgMHgyNzQ4Nzc0YywgMHhkZjhlZWI5OSwgMHgzNGIwYmNiNSwgMHhlMTliNDhhOCxcbiAgMHgzOTFjMGNiMywgMHhjNWM5NWE2MywgMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYixcbiAgMHg1YjljY2E0ZiwgMHg3NzYzZTM3MywgMHg2ODJlNmZmMywgMHhkNmIyYjhhMyxcbiAgMHg3NDhmODJlZSwgMHg1ZGVmYjJmYywgMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCxcbiAgMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiwgMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyxcbiAgMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCwgMHhhNDUwNmNlYiwgMHhkZTgyYmRlOSxcbiAgMHhiZWY5YTNmNywgMHhiMmM2NzkxNSwgMHhjNjcxNzhmMiwgMHhlMzcyNTMyYixcbiAgMHhjYTI3M2VjZSwgMHhlYTI2NjE5YywgMHhkMTg2YjhjNywgMHgyMWMwYzIwNyxcbiAgMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSwgMHhmNTdkNGY3ZiwgMHhlZTZlZDE3OCxcbiAgMHgwNmYwNjdhYSwgMHg3MjE3NmZiYSwgMHgwYTYzN2RjNSwgMHhhMmM4OThhNixcbiAgMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSwgMHgxYjcxMGIzNSwgMHgxMzFjNDcxYixcbiAgMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCwgMHgzMmNhYWI3YiwgMHg0MGM3MjQ5MyxcbiAgMHgzYzllYmUwYSwgMHgxNWM5YmViYywgMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyxcbiAgMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiwgMHg1OTdmMjk5YywgMHhmYzY1N2UyYSxcbiAgMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYywgMHg2YzQ0MTk4YywgMHg0YTQ3NTgxN1xuXVxuXG52YXIgVyA9IG5ldyBBcnJheSgxNjApXG5cbmZ1bmN0aW9uIFNoYTUxMiAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDEyOCwgMTEyKVxufVxuXG5pbmhlcml0cyhTaGE1MTIsIEhhc2gpXG5cblNoYTUxMi5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYWggPSAweDZhMDllNjY3XG4gIHRoaXMuX2JoID0gMHhiYjY3YWU4NVxuICB0aGlzLl9jaCA9IDB4M2M2ZWYzNzJcbiAgdGhpcy5fZGggPSAweGE1NGZmNTNhXG4gIHRoaXMuX2VoID0gMHg1MTBlNTI3ZlxuICB0aGlzLl9maCA9IDB4OWIwNTY4OGNcbiAgdGhpcy5fZ2ggPSAweDFmODNkOWFiXG4gIHRoaXMuX2hoID0gMHg1YmUwY2QxOVxuXG4gIHRoaXMuX2FsID0gMHhmM2JjYzkwOFxuICB0aGlzLl9ibCA9IDB4ODRjYWE3M2JcbiAgdGhpcy5fY2wgPSAweGZlOTRmODJiXG4gIHRoaXMuX2RsID0gMHg1ZjFkMzZmMVxuICB0aGlzLl9lbCA9IDB4YWRlNjgyZDFcbiAgdGhpcy5fZmwgPSAweDJiM2U2YzFmXG4gIHRoaXMuX2dsID0gMHhmYjQxYmQ2YlxuICB0aGlzLl9obCA9IDB4MTM3ZTIxNzlcblxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBDaCAoeCwgeSwgeikge1xuICByZXR1cm4geiBeICh4ICYgKHkgXiB6KSlcbn1cblxuZnVuY3Rpb24gbWFqICh4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIHwgKHogJiAoeCB8IHkpKVxufVxuXG5mdW5jdGlvbiBzaWdtYTAgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMjggfCB4bCA8PCA0KSBeICh4bCA+Pj4gMiB8IHggPDwgMzApIF4gKHhsID4+PiA3IHwgeCA8PCAyNSlcbn1cblxuZnVuY3Rpb24gc2lnbWExICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDE0IHwgeGwgPDwgMTgpIF4gKHggPj4+IDE4IHwgeGwgPDwgMTQpIF4gKHhsID4+PiA5IHwgeCA8PCAyMylcbn1cblxuZnVuY3Rpb24gR2FtbWEwICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDEgfCB4bCA8PCAzMSkgXiAoeCA+Pj4gOCB8IHhsIDw8IDI0KSBeICh4ID4+PiA3KVxufVxuXG5mdW5jdGlvbiBHYW1tYTBsICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDEgfCB4bCA8PCAzMSkgXiAoeCA+Pj4gOCB8IHhsIDw8IDI0KSBeICh4ID4+PiA3IHwgeGwgPDwgMjUpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMSAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxOSB8IHhsIDw8IDEzKSBeICh4bCA+Pj4gMjkgfCB4IDw8IDMpIF4gKHggPj4+IDYpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMWwgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMTkgfCB4bCA8PCAxMykgXiAoeGwgPj4+IDI5IHwgeCA8PCAzKSBeICh4ID4+PiA2IHwgeGwgPDwgMjYpXG59XG5cbmZ1bmN0aW9uIGdldENhcnJ5IChhLCBiKSB7XG4gIHJldHVybiAoYSA+Pj4gMCkgPCAoYiA+Pj4gMCkgPyAxIDogMFxufVxuXG5TaGE1MTIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYWggPSB0aGlzLl9haCB8IDBcbiAgdmFyIGJoID0gdGhpcy5fYmggfCAwXG4gIHZhciBjaCA9IHRoaXMuX2NoIHwgMFxuICB2YXIgZGggPSB0aGlzLl9kaCB8IDBcbiAgdmFyIGVoID0gdGhpcy5fZWggfCAwXG4gIHZhciBmaCA9IHRoaXMuX2ZoIHwgMFxuICB2YXIgZ2ggPSB0aGlzLl9naCB8IDBcbiAgdmFyIGhoID0gdGhpcy5faGggfCAwXG5cbiAgdmFyIGFsID0gdGhpcy5fYWwgfCAwXG4gIHZhciBibCA9IHRoaXMuX2JsIHwgMFxuICB2YXIgY2wgPSB0aGlzLl9jbCB8IDBcbiAgdmFyIGRsID0gdGhpcy5fZGwgfCAwXG4gIHZhciBlbCA9IHRoaXMuX2VsIHwgMFxuICB2YXIgZmwgPSB0aGlzLl9mbCB8IDBcbiAgdmFyIGdsID0gdGhpcy5fZ2wgfCAwXG4gIHZhciBobCA9IHRoaXMuX2hsIHwgMFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzI7IGkgKz0gMikge1xuICAgIFdbaV0gPSBNLnJlYWRJbnQzMkJFKGkgKiA0KVxuICAgIFdbaSArIDFdID0gTS5yZWFkSW50MzJCRShpICogNCArIDQpXG4gIH1cbiAgZm9yICg7IGkgPCAxNjA7IGkgKz0gMikge1xuICAgIHZhciB4aCA9IFdbaSAtIDE1ICogMl1cbiAgICB2YXIgeGwgPSBXW2kgLSAxNSAqIDIgKyAxXVxuICAgIHZhciBnYW1tYTAgPSBHYW1tYTAoeGgsIHhsKVxuICAgIHZhciBnYW1tYTBsID0gR2FtbWEwbCh4bCwgeGgpXG5cbiAgICB4aCA9IFdbaSAtIDIgKiAyXVxuICAgIHhsID0gV1tpIC0gMiAqIDIgKyAxXVxuICAgIHZhciBnYW1tYTEgPSBHYW1tYTEoeGgsIHhsKVxuICAgIHZhciBnYW1tYTFsID0gR2FtbWExbCh4bCwgeGgpXG5cbiAgICAvLyBXW2ldID0gZ2FtbWEwICsgV1tpIC0gN10gKyBnYW1tYTEgKyBXW2kgLSAxNl1cbiAgICB2YXIgV2k3aCA9IFdbaSAtIDcgKiAyXVxuICAgIHZhciBXaTdsID0gV1tpIC0gNyAqIDIgKyAxXVxuXG4gICAgdmFyIFdpMTZoID0gV1tpIC0gMTYgKiAyXVxuICAgIHZhciBXaTE2bCA9IFdbaSAtIDE2ICogMiArIDFdXG5cbiAgICB2YXIgV2lsID0gKGdhbW1hMGwgKyBXaTdsKSB8IDBcbiAgICB2YXIgV2loID0gKGdhbW1hMCArIFdpN2ggKyBnZXRDYXJyeShXaWwsIGdhbW1hMGwpKSB8IDBcbiAgICBXaWwgPSAoV2lsICsgZ2FtbWExbCkgfCAwXG4gICAgV2loID0gKFdpaCArIGdhbW1hMSArIGdldENhcnJ5KFdpbCwgZ2FtbWExbCkpIHwgMFxuICAgIFdpbCA9IChXaWwgKyBXaTE2bCkgfCAwXG4gICAgV2loID0gKFdpaCArIFdpMTZoICsgZ2V0Q2FycnkoV2lsLCBXaTE2bCkpIHwgMFxuXG4gICAgV1tpXSA9IFdpaFxuICAgIFdbaSArIDFdID0gV2lsXG4gIH1cblxuICBmb3IgKHZhciBqID0gMDsgaiA8IDE2MDsgaiArPSAyKSB7XG4gICAgV2loID0gV1tqXVxuICAgIFdpbCA9IFdbaiArIDFdXG5cbiAgICB2YXIgbWFqaCA9IG1haihhaCwgYmgsIGNoKVxuICAgIHZhciBtYWpsID0gbWFqKGFsLCBibCwgY2wpXG5cbiAgICB2YXIgc2lnbWEwaCA9IHNpZ21hMChhaCwgYWwpXG4gICAgdmFyIHNpZ21hMGwgPSBzaWdtYTAoYWwsIGFoKVxuICAgIHZhciBzaWdtYTFoID0gc2lnbWExKGVoLCBlbClcbiAgICB2YXIgc2lnbWExbCA9IHNpZ21hMShlbCwgZWgpXG5cbiAgICAvLyB0MSA9IGggKyBzaWdtYTEgKyBjaCArIEtbal0gKyBXW2pdXG4gICAgdmFyIEtpaCA9IEtbal1cbiAgICB2YXIgS2lsID0gS1tqICsgMV1cblxuICAgIHZhciBjaGggPSBDaChlaCwgZmgsIGdoKVxuICAgIHZhciBjaGwgPSBDaChlbCwgZmwsIGdsKVxuXG4gICAgdmFyIHQxbCA9IChobCArIHNpZ21hMWwpIHwgMFxuICAgIHZhciB0MWggPSAoaGggKyBzaWdtYTFoICsgZ2V0Q2FycnkodDFsLCBobCkpIHwgMFxuICAgIHQxbCA9ICh0MWwgKyBjaGwpIHwgMFxuICAgIHQxaCA9ICh0MWggKyBjaGggKyBnZXRDYXJyeSh0MWwsIGNobCkpIHwgMFxuICAgIHQxbCA9ICh0MWwgKyBLaWwpIHwgMFxuICAgIHQxaCA9ICh0MWggKyBLaWggKyBnZXRDYXJyeSh0MWwsIEtpbCkpIHwgMFxuICAgIHQxbCA9ICh0MWwgKyBXaWwpIHwgMFxuICAgIHQxaCA9ICh0MWggKyBXaWggKyBnZXRDYXJyeSh0MWwsIFdpbCkpIHwgMFxuXG4gICAgLy8gdDIgPSBzaWdtYTAgKyBtYWpcbiAgICB2YXIgdDJsID0gKHNpZ21hMGwgKyBtYWpsKSB8IDBcbiAgICB2YXIgdDJoID0gKHNpZ21hMGggKyBtYWpoICsgZ2V0Q2FycnkodDJsLCBzaWdtYTBsKSkgfCAwXG5cbiAgICBoaCA9IGdoXG4gICAgaGwgPSBnbFxuICAgIGdoID0gZmhcbiAgICBnbCA9IGZsXG4gICAgZmggPSBlaFxuICAgIGZsID0gZWxcbiAgICBlbCA9IChkbCArIHQxbCkgfCAwXG4gICAgZWggPSAoZGggKyB0MWggKyBnZXRDYXJyeShlbCwgZGwpKSB8IDBcbiAgICBkaCA9IGNoXG4gICAgZGwgPSBjbFxuICAgIGNoID0gYmhcbiAgICBjbCA9IGJsXG4gICAgYmggPSBhaFxuICAgIGJsID0gYWxcbiAgICBhbCA9ICh0MWwgKyB0MmwpIHwgMFxuICAgIGFoID0gKHQxaCArIHQyaCArIGdldENhcnJ5KGFsLCB0MWwpKSB8IDBcbiAgfVxuXG4gIHRoaXMuX2FsID0gKHRoaXMuX2FsICsgYWwpIHwgMFxuICB0aGlzLl9ibCA9ICh0aGlzLl9ibCArIGJsKSB8IDBcbiAgdGhpcy5fY2wgPSAodGhpcy5fY2wgKyBjbCkgfCAwXG4gIHRoaXMuX2RsID0gKHRoaXMuX2RsICsgZGwpIHwgMFxuICB0aGlzLl9lbCA9ICh0aGlzLl9lbCArIGVsKSB8IDBcbiAgdGhpcy5fZmwgPSAodGhpcy5fZmwgKyBmbCkgfCAwXG4gIHRoaXMuX2dsID0gKHRoaXMuX2dsICsgZ2wpIHwgMFxuICB0aGlzLl9obCA9ICh0aGlzLl9obCArIGhsKSB8IDBcblxuICB0aGlzLl9haCA9ICh0aGlzLl9haCArIGFoICsgZ2V0Q2FycnkodGhpcy5fYWwsIGFsKSkgfCAwXG4gIHRoaXMuX2JoID0gKHRoaXMuX2JoICsgYmggKyBnZXRDYXJyeSh0aGlzLl9ibCwgYmwpKSB8IDBcbiAgdGhpcy5fY2ggPSAodGhpcy5fY2ggKyBjaCArIGdldENhcnJ5KHRoaXMuX2NsLCBjbCkpIHwgMFxuICB0aGlzLl9kaCA9ICh0aGlzLl9kaCArIGRoICsgZ2V0Q2FycnkodGhpcy5fZGwsIGRsKSkgfCAwXG4gIHRoaXMuX2VoID0gKHRoaXMuX2VoICsgZWggKyBnZXRDYXJyeSh0aGlzLl9lbCwgZWwpKSB8IDBcbiAgdGhpcy5fZmggPSAodGhpcy5fZmggKyBmaCArIGdldENhcnJ5KHRoaXMuX2ZsLCBmbCkpIHwgMFxuICB0aGlzLl9naCA9ICh0aGlzLl9naCArIGdoICsgZ2V0Q2FycnkodGhpcy5fZ2wsIGdsKSkgfCAwXG4gIHRoaXMuX2hoID0gKHRoaXMuX2hoICsgaGggKyBnZXRDYXJyeSh0aGlzLl9obCwgaGwpKSB8IDBcbn1cblxuU2hhNTEyLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoNjQpXG5cbiAgZnVuY3Rpb24gd3JpdGVJbnQ2NEJFIChoLCBsLCBvZmZzZXQpIHtcbiAgICBILndyaXRlSW50MzJCRShoLCBvZmZzZXQpXG4gICAgSC53cml0ZUludDMyQkUobCwgb2Zmc2V0ICsgNClcbiAgfVxuXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9haCwgdGhpcy5fYWwsIDApXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9iaCwgdGhpcy5fYmwsIDgpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9jaCwgdGhpcy5fY2wsIDE2KVxuICB3cml0ZUludDY0QkUodGhpcy5fZGgsIHRoaXMuX2RsLCAyNClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2VoLCB0aGlzLl9lbCwgMzIpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9maCwgdGhpcy5fZmwsIDQwKVxuICB3cml0ZUludDY0QkUodGhpcy5fZ2gsIHRoaXMuX2dsLCA0OClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2hoLCB0aGlzLl9obCwgNTYpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGE1MTJcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5tb2R1bGUuZXhwb3J0cyA9IFN0cmVhbTtcblxudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuaW5oZXJpdHMoU3RyZWFtLCBFRSk7XG5TdHJlYW0uUmVhZGFibGUgPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vcmVhZGFibGUuanMnKTtcblN0cmVhbS5Xcml0YWJsZSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS93cml0YWJsZS5qcycpO1xuU3RyZWFtLkR1cGxleCA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9kdXBsZXguanMnKTtcblN0cmVhbS5UcmFuc2Zvcm0gPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzJyk7XG5TdHJlYW0uUGFzc1Rocm91Z2ggPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanMnKTtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC40LnhcblN0cmVhbS5TdHJlYW0gPSBTdHJlYW07XG5cblxuXG4vLyBvbGQtc3R5bGUgc3RyZWFtcy4gIE5vdGUgdGhhdCB0aGUgcGlwZSBtZXRob2QgKHRoZSBvbmx5IHJlbGV2YW50XG4vLyBwYXJ0IG9mIHRoaXMgY2xhc3MpIGlzIG92ZXJyaWRkZW4gaW4gdGhlIFJlYWRhYmxlIGNsYXNzLlxuXG5mdW5jdGlvbiBTdHJlYW0oKSB7XG4gIEVFLmNhbGwodGhpcyk7XG59XG5cblN0cmVhbS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKGRlc3QsIG9wdGlvbnMpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgaWYgKGRlc3Qud3JpdGFibGUpIHtcbiAgICAgIGlmIChmYWxzZSA9PT0gZGVzdC53cml0ZShjaHVuaykgJiYgc291cmNlLnBhdXNlKSB7XG4gICAgICAgIHNvdXJjZS5wYXVzZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZGF0YScsIG9uZGF0YSk7XG5cbiAgZnVuY3Rpb24gb25kcmFpbigpIHtcbiAgICBpZiAoc291cmNlLnJlYWRhYmxlICYmIHNvdXJjZS5yZXN1bWUpIHtcbiAgICAgIHNvdXJjZS5yZXN1bWUoKTtcbiAgICB9XG4gIH1cblxuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIC8vIElmIHRoZSAnZW5kJyBvcHRpb24gaXMgbm90IHN1cHBsaWVkLCBkZXN0LmVuZCgpIHdpbGwgYmUgY2FsbGVkIHdoZW5cbiAgLy8gc291cmNlIGdldHMgdGhlICdlbmQnIG9yICdjbG9zZScgZXZlbnRzLiAgT25seSBkZXN0LmVuZCgpIG9uY2UuXG4gIGlmICghZGVzdC5faXNTdGRpbyAmJiAoIW9wdGlvbnMgfHwgb3B0aW9ucy5lbmQgIT09IGZhbHNlKSkge1xuICAgIHNvdXJjZS5vbignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5vbignY2xvc2UnLCBvbmNsb3NlKTtcbiAgfVxuXG4gIHZhciBkaWRPbkVuZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGlmICh0eXBlb2YgZGVzdC5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSBkZXN0LmRlc3Ryb3koKTtcbiAgfVxuXG4gIC8vIGRvbid0IGxlYXZlIGRhbmdsaW5nIHBpcGVzIHdoZW4gdGhlcmUgYXJlIGVycm9ycy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGNsZWFudXAoKTtcbiAgICBpZiAoRUUubGlzdGVuZXJDb3VudCh0aGlzLCAnZXJyb3InKSA9PT0gMCkge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCBzdHJlYW0gZXJyb3IgaW4gcGlwZS5cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2Vycm9yJywgb25lcnJvcik7XG4gIGRlc3Qub24oJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gcmVtb3ZlIGFsbCB0aGUgZXZlbnQgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZC5cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcbiAgfVxuXG4gIHNvdXJjZS5vbignZW5kJywgY2xlYW51cCk7XG4gIHNvdXJjZS5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0Lm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3QuZW1pdCgncGlwZScsIHNvdXJjZSk7XG5cbiAgLy8gQWxsb3cgZm9yIHVuaXgtbGlrZSB1c2FnZTogQS5waXBlKEIpLnBpcGUoQylcbiAgcmV0dXJuIGRlc3Q7XG59O1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBpc0VuY29kaW5nID0gQnVmZmVyLmlzRW5jb2RpbmcgfHwgZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIGVuY29kaW5nID0gJycgKyBlbmNvZGluZztcbiAgc3dpdGNoIChlbmNvZGluZyAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpjYXNlICd1dGY4JzpjYXNlICd1dGYtOCc6Y2FzZSAnYXNjaWknOmNhc2UgJ2JpbmFyeSc6Y2FzZSAnYmFzZTY0JzpjYXNlICd1Y3MyJzpjYXNlICd1Y3MtMic6Y2FzZSAndXRmMTZsZSc6Y2FzZSAndXRmLTE2bGUnOmNhc2UgJ3Jhdyc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBfbm9ybWFsaXplRW5jb2RpbmcoZW5jKSB7XG4gIGlmICghZW5jKSByZXR1cm4gJ3V0ZjgnO1xuICB2YXIgcmV0cmllZDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuYykge1xuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiAndXRmOCc7XG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gJ3V0ZjE2bGUnO1xuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiAnbGF0aW4xJztcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gZW5jO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKHJldHJpZWQpIHJldHVybjsgLy8gdW5kZWZpbmVkXG4gICAgICAgIGVuYyA9ICgnJyArIGVuYykudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0cmllZCA9IHRydWU7XG4gICAgfVxuICB9XG59O1xuXG4vLyBEbyBub3QgY2FjaGUgYEJ1ZmZlci5pc0VuY29kaW5nYCB3aGVuIGNoZWNraW5nIGVuY29kaW5nIG5hbWVzIGFzIHNvbWVcbi8vIG1vZHVsZXMgbW9ua2V5LXBhdGNoIGl0IHRvIHN1cHBvcnQgYWRkaXRpb25hbCBlbmNvZGluZ3NcbmZ1bmN0aW9uIG5vcm1hbGl6ZUVuY29kaW5nKGVuYykge1xuICB2YXIgbmVuYyA9IF9ub3JtYWxpemVFbmNvZGluZyhlbmMpO1xuICBpZiAodHlwZW9mIG5lbmMgIT09ICdzdHJpbmcnICYmIChCdWZmZXIuaXNFbmNvZGluZyA9PT0gaXNFbmNvZGluZyB8fCAhaXNFbmNvZGluZyhlbmMpKSkgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jKTtcbiAgcmV0dXJuIG5lbmMgfHwgZW5jO1xufVxuXG4vLyBTdHJpbmdEZWNvZGVyIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgZWZmaWNpZW50bHkgc3BsaXR0aW5nIGEgc2VyaWVzIG9mXG4vLyBidWZmZXJzIGludG8gYSBzZXJpZXMgb2YgSlMgc3RyaW5ncyB3aXRob3V0IGJyZWFraW5nIGFwYXJ0IG11bHRpLWJ5dGVcbi8vIGNoYXJhY3RlcnMuXG5leHBvcnRzLlN0cmluZ0RlY29kZXIgPSBTdHJpbmdEZWNvZGVyO1xuZnVuY3Rpb24gU3RyaW5nRGVjb2RlcihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gbm9ybWFsaXplRW5jb2RpbmcoZW5jb2RpbmcpO1xuICB2YXIgbmI7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgdGhpcy50ZXh0ID0gdXRmMTZUZXh0O1xuICAgICAgdGhpcy5lbmQgPSB1dGYxNkVuZDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgdGhpcy5maWxsTGFzdCA9IHV0ZjhGaWxsTGFzdDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICB0aGlzLnRleHQgPSBiYXNlNjRUZXh0O1xuICAgICAgdGhpcy5lbmQgPSBiYXNlNjRFbmQ7XG4gICAgICBuYiA9IDM7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhpcy53cml0ZSA9IHNpbXBsZVdyaXRlO1xuICAgICAgdGhpcy5lbmQgPSBzaW1wbGVFbmQ7XG4gICAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIHRoaXMubGFzdFRvdGFsID0gMDtcbiAgdGhpcy5sYXN0Q2hhciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShuYik7XG59XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAoYnVmLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnO1xuICB2YXIgcjtcbiAgdmFyIGk7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSB7XG4gICAgciA9IHRoaXMuZmlsbExhc3QoYnVmKTtcbiAgICBpZiAociA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJyc7XG4gICAgaSA9IHRoaXMubGFzdE5lZWQ7XG4gICAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgaSA9IDA7XG4gIH1cbiAgaWYgKGkgPCBidWYubGVuZ3RoKSByZXR1cm4gciA/IHIgKyB0aGlzLnRleHQoYnVmLCBpKSA6IHRoaXMudGV4dChidWYsIGkpO1xuICByZXR1cm4gciB8fCAnJztcbn07XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZCA9IHV0ZjhFbmQ7XG5cbi8vIFJldHVybnMgb25seSBjb21wbGV0ZSBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS50ZXh0ID0gdXRmOFRleHQ7XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgcGFydGlhbCBub24tVVRGLTggY2hhcmFjdGVyIHVzaW5nIGJ5dGVzIGZyb20gYSBCdWZmZXJcblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmZpbGxMYXN0ID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAodGhpcy5sYXN0TmVlZCA8PSBidWYubGVuZ3RoKSB7XG4gICAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCB0aGlzLmxhc3ROZWVkKTtcbiAgICByZXR1cm4gdGhpcy5sYXN0Q2hhci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCB0aGlzLmxhc3RUb3RhbCk7XG4gIH1cbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufTtcblxuLy8gQ2hlY2tzIHRoZSB0eXBlIG9mIGEgVVRGLTggYnl0ZSwgd2hldGhlciBpdCdzIEFTQ0lJLCBhIGxlYWRpbmcgYnl0ZSwgb3IgYVxuLy8gY29udGludWF0aW9uIGJ5dGUuIElmIGFuIGludmFsaWQgYnl0ZSBpcyBkZXRlY3RlZCwgLTIgaXMgcmV0dXJuZWQuXG5mdW5jdGlvbiB1dGY4Q2hlY2tCeXRlKGJ5dGUpIHtcbiAgaWYgKGJ5dGUgPD0gMHg3RikgcmV0dXJuIDA7ZWxzZSBpZiAoYnl0ZSA+PiA1ID09PSAweDA2KSByZXR1cm4gMjtlbHNlIGlmIChieXRlID4+IDQgPT09IDB4MEUpIHJldHVybiAzO2Vsc2UgaWYgKGJ5dGUgPj4gMyA9PT0gMHgxRSkgcmV0dXJuIDQ7XG4gIHJldHVybiBieXRlID4+IDYgPT09IDB4MDIgPyAtMSA6IC0yO1xufVxuXG4vLyBDaGVja3MgYXQgbW9zdCAzIGJ5dGVzIGF0IHRoZSBlbmQgb2YgYSBCdWZmZXIgaW4gb3JkZXIgdG8gZGV0ZWN0IGFuXG4vLyBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyLiBUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzICgyLCAzLCBvciA0KVxuLy8gbmVlZGVkIHRvIGNvbXBsZXRlIHRoZSBVVEYtOCBjaGFyYWN0ZXIgKGlmIGFwcGxpY2FibGUpIGFyZSByZXR1cm5lZC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0luY29tcGxldGUoc2VsZiwgYnVmLCBpKSB7XG4gIHZhciBqID0gYnVmLmxlbmd0aCAtIDE7XG4gIGlmIChqIDwgaSkgcmV0dXJuIDA7XG4gIHZhciBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAxO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAyO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSB7XG4gICAgICBpZiAobmIgPT09IDIpIG5iID0gMDtlbHNlIHNlbGYubGFzdE5lZWQgPSBuYiAtIDM7XG4gICAgfVxuICAgIHJldHVybiBuYjtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy8gVmFsaWRhdGVzIGFzIG1hbnkgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyIGFzXG4vLyBuZWVkZWQgb3IgYXJlIGF2YWlsYWJsZS4gSWYgd2Ugc2VlIGEgbm9uLWNvbnRpbnVhdGlvbiBieXRlIHdoZXJlIHdlIGV4cGVjdFxuLy8gb25lLCB3ZSBcInJlcGxhY2VcIiB0aGUgdmFsaWRhdGVkIGNvbnRpbnVhdGlvbiBieXRlcyB3ZSd2ZSBzZWVuIHNvIGZhciB3aXRoXG4vLyBhIHNpbmdsZSBVVEYtOCByZXBsYWNlbWVudCBjaGFyYWN0ZXIgKCdcXHVmZmZkJyksIHRvIG1hdGNoIHY4J3MgVVRGLTggZGVjb2Rpbmdcbi8vIGJlaGF2aW9yLiBUaGUgY29udGludWF0aW9uIGJ5dGUgY2hlY2sgaXMgaW5jbHVkZWQgdGhyZWUgdGltZXMgaW4gdGhlIGNhc2Vcbi8vIHdoZXJlIGFsbCBvZiB0aGUgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIGNoYXJhY3RlciBleGlzdCBpbiB0aGUgc2FtZSBidWZmZXIuXG4vLyBJdCBpcyBhbHNvIGRvbmUgdGhpcyB3YXkgYXMgYSBzbGlnaHQgcGVyZm9ybWFuY2UgaW5jcmVhc2UgaW5zdGVhZCBvZiB1c2luZyBhXG4vLyBsb29wLlxuZnVuY3Rpb24gdXRmOENoZWNrRXh0cmFCeXRlcyhzZWxmLCBidWYsIHApIHtcbiAgaWYgKChidWZbMF0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgIHNlbGYubGFzdE5lZWQgPSAwO1xuICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gIH1cbiAgaWYgKHNlbGYubGFzdE5lZWQgPiAxICYmIGJ1Zi5sZW5ndGggPiAxKSB7XG4gICAgaWYgKChidWZbMV0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgc2VsZi5sYXN0TmVlZCA9IDE7XG4gICAgICByZXR1cm4gJ1xcdWZmZmQnO1xuICAgIH1cbiAgICBpZiAoc2VsZi5sYXN0TmVlZCA+IDIgJiYgYnVmLmxlbmd0aCA+IDIpIHtcbiAgICAgIGlmICgoYnVmWzJdICYgMHhDMCkgIT09IDB4ODApIHtcbiAgICAgICAgc2VsZi5sYXN0TmVlZCA9IDI7XG4gICAgICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIgdXNpbmcgYnl0ZXMgZnJvbSBhIEJ1ZmZlci5cbmZ1bmN0aW9uIHV0ZjhGaWxsTGFzdChidWYpIHtcbiAgdmFyIHAgPSB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQ7XG4gIHZhciByID0gdXRmOENoZWNrRXh0cmFCeXRlcyh0aGlzLCBidWYsIHApO1xuICBpZiAociAhPT0gdW5kZWZpbmVkKSByZXR1cm4gcjtcbiAgaWYgKHRoaXMubGFzdE5lZWQgPD0gYnVmLmxlbmd0aCkge1xuICAgIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHAsIDAsIHRoaXMubGFzdE5lZWQpO1xuICAgIHJldHVybiB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMubGFzdFRvdGFsKTtcbiAgfVxuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCBwLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufVxuXG4vLyBSZXR1cm5zIGFsbCBjb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyLiBJZiB0aGUgQnVmZmVyIGVuZGVkIG9uIGFcbi8vIHBhcnRpYWwgY2hhcmFjdGVyLCB0aGUgY2hhcmFjdGVyJ3MgYnl0ZXMgYXJlIGJ1ZmZlcmVkIHVudGlsIHRoZSByZXF1aXJlZFxuLy8gbnVtYmVyIG9mIGJ5dGVzIGFyZSBhdmFpbGFibGUuXG5mdW5jdGlvbiB1dGY4VGV4dChidWYsIGkpIHtcbiAgdmFyIHRvdGFsID0gdXRmOENoZWNrSW5jb21wbGV0ZSh0aGlzLCBidWYsIGkpO1xuICBpZiAoIXRoaXMubGFzdE5lZWQpIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjgnLCBpKTtcbiAgdGhpcy5sYXN0VG90YWwgPSB0b3RhbDtcbiAgdmFyIGVuZCA9IGJ1Zi5sZW5ndGggLSAodG90YWwgLSB0aGlzLmxhc3ROZWVkKTtcbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgMCwgZW5kKTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmOCcsIGksIGVuZCk7XG59XG5cbi8vIEZvciBVVEYtOCwgYSByZXBsYWNlbWVudCBjaGFyYWN0ZXIgaXMgYWRkZWQgd2hlbiBlbmRpbmcgb24gYSBwYXJ0aWFsXG4vLyBjaGFyYWN0ZXIuXG5mdW5jdGlvbiB1dGY4RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSByZXR1cm4gciArICdcXHVmZmZkJztcbiAgcmV0dXJuIHI7XG59XG5cbi8vIFVURi0xNkxFIHR5cGljYWxseSBuZWVkcyB0d28gYnl0ZXMgcGVyIGNoYXJhY3RlciwgYnV0IGV2ZW4gaWYgd2UgaGF2ZSBhbiBldmVuXG4vLyBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlLCB3ZSBuZWVkIHRvIGNoZWNrIGlmIHdlIGVuZCBvbiBhIGxlYWRpbmcvaGlnaFxuLy8gc3Vycm9nYXRlLiBJbiB0aGF0IGNhc2UsIHdlIG5lZWQgdG8gd2FpdCBmb3IgdGhlIG5leHQgdHdvIGJ5dGVzIGluIG9yZGVyIHRvXG4vLyBkZWNvZGUgdGhlIGxhc3QgY2hhcmFjdGVyIHByb3Blcmx5LlxuZnVuY3Rpb24gdXRmMTZUZXh0KGJ1ZiwgaSkge1xuICBpZiAoKGJ1Zi5sZW5ndGggLSBpKSAlIDIgPT09IDApIHtcbiAgICB2YXIgciA9IGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGkpO1xuICAgIGlmIChyKSB7XG4gICAgICB2YXIgYyA9IHIuY2hhckNvZGVBdChyLmxlbmd0aCAtIDEpO1xuICAgICAgaWYgKGMgPj0gMHhEODAwICYmIGMgPD0gMHhEQkZGKSB7XG4gICAgICAgIHRoaXMubGFzdE5lZWQgPSAyO1xuICAgICAgICB0aGlzLmxhc3RUb3RhbCA9IDQ7XG4gICAgICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDJdO1xuICAgICAgICB0aGlzLmxhc3RDaGFyWzFdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgICAgICAgcmV0dXJuIHIuc2xpY2UoMCwgLTEpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuICB0aGlzLmxhc3ROZWVkID0gMTtcbiAgdGhpcy5sYXN0VG90YWwgPSAyO1xuICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGksIGJ1Zi5sZW5ndGggLSAxKTtcbn1cblxuLy8gRm9yIFVURi0xNkxFIHdlIGRvIG5vdCBleHBsaWNpdGx5IGFwcGVuZCBzcGVjaWFsIHJlcGxhY2VtZW50IGNoYXJhY3RlcnMgaWYgd2Vcbi8vIGVuZCBvbiBhIHBhcnRpYWwgY2hhcmFjdGVyLCB3ZSBzaW1wbHkgbGV0IHY4IGhhbmRsZSB0aGF0LlxuZnVuY3Rpb24gdXRmMTZFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHtcbiAgICB2YXIgZW5kID0gdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkO1xuICAgIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygndXRmMTZsZScsIDAsIGVuZCk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRleHQoYnVmLCBpKSB7XG4gIHZhciBuID0gKGJ1Zi5sZW5ndGggLSBpKSAlIDM7XG4gIGlmIChuID09PSAwKSByZXR1cm4gYnVmLnRvU3RyaW5nKCdiYXNlNjQnLCBpKTtcbiAgdGhpcy5sYXN0TmVlZCA9IDMgLSBuO1xuICB0aGlzLmxhc3RUb3RhbCA9IDM7XG4gIGlmIChuID09PSAxKSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMl07XG4gICAgdGhpcy5sYXN0Q2hhclsxXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH1cbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygnYmFzZTY0JywgaSwgYnVmLmxlbmd0aCAtIG4pO1xufVxuXG5mdW5jdGlvbiBiYXNlNjRFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygnYmFzZTY0JywgMCwgMyAtIHRoaXMubGFzdE5lZWQpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gUGFzcyBieXRlcyBvbiB0aHJvdWdoIGZvciBzaW5nbGUtYnl0ZSBlbmNvZGluZ3MgKGUuZy4gYXNjaWksIGxhdGluMSwgaGV4KVxuZnVuY3Rpb24gc2ltcGxlV3JpdGUoYnVmKSB7XG4gIHJldHVybiBidWYudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG59XG5cbmZ1bmN0aW9uIHNpbXBsZUVuZChidWYpIHtcbiAgcmV0dXJuIGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG59IiwidmFyIG5leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy9icm93c2VyLmpzJykubmV4dFRpY2s7XG52YXIgYXBwbHkgPSBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHk7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgaW1tZWRpYXRlSWRzID0ge307XG52YXIgbmV4dEltbWVkaWF0ZUlkID0gMDtcblxuLy8gRE9NIEFQSXMsIGZvciBjb21wbGV0ZW5lc3NcblxuZXhwb3J0cy5zZXRUaW1lb3V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgVGltZW91dChhcHBseS5jYWxsKHNldFRpbWVvdXQsIHdpbmRvdywgYXJndW1lbnRzKSwgY2xlYXJUaW1lb3V0KTtcbn07XG5leHBvcnRzLnNldEludGVydmFsID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgVGltZW91dChhcHBseS5jYWxsKHNldEludGVydmFsLCB3aW5kb3csIGFyZ3VtZW50cyksIGNsZWFySW50ZXJ2YWwpO1xufTtcbmV4cG9ydHMuY2xlYXJUaW1lb3V0ID1cbmV4cG9ydHMuY2xlYXJJbnRlcnZhbCA9IGZ1bmN0aW9uKHRpbWVvdXQpIHsgdGltZW91dC5jbG9zZSgpOyB9O1xuXG5mdW5jdGlvbiBUaW1lb3V0KGlkLCBjbGVhckZuKSB7XG4gIHRoaXMuX2lkID0gaWQ7XG4gIHRoaXMuX2NsZWFyRm4gPSBjbGVhckZuO1xufVxuVGltZW91dC5wcm90b3R5cGUudW5yZWYgPSBUaW1lb3V0LnByb3RvdHlwZS5yZWYgPSBmdW5jdGlvbigpIHt9O1xuVGltZW91dC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fY2xlYXJGbi5jYWxsKHdpbmRvdywgdGhpcy5faWQpO1xufTtcblxuLy8gRG9lcyBub3Qgc3RhcnQgdGhlIHRpbWUsIGp1c3Qgc2V0cyB1cCB0aGUgbWVtYmVycyBuZWVkZWQuXG5leHBvcnRzLmVucm9sbCA9IGZ1bmN0aW9uKGl0ZW0sIG1zZWNzKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcbiAgaXRlbS5faWRsZVRpbWVvdXQgPSBtc2Vjcztcbn07XG5cbmV4cG9ydHMudW5lbnJvbGwgPSBmdW5jdGlvbihpdGVtKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcbiAgaXRlbS5faWRsZVRpbWVvdXQgPSAtMTtcbn07XG5cbmV4cG9ydHMuX3VucmVmQWN0aXZlID0gZXhwb3J0cy5hY3RpdmUgPSBmdW5jdGlvbihpdGVtKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcblxuICB2YXIgbXNlY3MgPSBpdGVtLl9pZGxlVGltZW91dDtcbiAgaWYgKG1zZWNzID49IDApIHtcbiAgICBpdGVtLl9pZGxlVGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiBvblRpbWVvdXQoKSB7XG4gICAgICBpZiAoaXRlbS5fb25UaW1lb3V0KVxuICAgICAgICBpdGVtLl9vblRpbWVvdXQoKTtcbiAgICB9LCBtc2Vjcyk7XG4gIH1cbn07XG5cbi8vIFRoYXQncyBub3QgaG93IG5vZGUuanMgaW1wbGVtZW50cyBpdCBidXQgdGhlIGV4cG9zZWQgYXBpIGlzIHRoZSBzYW1lLlxuZXhwb3J0cy5zZXRJbW1lZGlhdGUgPSB0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSBcImZ1bmN0aW9uXCIgPyBzZXRJbW1lZGlhdGUgOiBmdW5jdGlvbihmbikge1xuICB2YXIgaWQgPSBuZXh0SW1tZWRpYXRlSWQrKztcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IGZhbHNlIDogc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gIGltbWVkaWF0ZUlkc1tpZF0gPSB0cnVlO1xuXG4gIG5leHRUaWNrKGZ1bmN0aW9uIG9uTmV4dFRpY2soKSB7XG4gICAgaWYgKGltbWVkaWF0ZUlkc1tpZF0pIHtcbiAgICAgIC8vIGZuLmNhbGwoKSBpcyBmYXN0ZXIgc28gd2Ugb3B0aW1pemUgZm9yIHRoZSBjb21tb24gdXNlLWNhc2VcbiAgICAgIC8vIEBzZWUgaHR0cDovL2pzcGVyZi5jb20vY2FsbC1hcHBseS1zZWd1XG4gICAgICBpZiAoYXJncykge1xuICAgICAgICBmbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZuLmNhbGwobnVsbCk7XG4gICAgICB9XG4gICAgICAvLyBQcmV2ZW50IGlkcyBmcm9tIGxlYWtpbmdcbiAgICAgIGV4cG9ydHMuY2xlYXJJbW1lZGlhdGUoaWQpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGlkO1xufTtcblxuZXhwb3J0cy5jbGVhckltbWVkaWF0ZSA9IHR5cGVvZiBjbGVhckltbWVkaWF0ZSA9PT0gXCJmdW5jdGlvblwiID8gY2xlYXJJbW1lZGlhdGUgOiBmdW5jdGlvbihpZCkge1xuICBkZWxldGUgaW1tZWRpYXRlSWRzW2lkXTtcbn07IiwiXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVwcmVjYXRlO1xuXG4vKipcbiAqIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4gKiBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2Uubm9EZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudGhyb3dEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCB0aHJvdyBhbiBFcnJvciB3aGVuIGludm9rZWQuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS50cmFjZURlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGRlcHJlY2F0ZWQgZnVuY3Rpb25zXG4gKiB3aWxsIGludm9rZSBgY29uc29sZS50cmFjZSgpYCBpbnN0ZWFkIG9mIGBjb25zb2xlLmVycm9yKClgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGRlcHJlY2F0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG1zZyAtIHRoZSBzdHJpbmcgdG8gcHJpbnQgdG8gdGhlIGNvbnNvbGUgd2hlbiBgZm5gIGlzIGludm9rZWRcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gYSBuZXcgXCJkZXByZWNhdGVkXCIgdmVyc2lvbiBvZiBgZm5gXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZSAoZm4sIG1zZykge1xuICBpZiAoY29uZmlnKCdub0RlcHJlY2F0aW9uJykpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChjb25maWcoJ3Rocm93RGVwcmVjYXRpb24nKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAoY29uZmlnKCd0cmFjZURlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBgbG9jYWxTdG9yYWdlYCBmb3IgYm9vbGVhbiB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBgbmFtZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm5zIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gY29uZmlnIChuYW1lKSB7XG4gIC8vIGFjY2Vzc2luZyBnbG9iYWwubG9jYWxTdG9yYWdlIGNhbiB0cmlnZ2VyIGEgRE9NRXhjZXB0aW9uIGluIHNhbmRib3hlZCBpZnJhbWVzXG4gIHRyeSB7XG4gICAgaWYgKCFnbG9iYWwubG9jYWxTdG9yYWdlKSByZXR1cm4gZmFsc2U7XG4gIH0gY2F0Y2ggKF8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHZhbCA9IGdsb2JhbC5sb2NhbFN0b3JhZ2VbbmFtZV07XG4gIGlmIChudWxsID09IHZhbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gU3RyaW5nKHZhbCkudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnO1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0J1ZmZlcihhcmcpIHtcbiAgcmV0dXJuIGFyZyAmJiB0eXBlb2YgYXJnID09PSAnb2JqZWN0J1xuICAgICYmIHR5cGVvZiBhcmcuY29weSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcuZmlsbCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICYmIHR5cGVvZiBhcmcucmVhZFVJbnQ4ID09PSAnZnVuY3Rpb24nO1xufSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgZm9ybWF0UmVnRXhwID0gLyVbc2RqJV0vZztcbmV4cG9ydHMuZm9ybWF0ID0gZnVuY3Rpb24oZikge1xuICBpZiAoIWlzU3RyaW5nKGYpKSB7XG4gICAgdmFyIG9iamVjdHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgb2JqZWN0cy5wdXNoKGluc3BlY3QoYXJndW1lbnRzW2ldKSk7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHZhciBpID0gMTtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciBsZW4gPSBhcmdzLmxlbmd0aDtcbiAgdmFyIHN0ciA9IFN0cmluZyhmKS5yZXBsYWNlKGZvcm1hdFJlZ0V4cCwgZnVuY3Rpb24oeCkge1xuICAgIGlmICh4ID09PSAnJSUnKSByZXR1cm4gJyUnO1xuICAgIGlmIChpID49IGxlbikgcmV0dXJuIHg7XG4gICAgc3dpdGNoICh4KSB7XG4gICAgICBjYXNlICclcyc6IHJldHVybiBTdHJpbmcoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVkJzogcmV0dXJuIE51bWJlcihhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWonOlxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShhcmdzW2krK10pO1xuICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHg7XG4gICAgfVxuICB9KTtcbiAgZm9yICh2YXIgeCA9IGFyZ3NbaV07IGkgPCBsZW47IHggPSBhcmdzWysraV0pIHtcbiAgICBpZiAoaXNOdWxsKHgpIHx8ICFpc09iamVjdCh4KSkge1xuICAgICAgc3RyICs9ICcgJyArIHg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnICcgKyBpbnNwZWN0KHgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3RyO1xufTtcblxuXG4vLyBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuLy8gUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbi8vIElmIC0tbm8tZGVwcmVjYXRpb24gaXMgc2V0LCB0aGVuIGl0IGlzIGEgbm8tb3AuXG5leHBvcnRzLmRlcHJlY2F0ZSA9IGZ1bmN0aW9uKGZuLCBtc2cpIHtcbiAgLy8gQWxsb3cgZm9yIGRlcHJlY2F0aW5nIHRoaW5ncyBpbiB0aGUgcHJvY2VzcyBvZiBzdGFydGluZyB1cC5cbiAgaWYgKGlzVW5kZWZpbmVkKGdsb2JhbC5wcm9jZXNzKSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmRlcHJlY2F0ZShmbiwgbXNnKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cblxuICBpZiAocHJvY2Vzcy5ub0RlcHJlY2F0aW9uID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAocHJvY2Vzcy50aHJvd0RlcHJlY2F0aW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgfSBlbHNlIGlmIChwcm9jZXNzLnRyYWNlRGVwcmVjYXRpb24pIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn07XG5cblxudmFyIGRlYnVncyA9IHt9O1xudmFyIGRlYnVnRW52aXJvbjtcbmV4cG9ydHMuZGVidWdsb2cgPSBmdW5jdGlvbihzZXQpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKGRlYnVnRW52aXJvbikpXG4gICAgZGVidWdFbnZpcm9uID0gcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyB8fCAnJztcbiAgc2V0ID0gc2V0LnRvVXBwZXJDYXNlKCk7XG4gIGlmICghZGVidWdzW3NldF0pIHtcbiAgICBpZiAobmV3IFJlZ0V4cCgnXFxcXGInICsgc2V0ICsgJ1xcXFxiJywgJ2knKS50ZXN0KGRlYnVnRW52aXJvbikpIHtcbiAgICAgIHZhciBwaWQgPSBwcm9jZXNzLnBpZDtcbiAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBtc2cgPSBleHBvcnRzLmZvcm1hdC5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCclcyAlZDogJXMnLCBzZXQsIHBpZCwgbXNnKTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnc1tzZXRdID0gZnVuY3Rpb24oKSB7fTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRlYnVnc1tzZXRdO1xufTtcblxuXG4vKipcbiAqIEVjaG9zIHRoZSB2YWx1ZSBvZiBhIHZhbHVlLiBUcnlzIHRvIHByaW50IHRoZSB2YWx1ZSBvdXRcbiAqIGluIHRoZSBiZXN0IHdheSBwb3NzaWJsZSBnaXZlbiB0aGUgZGlmZmVyZW50IHR5cGVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBwcmludCBvdXQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyBPcHRpb25hbCBvcHRpb25zIG9iamVjdCB0aGF0IGFsdGVycyB0aGUgb3V0cHV0LlxuICovXG4vKiBsZWdhY3k6IG9iaiwgc2hvd0hpZGRlbiwgZGVwdGgsIGNvbG9ycyovXG5mdW5jdGlvbiBpbnNwZWN0KG9iaiwgb3B0cykge1xuICAvLyBkZWZhdWx0IG9wdGlvbnNcbiAgdmFyIGN0eCA9IHtcbiAgICBzZWVuOiBbXSxcbiAgICBzdHlsaXplOiBzdHlsaXplTm9Db2xvclxuICB9O1xuICAvLyBsZWdhY3kuLi5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykgY3R4LmRlcHRoID0gYXJndW1lbnRzWzJdO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSBjdHguY29sb3JzID0gYXJndW1lbnRzWzNdO1xuICBpZiAoaXNCb29sZWFuKG9wdHMpKSB7XG4gICAgLy8gbGVnYWN5Li4uXG4gICAgY3R4LnNob3dIaWRkZW4gPSBvcHRzO1xuICB9IGVsc2UgaWYgKG9wdHMpIHtcbiAgICAvLyBnb3QgYW4gXCJvcHRpb25zXCIgb2JqZWN0XG4gICAgZXhwb3J0cy5fZXh0ZW5kKGN0eCwgb3B0cyk7XG4gIH1cbiAgLy8gc2V0IGRlZmF1bHQgb3B0aW9uc1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LnNob3dIaWRkZW4pKSBjdHguc2hvd0hpZGRlbiA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmRlcHRoKSkgY3R4LmRlcHRoID0gMjtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jb2xvcnMpKSBjdHguY29sb3JzID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY3VzdG9tSW5zcGVjdCkpIGN0eC5jdXN0b21JbnNwZWN0ID0gdHJ1ZTtcbiAgaWYgKGN0eC5jb2xvcnMpIGN0eC5zdHlsaXplID0gc3R5bGl6ZVdpdGhDb2xvcjtcbiAgcmV0dXJuIGZvcm1hdFZhbHVlKGN0eCwgb2JqLCBjdHguZGVwdGgpO1xufVxuZXhwb3J0cy5pbnNwZWN0ID0gaW5zcGVjdDtcblxuXG4vLyBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0FOU0lfZXNjYXBlX2NvZGUjZ3JhcGhpY3Ncbmluc3BlY3QuY29sb3JzID0ge1xuICAnYm9sZCcgOiBbMSwgMjJdLFxuICAnaXRhbGljJyA6IFszLCAyM10sXG4gICd1bmRlcmxpbmUnIDogWzQsIDI0XSxcbiAgJ2ludmVyc2UnIDogWzcsIDI3XSxcbiAgJ3doaXRlJyA6IFszNywgMzldLFxuICAnZ3JleScgOiBbOTAsIDM5XSxcbiAgJ2JsYWNrJyA6IFszMCwgMzldLFxuICAnYmx1ZScgOiBbMzQsIDM5XSxcbiAgJ2N5YW4nIDogWzM2LCAzOV0sXG4gICdncmVlbicgOiBbMzIsIDM5XSxcbiAgJ21hZ2VudGEnIDogWzM1LCAzOV0sXG4gICdyZWQnIDogWzMxLCAzOV0sXG4gICd5ZWxsb3cnIDogWzMzLCAzOV1cbn07XG5cbi8vIERvbid0IHVzZSAnYmx1ZScgbm90IHZpc2libGUgb24gY21kLmV4ZVxuaW5zcGVjdC5zdHlsZXMgPSB7XG4gICdzcGVjaWFsJzogJ2N5YW4nLFxuICAnbnVtYmVyJzogJ3llbGxvdycsXG4gICdib29sZWFuJzogJ3llbGxvdycsXG4gICd1bmRlZmluZWQnOiAnZ3JleScsXG4gICdudWxsJzogJ2JvbGQnLFxuICAnc3RyaW5nJzogJ2dyZWVuJyxcbiAgJ2RhdGUnOiAnbWFnZW50YScsXG4gIC8vIFwibmFtZVwiOiBpbnRlbnRpb25hbGx5IG5vdCBzdHlsaW5nXG4gICdyZWdleHAnOiAncmVkJ1xufTtcblxuXG5mdW5jdGlvbiBzdHlsaXplV2l0aENvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHZhciBzdHlsZSA9IGluc3BlY3Quc3R5bGVzW3N0eWxlVHlwZV07XG5cbiAgaWYgKHN0eWxlKSB7XG4gICAgcmV0dXJuICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMF0gKyAnbScgKyBzdHIgK1xuICAgICAgICAgICAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzFdICsgJ20nO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBzdHlsaXplTm9Db2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICByZXR1cm4gc3RyO1xufVxuXG5cbmZ1bmN0aW9uIGFycmF5VG9IYXNoKGFycmF5KSB7XG4gIHZhciBoYXNoID0ge307XG5cbiAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbih2YWwsIGlkeCkge1xuICAgIGhhc2hbdmFsXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBoYXNoO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFZhbHVlKGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcykge1xuICAvLyBQcm92aWRlIGEgaG9vayBmb3IgdXNlci1zcGVjaWZpZWQgaW5zcGVjdCBmdW5jdGlvbnMuXG4gIC8vIENoZWNrIHRoYXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW4gaW5zcGVjdCBmdW5jdGlvbiBvbiBpdFxuICBpZiAoY3R4LmN1c3RvbUluc3BlY3QgJiZcbiAgICAgIHZhbHVlICYmXG4gICAgICBpc0Z1bmN0aW9uKHZhbHVlLmluc3BlY3QpICYmXG4gICAgICAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcbiAgICAgIHZhbHVlLmluc3BlY3QgIT09IGV4cG9ydHMuaW5zcGVjdCAmJlxuICAgICAgLy8gQWxzbyBmaWx0ZXIgb3V0IGFueSBwcm90b3R5cGUgb2JqZWN0cyB1c2luZyB0aGUgY2lyY3VsYXIgY2hlY2suXG4gICAgICAhKHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSA9PT0gdmFsdWUpKSB7XG4gICAgdmFyIHJldCA9IHZhbHVlLmluc3BlY3QocmVjdXJzZVRpbWVzLCBjdHgpO1xuICAgIGlmICghaXNTdHJpbmcocmV0KSkge1xuICAgICAgcmV0ID0gZm9ybWF0VmFsdWUoY3R4LCByZXQsIHJlY3Vyc2VUaW1lcyk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICAvLyBQcmltaXRpdmUgdHlwZXMgY2Fubm90IGhhdmUgcHJvcGVydGllc1xuICB2YXIgcHJpbWl0aXZlID0gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpO1xuICBpZiAocHJpbWl0aXZlKSB7XG4gICAgcmV0dXJuIHByaW1pdGl2ZTtcbiAgfVxuXG4gIC8vIExvb2sgdXAgdGhlIGtleXMgb2YgdGhlIG9iamVjdC5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7XG4gIHZhciB2aXNpYmxlS2V5cyA9IGFycmF5VG9IYXNoKGtleXMpO1xuXG4gIGlmIChjdHguc2hvd0hpZGRlbikge1xuICAgIGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh2YWx1ZSk7XG4gIH1cblxuICAvLyBJRSBkb2Vzbid0IG1ha2UgZXJyb3IgZmllbGRzIG5vbi1lbnVtZXJhYmxlXG4gIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9kd3c1MnNidCh2PXZzLjk0KS5hc3B4XG4gIGlmIChpc0Vycm9yKHZhbHVlKVxuICAgICAgJiYgKGtleXMuaW5kZXhPZignbWVzc2FnZScpID49IDAgfHwga2V5cy5pbmRleE9mKCdkZXNjcmlwdGlvbicpID49IDApKSB7XG4gICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIC8vIFNvbWUgdHlwZSBvZiBvYmplY3Qgd2l0aG91dCBwcm9wZXJ0aWVzIGNhbiBiZSBzaG9ydGN1dHRlZC5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICB2YXIgbmFtZSA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZSArICddJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShEYXRlLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ2RhdGUnKTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBiYXNlID0gJycsIGFycmF5ID0gZmFsc2UsIGJyYWNlcyA9IFsneycsICd9J107XG5cbiAgLy8gTWFrZSBBcnJheSBzYXkgdGhhdCB0aGV5IGFyZSBBcnJheVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBhcnJheSA9IHRydWU7XG4gICAgYnJhY2VzID0gWydbJywgJ10nXTtcbiAgfVxuXG4gIC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICB2YXIgbiA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgIGJhc2UgPSAnIFtGdW5jdGlvbicgKyBuICsgJ10nO1xuICB9XG5cbiAgLy8gTWFrZSBSZWdFeHBzIHNheSB0aGF0IHRoZXkgYXJlIFJlZ0V4cHNcbiAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG4gIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyBicmFjZXNbMV07XG4gIH1cblxuICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW09iamVjdF0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5zZWVuLnB1c2godmFsdWUpO1xuXG4gIHZhciBvdXRwdXQ7XG4gIGlmIChhcnJheSkge1xuICAgIG91dHB1dCA9IGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IGtleXMubWFwKGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuICAgIH0pO1xuICB9XG5cbiAgY3R4LnNlZW4ucG9wKCk7XG5cbiAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSkge1xuICBpZiAoaXNVbmRlZmluZWQodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgndW5kZWZpbmVkJywgJ3VuZGVmaW5lZCcpO1xuICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgdmFyIHNpbXBsZSA9ICdcXCcnICsgSlNPTi5zdHJpbmdpZnkodmFsdWUpLnJlcGxhY2UoL15cInxcIiQvZywgJycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpICsgJ1xcJyc7XG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKHNpbXBsZSwgJ3N0cmluZycpO1xuICB9XG4gIGlmIChpc051bWJlcih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdudW1iZXInKTtcbiAgaWYgKGlzQm9vbGVhbih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdib29sZWFuJyk7XG4gIC8vIEZvciBzb21lIHJlYXNvbiB0eXBlb2YgbnVsbCBpcyBcIm9iamVjdFwiLCBzbyBzcGVjaWFsIGNhc2UgaGVyZS5cbiAgaWYgKGlzTnVsbCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCdudWxsJywgJ251bGwnKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRFcnJvcih2YWx1ZSkge1xuICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpIHtcbiAgdmFyIG91dHB1dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eSh2YWx1ZSwgU3RyaW5nKGkpKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBTdHJpbmcoaSksIHRydWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgIH1cbiAgfVxuICBrZXlzLmZvckVhY2goZnVuY3Rpb24oa2V5KSB7XG4gICAgaWYgKCFrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIGtleSwgdHJ1ZSkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSkge1xuICB2YXIgbmFtZSwgc3RyLCBkZXNjO1xuICBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KSB8fCB7IHZhbHVlOiB2YWx1ZVtrZXldIH07XG4gIGlmIChkZXNjLmdldCkge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXIvU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tTZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFoYXNPd25Qcm9wZXJ0eSh2aXNpYmxlS2V5cywga2V5KSkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoY3R4LnNlZW4uaW5kZXhPZihkZXNjLnZhbHVlKSA8IDApIHtcbiAgICAgIGlmIChpc051bGwocmVjdXJzZVRpbWVzKSkge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCByZWN1cnNlVGltZXMgLSAxKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdHIuaW5kZXhPZignXFxuJykgPiAtMSkge1xuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBzdHIgPSBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJykuc3Vic3RyKDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0ciA9ICdcXG4nICsgc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0NpcmN1bGFyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmIChpc1VuZGVmaW5lZChuYW1lKSkge1xuICAgIGlmIChhcnJheSAmJiBrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgICBuYW1lID0gSlNPTi5zdHJpbmdpZnkoJycgKyBrZXkpO1xuICAgIGlmIChuYW1lLm1hdGNoKC9eXCIoW2EtekEtWl9dW2EtekEtWl8wLTldKilcIiQvKSkge1xuICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyKDEsIG5hbWUubGVuZ3RoIC0gMik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ25hbWUnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJylcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLyheXCJ8XCIkKS9nLCBcIidcIik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ3N0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuYW1lICsgJzogJyArIHN0cjtcbn1cblxuXG5mdW5jdGlvbiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcykge1xuICB2YXIgbnVtTGluZXNFc3QgPSAwO1xuICB2YXIgbGVuZ3RoID0gb3V0cHV0LnJlZHVjZShmdW5jdGlvbihwcmV2LCBjdXIpIHtcbiAgICBudW1MaW5lc0VzdCsrO1xuICAgIGlmIChjdXIuaW5kZXhPZignXFxuJykgPj0gMCkgbnVtTGluZXNFc3QrKztcbiAgICByZXR1cm4gcHJldiArIGN1ci5yZXBsYWNlKC9cXHUwMDFiXFxbXFxkXFxkP20vZywgJycpLmxlbmd0aCArIDE7XG4gIH0sIDApO1xuXG4gIGlmIChsZW5ndGggPiA2MCkge1xuICAgIHJldHVybiBicmFjZXNbMF0gK1xuICAgICAgICAgICAoYmFzZSA9PT0gJycgPyAnJyA6IGJhc2UgKyAnXFxuICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgb3V0cHV0LmpvaW4oJyxcXG4gICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgYnJhY2VzWzFdO1xuICB9XG5cbiAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcbn1cblxuXG4vLyBOT1RFOiBUaGVzZSB0eXBlIGNoZWNraW5nIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBgaW5zdGFuY2VvZmBcbi8vIGJlY2F1c2UgaXQgaXMgZnJhZ2lsZSBhbmQgY2FuIGJlIGVhc2lseSBmYWtlZCB3aXRoIGBPYmplY3QuY3JlYXRlKClgLlxuZnVuY3Rpb24gaXNBcnJheShhcikge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShhcik7XG59XG5leHBvcnRzLmlzQXJyYXkgPSBpc0FycmF5O1xuXG5mdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG59XG5leHBvcnRzLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGwgPSBpc051bGw7XG5cbmZ1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkID0gaXNOdWxsT3JVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5leHBvcnRzLmlzTnVtYmVyID0gaXNOdW1iZXI7XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N0cmluZyc7XG59XG5leHBvcnRzLmlzU3RyaW5nID0gaXNTdHJpbmc7XG5cbmZ1bmN0aW9uIGlzU3ltYm9sKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCc7XG59XG5leHBvcnRzLmlzU3ltYm9sID0gaXNTeW1ib2w7XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5leHBvcnRzLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG4gIHJldHVybiBpc09iamVjdChyZSkgJiYgb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBpc09iamVjdChkKSAmJiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gaXNPYmplY3QoZSkgJiZcbiAgICAgIChvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJyB8fCBlIGluc3RhbmNlb2YgRXJyb3IpO1xufVxuZXhwb3J0cy5pc0Vycm9yID0gaXNFcnJvcjtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnIHx8ICAvLyBFUzYgc3ltYm9sXG4gICAgICAgICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcbn1cbmV4cG9ydHMuaXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZTtcblxuZXhwb3J0cy5pc0J1ZmZlciA9IHJlcXVpcmUoJy4vc3VwcG9ydC9pc0J1ZmZlcicpO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cblxuZnVuY3Rpb24gcGFkKG4pIHtcbiAgcmV0dXJuIG4gPCAxMCA/ICcwJyArIG4udG9TdHJpbmcoMTApIDogbi50b1N0cmluZygxMCk7XG59XG5cblxudmFyIG1vbnRocyA9IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLFxuICAgICAgICAgICAgICAnT2N0JywgJ05vdicsICdEZWMnXTtcblxuLy8gMjYgRmViIDE2OjE5OjM0XG5mdW5jdGlvbiB0aW1lc3RhbXAoKSB7XG4gIHZhciBkID0gbmV3IERhdGUoKTtcbiAgdmFyIHRpbWUgPSBbcGFkKGQuZ2V0SG91cnMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldE1pbnV0ZXMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldFNlY29uZHMoKSldLmpvaW4oJzonKTtcbiAgcmV0dXJuIFtkLmdldERhdGUoKSwgbW9udGhzW2QuZ2V0TW9udGgoKV0sIHRpbWVdLmpvaW4oJyAnKTtcbn1cblxuXG4vLyBsb2cgaXMganVzdCBhIHRoaW4gd3JhcHBlciB0byBjb25zb2xlLmxvZyB0aGF0IHByZXBlbmRzIGEgdGltZXN0YW1wXG5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICBjb25zb2xlLmxvZygnJXMgLSAlcycsIHRpbWVzdGFtcCgpLCBleHBvcnRzLmZvcm1hdC5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpKTtcbn07XG5cblxuLyoqXG4gKiBJbmhlcml0IHRoZSBwcm90b3R5cGUgbWV0aG9kcyBmcm9tIG9uZSBjb25zdHJ1Y3RvciBpbnRvIGFub3RoZXIuXG4gKlxuICogVGhlIEZ1bmN0aW9uLnByb3RvdHlwZS5pbmhlcml0cyBmcm9tIGxhbmcuanMgcmV3cml0dGVuIGFzIGEgc3RhbmRhbG9uZVxuICogZnVuY3Rpb24gKG5vdCBvbiBGdW5jdGlvbi5wcm90b3R5cGUpLiBOT1RFOiBJZiB0aGlzIGZpbGUgaXMgdG8gYmUgbG9hZGVkXG4gKiBkdXJpbmcgYm9vdHN0cmFwcGluZyB0aGlzIGZ1bmN0aW9uIG5lZWRzIHRvIGJlIHJld3JpdHRlbiB1c2luZyBzb21lIG5hdGl2ZVxuICogZnVuY3Rpb25zIGFzIHByb3RvdHlwZSBzZXR1cCB1c2luZyBub3JtYWwgSmF2YVNjcmlwdCBkb2VzIG5vdCB3b3JrIGFzXG4gKiBleHBlY3RlZCBkdXJpbmcgYm9vdHN0cmFwcGluZyAoc2VlIG1pcnJvci5qcyBpbiByMTE0OTAzKS5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHdoaWNoIG5lZWRzIHRvIGluaGVyaXQgdGhlXG4gKiAgICAgcHJvdG90eXBlLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gc3VwZXJDdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHRvIGluaGVyaXQgcHJvdG90eXBlIGZyb20uXG4gKi9cbmV4cG9ydHMuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5leHBvcnRzLl9leHRlbmQgPSBmdW5jdGlvbihvcmlnaW4sIGFkZCkge1xuICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiBhZGQgaXNuJ3QgYW4gb2JqZWN0XG4gIGlmICghYWRkIHx8ICFpc09iamVjdChhZGQpKSByZXR1cm4gb3JpZ2luO1xuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMoYWRkKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcbiAgfVxuICByZXR1cm4gb3JpZ2luO1xufTtcblxuZnVuY3Rpb24gaGFzT3duUHJvcGVydHkob2JqLCBwcm9wKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKTtcbn1cbiJdfQ== diff --git a/build/peerplaysjs-lib.min.js b/build/peerplaysjs-lib.min.js index 2af404d..e69d03f 100644 --- a/build/peerplaysjs-lib.min.js +++ b/build/peerplaysjs-lib.min.js @@ -1 +1 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).peerplays_js=e()}}(function(){return function o(s,a,f){function u(t,e){if(!a[t]){if(!s[t]){var r="function"==typeof require&&require;if(!e&&r)return r(t,!0);if(c)return c(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var i=a[t]={exports:{}};s[t][0].call(i.exports,function(e){return u(s[t][1][e]||e)},i,i.exports,o,s,a,f)}return a[t].exports}for(var c="function"==typeof require&&require,e=0;e %s (%d bytes)",o.operation_name,i[1],s,s.length/2)}a.tr_buffer=p.ops.transaction.toBuffer(a)}))})},e.prototype.id=function(){if(!this.tr_buffer)throw new Error("not finalized");return a.hash.sha256(this.tr_buffer).toString("hex").substring(0,40)},e.prototype.add_operation=function(e){if(this.tr_buffer)throw new Error("already finalized");if((0,u.default)(e,"operation"),!Array.isArray(e))throw new Error("Expecting array [operation_id, operation]");this.operations.push(e)},e.prototype.get_type_operation=function(e,t){if(this.tr_buffer)throw new Error("already finalized");(0,u.default)(e,"name"),(0,u.default)(t,"operation");var r=p.ops[e];(0,u.default)(r,"Unknown operation "+e);var n=c.default.operations[r.operation_name];if(void 0===n)throw new Error("unknown operation: "+r.operation_name);if(t.fee||(t.fee={amount:0,asset_id:0}),"proposal_create"===e){var i=!1,o=0;if(t.proposed_ops.forEach(function(e){var t=void 0;switch(e.op[0]){case 0:t="from";break;case 6:case 17:t="account";break;case 10:case 11:case 12:case 13:case 14:case 18:case 43:t="issuer";break;case 15:t="payer";break;case 16:t="from_account";break;case 22:case 23:case 24:t="fee_paying_account";break;case 31:i=!0,o=1123200}t in e.op[1]&&0===e.op[1][t]&&(i=!0)}),!t.expiration_time){var s=this.base_expiration_sec();t.expiration_time=s+l.ChainConfig.expire_in_secs_proposal}if(i){var a=Math.max(this.commitee_min_review,86400,l.ChainConfig.review_in_secs_committee);t.review_period_seconds=o+a,t.expiration_time+=3600+o}}return[n,r.fromObject(t)]},e.prototype.update_head_block=function(){var n=this;return l.Apis.instance().db_api().exec("get_objects",[["2.0.0","2.1.0"]]).then(function(e){var t=e[0],r=e[1];n.head_block_time_string=r[0].time,n.committee_min_review=t[0].parameters.committee_proposal_review_period})},e.prototype.set_expire_seconds=function(e){if(this.tr_buffer)throw new Error("already finalized");return this.expiration=this.base_expiration_sec()+e,this.expiration},e.prototype.propose=function(e){if(this.tr_buffer)throw new Error("already finalized");if(!this.operations.length)throw new Error("add operation first");(0,u.default)(e,"proposal_create_options"),(0,u.default)(e.fee_paying_account,"proposal_create_options.fee_paying_account");var t=this.operations.map(function(e){return{op:e}});return this.operations=[],this.signatures=[],this.signer_private_keys=[],e.proposed_ops=t,this.add_type_operation("proposal_create",e),this},e.prototype.has_proposed_operation=function(){for(var e=!1,t=0;tparseInt(h,10)&&(a=f,u="1.3.0")}var i=[];!function e(t){if(Array.isArray(t))for(var r=0,n=t.length;r>1?s.add(i):s,c=e.pointFromX(f,u),h=c.multiply(i);(0,_.default)(e.isInfinity(h),"nR is not a valid curve point");var l=t.negate().mod(i),p=s.modInverse(i),d=c.multiplyTwo(a,o,l).multiply(p);return e.validate(d),d}r.calcPubKeyRecoveryParam=function(e,t,r,n){for(var i=0;i<4;i++)if(o(e,t,r,i).equals(n))return i;throw new Error("Unable to find valid recovery factor")},r.deterministicGenerateK=d,r.recoverPubKey=o,r.sign=function(r,e,n,t){var i=c.default.fromBuffer(e),o=r.n,s=r.G,a=void 0,f=void 0;d(r,e,n,function(e){var t=s.multiply(e);return!r.isInfinity(t)&&0!==(a=t.affineX.mod(o)).signum()&&0!==(f=e.modInverse(o).multiply(i.add(n.multiply(a))).mod(o)).signum()},t);var u=o.shiftRight(1);return 0i.length;)e.writeUint8(0)}},n.public_key=function(e,t){var r=void 0;if(e)return t?(r=t.toBuffer(),void e.append(r.toString("binary"),"binary")):(r=n.fixed_data(e,33),i.default.fromBuffer(r))},n.ripemd160=function(e,t){if(e)return t?void n.fixed_data(e,20,t):n.fixed_data(e,20)},n.sha256=function(e,t){if(e)return t?void n.fixed_data(e,32,t):n.fixed_data(e,32)},n.time_point_sec=function(e,t){if(!t)return t=e.readInt32(),new Date(1e3*t);t=Math.ceil(t/1e3),e.writeInt32(t)},n}();a.default=r,s.exports=a.default}).call(this,n(35).Buffer)},{11:11,35:35}],21:[function(e,t,r){"use strict";r.__esModule=!0;var n,i="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},o=e(38),s=e(3),a=(n=s)&&n.__esModule?n:{default:n};var f=9007199254740991,u=-9007199254740991,c={is_empty:function(e){return null==e},required:function(e){var t=1>=8;for(;0>=8}for(var s=0;e[s]===c&&s>16&255,o[s++]=t>>8&255,o[s++]=255&t;var u,c;2===i&&(t=h[e.charCodeAt(f)]<<2|h[e.charCodeAt(f+1)]>>4,o[s++]=255&t);1===i&&(t=h[e.charCodeAt(f)]<<10|h[e.charCodeAt(f+1)]<<4|h[e.charCodeAt(f+2)]>>2,o[s++]=t>>8&255,o[s++]=255&t);return o},r.fromByteArray=function(e){for(var t,r=e.length,n=r%3,i=[],o=0,s=r-n;o>2]+a[t<<4&63]+"==")):2===n&&(t=(e[r-2]<<8)+e[r-1],i.push(a[t>>10]+a[t>>4&63]+a[t<<2&63]+"="));return i.join("")};for(var a=[],h=[],l="undefined"!=typeof Uint8Array?Uint8Array:Array,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,o=n.length;i>18&63]+a[i>>12&63]+a[i>>6&63]+a[63&i]);return o.join("")}h["-".charCodeAt(0)]=62,h["_".charCodeAt(0)]=63},{}],30:[function(e,t,r){function b(e,t,r){if(!(this instanceof b))return new b(e,t,r);null!=e&&("number"==typeof e?this.fromNumber(e,t,r):null==t&&"string"!=typeof e?this.fromString(e,256):this.fromString(e,t))}var n=b.prototype;n.__bigi=e(33).version,b.isBigInteger=function(e,t){return e&&e.__bigi&&(!t||e.__bigi===n.__bigi)},b.prototype.am=function(e,t,r,n,i,o){for(;0<=--o;){var s=t*this[e++]+r[n]+i;i=Math.floor(s/67108864),r[n++]=67108863&s}return i},b.prototype.DB=26,b.prototype.DM=67108863;var i=b.prototype.DV=1<<26;b.prototype.FV=Math.pow(2,52),b.prototype.F1=26,b.prototype.F2=0;var o,s,a="0123456789abcdefghijklmnopqrstuvwxyz",f=new Array;for(o="0".charCodeAt(0),s=0;s<=9;++s)f[o++]=s;for(o="a".charCodeAt(0),s=10;s<36;++s)f[o++]=s;for(o="A".charCodeAt(0),s=10;s<36;++s)f[o++]=s;function u(e){return a.charAt(e)}function c(e,t){var r=f[e.charCodeAt(t)];return null==r?-1:r}function g(e){var t=new b;return t.fromInt(e),t}function w(e){var t,r=1;return 0!=(t=e>>>16)&&(e=t,r+=16),0!=(t=e>>8)&&(e=t,r+=8),0!=(t=e>>4)&&(e=t,r+=4),0!=(t=e>>2)&&(e=t,r+=2),0!=(t=e>>1)&&(e=t,r+=1),r}function m(e){this.m=e}function v(e){this.m=e,this.mp=e.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<>=16,t+=16),0==(255&e)&&(e>>=8,t+=8),0==(15&e)&&(e>>=4,t+=4),0==(3&e)&&(e>>=2,t+=2),0==(1&e)&&++t,t}function y(e){for(var t=0;0!=e;)e&=e-1,++t;return t}function E(){}function B(e){return e}function k(e){this.r2=new b,this.q3=new b,b.ONE.dlShiftTo(2*e.t,this.r2),this.mu=this.r2.divide(e),this.m=e}m.prototype.convert=function(e){return e.s<0||0<=e.compareTo(this.m)?e.mod(this.m):e},m.prototype.revert=function(e){return e},m.prototype.reduce=function(e){e.divRemTo(this.m,null,e)},m.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},m.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},v.prototype.convert=function(e){var t=new b;return e.abs().dlShiftTo(this.m.t,t),t.divRemTo(this.m,null,t),e.s<0&&0>15)*this.mpl&this.um)<<15)&e.DM;for(e[r=t+this.m.t]+=this.m.am(0,n,e,t,0,this.m.t);e[r]>=e.DV;)e[r]-=e.DV,e[++r]++}e.clamp(),e.drShiftTo(this.m.t,e),0<=e.compareTo(this.m)&&e.subTo(this.m,e)},v.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},v.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},n.copyTo=function(e){for(var t=this.t-1;0<=t;--t)e[t]=this[t];e.t=this.t,e.s=this.s},n.fromInt=function(e){this.t=1,this.s=e<0?-1:0,0n.DB?(n[n.t-1]|=(a&(1<>n.DB-s):n[n.t-1]|=a<=n.DB&&(s-=n.DB))}8==r&&0!=(128&e[0])&&(n.s=-1,0>o|f,f=(n[r]&s)<=r.t)t.t=0;else{var i=e%r.DB,o=r.DB-i,s=(1<>i;for(var a=n+1;a>i;0>=r.DB;if(e.t>=r.DB;i+=r.s}else{for(i+=r.s;n>=r.DB;i-=e.s}t.s=i<0?-1:0,i<-1?t[n++]=r.DV+i:0=t.DV&&(e[r+t.t]-=t.DV,e[r+t.t+1]=1)}0>n.F2:0),p=n.FV/l,d=(1<>f)&&(o=!0,s=u(n));0<=a;)f>(f+=r.DB-t)):(n=r[a]>>(f-=t)&i,f<=0&&(f+=r.DB,--a)),0>3},n.mod=function(e){var t=new b;return this.abs().divRemTo(e,null,t),this.s<0&&02*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=new b;return e.copyTo(t),this.reduce(t),t},k.prototype.revert=function(e){return e},k.prototype.reduce=function(e){var t=this;for(e.drShiftTo(t.m.t-1,t.r2),e.t>t.m.t+1&&(e.t=t.m.t+1,e.clamp()),t.mu.multiplyUpperTo(t.r2,t.m.t+1,t.q3),t.m.multiplyLowerTo(t.q3,t.m.t+1,t.r2);e.compareTo(t.r2)<0;)e.dAddOffset(1,t.m.t+1);for(e.subTo(t.r2,e);0<=e.compareTo(t.m);)e.subTo(t.m,e)},k.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},k.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)};var T=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],S=(1<<26)/T[T.length-1];n.chunkSize=function(e){return Math.floor(Math.LN2*this.DB/Math.log(e))},n.toRadix=function(e){if(null==e&&(e=10),0==this.signum()||e<2||36=n&&(r.dMultiply(i),r.dAddOffset(a,0),a=s=0))}0e&&n.subTo(b.ONE.shiftLeft(e-1),n);else{var i=new Array,o=7&e;i.length=1+(e>>3),t.nextBytes(i),0>=r.DB;if(e.t>=r.DB;i+=r.s}else{for(i+=r.s;n>=r.DB;i+=e.s}t.s=i<0?-1:0,0=this.DV;)this[t]-=this.DV,++t>=this.t&&(this[this.t++]=0),++this[t]}},n.multiplyLowerTo=function(e,t,r){var n,i=Math.min(this.t+e.t,t);for(r.s=0,r.t=i;0>1)&&(e=T.length);for(var i=new b(null),o=[],s=0;s>24},n.shortValue=function(){return 0==this.t?this.s:this[0]<<16>>16},n.signum=function(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1},n.toByteArray=function(){var e=this,t=e.t,r=new Array;r[0]=e.s;var n,i=e.DB-t*e.DB%8,o=0;if(0>i)!=(e.s&e.DM)>>i&&(r[o++]=n|e.s<>(i+=e.DB-8)):(n=e[t]>>(i-=8)&255,i<=0&&(i+=e.DB,--t)),0!=(128&n)&&(n|=-256),0===o&&(128&e.s)!=(128&n)&&++o,(0=this.t?0!=this.s:0!=(this[t]&1<>i-f&u:(h=(e[p]&(1<>this.DB+i-f)),a=r;0==(1&h);)h>>=1,--a;if((i-=a)<0&&(i+=this.DB,--p),d)s[h].copyTo(o),d=!1;else{for(;1=r())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+r().toString(16)+" bytes");return 0|e}function p(e,t){if(h.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var r=e.length;if(0===r)return 0;for(var n=!1;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return j(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return M(e).length;default:if(n)return j(e).length;t=(""+t).toLowerCase(),n=!0}}function d(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}function _(e,t,r,n,i){if(0===e.length)return-1;if("string"==typeof r?(n=r,r=0):2147483647=e.length){if(i)return-1;r=e.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof t&&(t=h.from(t,n)),h.isBuffer(t))return 0===t.length?-1:g(e,t,r,n,i);if("number"==typeof t)return t&=255,h.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):g(e,[t],r,n,i);throw new TypeError("val must be string, number or Buffer")}function g(e,t,r,n,i){var o,s=1,a=e.length,f=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;a/=s=2,f/=2,r/=2}function u(e,t){return 1===s?e[t]:e.readUInt16BE(t*s)}if(i){var c=-1;for(o=r;o>>10&1023|55296),c=56320|1023&c),n.push(c),i+=h}return function(e){var t=e.length;if(t<=w)return String.fromCharCode.apply(String,e);var r="",n=0;for(;nthis.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return k(this,t,r);case"utf8":case"utf-8":return b(this,t,r);case"ascii":return E(this,t,r);case"latin1":case"binary":return B(this,t,r);case"base64":return y(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return T(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}.apply(this,arguments)},h.prototype.equals=function(e){if(!h.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===h.compare(this,e)},h.prototype.inspect=function(){var e="",t=q.INSPECT_MAX_BYTES;return 0t&&(e+=" ... ")),""},h.prototype.compare=function(e,t,r,n,i){if(!h.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),t<0||r>e.length||n<0||i>this.length)throw new RangeError("out of range index");if(i<=n&&r<=t)return 0;if(i<=n)return-1;if(r<=t)return 1;if(this===e)return 0;for(var o=(i>>>=0)-(n>>>=0),s=(r>>>=0)-(t>>>=0),a=Math.min(o,s),f=this.slice(n,i),u=e.slice(t,r),c=0;cthis.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var o,s,a,f,u,c,h,l,p,d=!1;;)switch(n){case"hex":return m(this,e,t,r);case"utf8":case"utf-8":return l=t,p=r,D(j(e,(h=this).length-l),h,l,p);case"ascii":return v(this,e,t,r);case"latin1":case"binary":return v(this,e,t,r);case"base64":return f=this,u=t,c=r,D(M(e),f,u,c);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return s=t,a=r,D(function(e,t){for(var r,n,i,o=[],s=0;s>8,i=r%256,o.push(i),o.push(n);return o}(e,(o=this).length-s),o,s,a);default:if(d)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),d=!0}},h.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var w=4096;function E(e,t,r){var n="";r=Math.min(e.length,r);for(var i=t;ie.length)throw new RangeError("Index out of range")}function I(e,t,r,n){t<0&&(t=65535+t+1);for(var i=0,o=Math.min(e.length-r,2);i>>8*(n?i:1-i)}function A(e,t,r,n){t<0&&(t=4294967295+t+1);for(var i=0,o=Math.min(e.length-r,4);i>>8*(n?i:3-i)&255}function O(e,t,r,n,i,o){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function L(e,t,r,n,i){return i||O(e,0,r,4),o.write(e,t,r,n,23,4),r+4}function C(e,t,r,n,i){return i||O(e,0,r,8),o.write(e,t,r,n,52,8),r+8}h.prototype.slice=function(e,t){var r,n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):n>>8):I(this,e,t,!0),t+2},h.prototype.writeUInt16BE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,2,65535,0),h.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):I(this,e,t,!1),t+2},h.prototype.writeUInt32LE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,4,4294967295,0),h.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):A(this,e,t,!0),t+4},h.prototype.writeUInt32BE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,4,4294967295,0),h.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},h.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t|=0,!n){var i=Math.pow(2,8*r-1);x(this,e,t,r,i-1,-i)}var o=0,s=1,a=0;for(this[t]=255&e;++o>0)-a&255;return t+r},h.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t|=0,!n){var i=Math.pow(2,8*r-1);x(this,e,t,r,i-1,-i)}var o=r-1,s=1,a=0;for(this[t+o]=255&e;0<=--o&&(s*=256);)e<0&&0===a&&0!==this[t+o+1]&&(a=1),this[t+o]=(e/s>>0)-a&255;return t+r},h.prototype.writeInt8=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,1,127,-128),h.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},h.prototype.writeInt16LE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,2,32767,-32768),h.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):I(this,e,t,!0),t+2},h.prototype.writeInt16BE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,2,32767,-32768),h.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):I(this,e,t,!1),t+2},h.prototype.writeInt32LE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,4,2147483647,-2147483648),h.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):A(this,e,t,!0),t+4},h.prototype.writeInt32BE=function(e,t,r){return e=+e,t|=0,r||x(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),h.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},h.prototype.writeFloatLE=function(e,t,r){return L(this,e,t,!0,r)},h.prototype.writeFloatBE=function(e,t,r){return L(this,e,t,!1,r)},h.prototype.writeDoubleLE=function(e,t,r){return C(this,e,t,!0,r)},h.prototype.writeDoubleBE=function(e,t,r){return C(this,e,t,!1,r)},h.prototype.copy=function(e,t,r,n){if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),0=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(o=t;o>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return o}function M(e){return n.toByteArray(function(e){var t;if((e=(t=e,t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")).replace(R,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function D(e,t,r,n){for(var i=0;i=t.length||i>=e.length);++i)t[i+r]=e[i];return i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{29:29,64:64,67:67}],36:[function(e,t,r){var n=e(35).Buffer,i=n.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};var o=r.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!i(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=a;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=f;break;default:return void(this.write=s)}this.charBuffer=new n(6),this.charReceived=0,this.charLength=0};function s(e){return e.toString(this.encoding)}function a(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function f(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}o.prototype.write=function(e){for(var t="";this.charLength;){var r=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,r),this.charReceived+=r,this.charReceived>5==6){this.charLength=2;break}if(t<=2&&r>>4==14){this.charLength=3;break}if(t<=3&&r>>3==30){this.charLength=4;break}}this.charReceived=t},o.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var r=this.charReceived,n=this.charBuffer,i=this.encoding;t+=n.slice(0,r).toString(i)}return t}},{35:35}],37:[function(e,t,r){var n=e(28);t.exports=n("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")},{28:28}],38:[function(t,e,r){var n,i;n=this,i=function(f){"use strict";var d=function(e,t,r){if(void 0===e&&(e=d.DEFAULT_CAPACITY),void 0===t&&(t=d.DEFAULT_ENDIAN),void 0===r&&(r=d.DEFAULT_NOASSERT),!r){if((e|=0)<0)throw RangeError("Illegal capacity");t=!!t,r=!!r}this.buffer=0===e?o:new ArrayBuffer(e),this.view=0===e?null:new Uint8Array(this.buffer),this.offset=0,this.markedOffset=-1,this.limit=e,this.littleEndian=t,this.noAssert=r};d.VERSION="5.0.1",d.LITTLE_ENDIAN=!0,d.BIG_ENDIAN=!1,d.DEFAULT_CAPACITY=16,d.DEFAULT_ENDIAN=d.BIG_ENDIAN,d.DEFAULT_NOASSERT=!1,d.Long=f||null;var s=d.prototype;s.__isByteBuffer__,Object.defineProperty(s,"__isByteBuffer__",{value:!0,enumerable:!1,configurable:!1});var o=new ArrayBuffer(0),r=String.fromCharCode;function a(e){var t=0;return function(){return t>1,c=-7,h=r?i-1:0,l=r?-1:1,p=e[t+h];for(h+=l,o=p&(1<<-c)-1,p>>=-c,c+=a;0>=-c,c+=n;0>1,l=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:o-1,d=n?1:-1,_=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=c):(s=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-s))<1&&(s--,f*=2),2<=(t+=1<=s+h?l/f:l*Math.pow(2,1-h))*f&&(s++,f/=2),c<=s+h?(a=0,s=c):1<=s+h?(a=(t*f-1)*Math.pow(2,i),s+=h):(a=t*Math.pow(2,h-1)*Math.pow(2,i),s=0));8<=i;e[r+p]=255&a,p+=d,a/=256,i-=8);for(s=s<>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i=t,o=e.length,s=o>>3,a=0;for(t+=this.writeVarint32(o,t);s--;)n=1&!!e[a++]|(1&!!e[a++])<<1|(1&!!e[a++])<<2|(1&!!e[a++])<<3|(1&!!e[a++])<<4|(1&!!e[a++])<<5|(1&!!e[a++])<<6|(1&!!e[a++])<<7,this.writeByte(n,t++);if(a>3,s=0,a=[];for(e+=n.length;o--;)r=this.readByte(e++),a[s++]=!!(1&r),a[s++]=!!(2&r),a[s++]=!!(4&r),a[s++]=!!(8&r),a[s++]=!!(16&r),a[s++]=!!(32&r),a[s++]=!!(64&r),a[s++]=!!(128&r);if(s>f++&1)}return t&&(this.offset=e),a},s.readBytes=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+e>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+"+e+") <= "+this.buffer.byteLength)}var n=this.slice(t,t+e);return r&&(this.offset+=e),n},s.writeBytes=s.append,s.writeInt8=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var n=this.buffer.byteLength;return nt?n:t),t-=1,this.view[t]=e,r&&(this.offset+=1),this},s.writeByte=s.writeInt8,s.readInt8=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=this.view[e];return 128==(128&r)&&(r=-(255-r+1)),t&&(this.offset+=1),r},s.readByte=s.readInt8,s.writeUint8=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var n=this.buffer.byteLength;return nt?n:t),t-=1,this.view[t]=e,r&&(this.offset+=1),this},s.writeUInt8=s.writeUint8,s.readUint8=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=this.view[e];return t&&(this.offset+=1),r},s.readUInt8=s.readUint8,s.writeInt16=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var n=this.buffer.byteLength;return nt?n:t),t-=2,this.littleEndian?(this.view[t+1]=(65280&e)>>>8,this.view[t]=255&e):(this.view[t]=(65280&e)>>>8,this.view[t+1]=255&e),r&&(this.offset+=2),this},s.writeShort=s.writeInt16,s.readInt16=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e],r|=this.view[e+1]<<8):(r=this.view[e]<<8,r|=this.view[e+1]),32768==(32768&r)&&(r=-(65535-r+1)),t&&(this.offset+=2),r},s.readShort=s.readInt16,s.writeUint16=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var n=this.buffer.byteLength;return nt?n:t),t-=2,this.littleEndian?(this.view[t+1]=(65280&e)>>>8,this.view[t]=255&e):(this.view[t]=(65280&e)>>>8,this.view[t+1]=255&e),r&&(this.offset+=2),this},s.writeUInt16=s.writeUint16,s.readUint16=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e],r|=this.view[e+1]<<8):(r=this.view[e]<<8,r|=this.view[e+1]),t&&(this.offset+=2),r},s.readUInt16=s.readUint16,s.writeInt32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var n=this.buffer.byteLength;return nt?n:t),t-=4,this.littleEndian?(this.view[t+3]=e>>>24&255,this.view[t+2]=e>>>16&255,this.view[t+1]=e>>>8&255,this.view[t]=255&e):(this.view[t]=e>>>24&255,this.view[t+1]=e>>>16&255,this.view[t+2]=e>>>8&255,this.view[t+3]=255&e),r&&(this.offset+=4),this},s.writeInt=s.writeInt32,s.readInt32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0):(r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0),r|=0,t&&(this.offset+=4),r},s.readInt=s.readInt32,s.writeUint32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var n=this.buffer.byteLength;return nt?n:t),t-=4,this.littleEndian?(this.view[t+3]=e>>>24&255,this.view[t+2]=e>>>16&255,this.view[t+1]=e>>>8&255,this.view[t]=255&e):(this.view[t]=e>>>24&255,this.view[t+1]=e>>>16&255,this.view[t+2]=e>>>8&255,this.view[t+3]=255&e),r&&(this.offset+=4),this},s.writeUInt32=s.writeUint32,s.readUint32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0):(r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0),t&&(this.offset+=4),r},s.readUInt32=s.readUint32,f&&(s.writeInt64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e)),t+=8;var n=this.buffer.byteLength;nt?n:t),t-=8;var i=e.low,o=e.high;return this.littleEndian?(this.view[t+3]=i>>>24&255,this.view[t+2]=i>>>16&255,this.view[t+1]=i>>>8&255,this.view[t]=255&i,t+=4,this.view[t+3]=o>>>24&255,this.view[t+2]=o>>>16&255,this.view[t+1]=o>>>8&255,this.view[t]=255&o):(this.view[t]=o>>>24&255,this.view[t+1]=o>>>16&255,this.view[t+2]=o>>>8&255,this.view[t+3]=255&o,t+=4,this.view[t]=i>>>24&255,this.view[t+1]=i>>>16&255,this.view[t+2]=i>>>8&255,this.view[t+3]=255&i),r&&(this.offset+=8),this},s.writeLong=s.writeInt64,s.readInt64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=0,n=0;this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0,e+=4,n=this.view[e+2]<<16,n|=this.view[e+1]<<8,n|=this.view[e],n+=this.view[e+3]<<24>>>0):(n=this.view[e+1]<<16,n|=this.view[e+2]<<8,n|=this.view[e+3],n+=this.view[e]<<24>>>0,e+=4,r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0);var i=new f(r,n,!1);return t&&(this.offset+=8),i},s.readLong=s.readInt64,s.writeUint64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e)),t+=8;var n=this.buffer.byteLength;nt?n:t),t-=8;var i=e.low,o=e.high;return this.littleEndian?(this.view[t+3]=i>>>24&255,this.view[t+2]=i>>>16&255,this.view[t+1]=i>>>8&255,this.view[t]=255&i,t+=4,this.view[t+3]=o>>>24&255,this.view[t+2]=o>>>16&255,this.view[t+1]=o>>>8&255,this.view[t]=255&o):(this.view[t]=o>>>24&255,this.view[t+1]=o>>>16&255,this.view[t+2]=o>>>8&255,this.view[t+3]=255&o,t+=4,this.view[t]=i>>>24&255,this.view[t+1]=i>>>16&255,this.view[t+2]=i>>>8&255,this.view[t+3]=255&i),r&&(this.offset+=8),this},s.writeUInt64=s.writeUint64,s.readUint64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=0,n=0;this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0,e+=4,n=this.view[e+2]<<16,n|=this.view[e+1]<<8,n|=this.view[e],n+=this.view[e+3]<<24>>>0):(n=this.view[e+1]<<16,n|=this.view[e+2]<<8,n|=this.view[e+3],n+=this.view[e]<<24>>>0,e+=4,r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0);var i=new f(r,n,!0);return t&&(this.offset+=8),i},s.readUInt64=s.readUint64),s.writeFloat32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var n=this.buffer.byteLength;return nt?n:t),t-=4,i(this.view,e,t,this.littleEndian,23,4),r&&(this.offset+=4),this},s.writeFloat=s.writeFloat32,s.readFloat32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=n(this.view,e,this.littleEndian,23,4);return t&&(this.offset+=4),r},s.readFloat=s.readFloat32,s.writeFloat64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=8;var n=this.buffer.byteLength;return nt?n:t),t-=8,i(this.view,e,t,this.littleEndian,52,8),r&&(this.offset+=8),this},s.writeDouble=s.writeFloat64,s.readFloat64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=n(this.view,e,this.littleEndian,52,8);return t&&(this.offset+=8),r},s.readDouble=s.readFloat64,d.MAX_VARINT32_BYTES=5,d.calculateVarint32=function(e){return(e>>>=0)<128?1:e<16384?2:e<1<<21?3:e<1<<28?4:5},d.zigZagEncode32=function(e){return((e|=0)<<1^e>>31)>>>0},d.zigZagDecode32=function(e){return e>>>1^-(1&e)|0},s.writeVarint32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i=d.calculateVarint32(e);t+=i;var o=this.buffer.byteLength;for(ot?o:t),t-=i,e>>>=0;128<=e;)n=127&e|128,this.view[t++]=n,e>>>=7;return this.view[t++]=e,r?(this.offset=t,this):i},s.writeVarint32ZigZag=function(e,t){return this.writeVarint32(d.zigZagEncode32(e),t)},s.readVarint32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,n=0,i=0;do{if(!this.noAssert&&e>this.limit){var o=Error("Truncated");throw o.truncated=!0,o}r=this.view[e++],n<5&&(i|=(127&r)<<7*n),++n}while(0!=(128&r));return i|=0,t?(this.offset=e,i):{value:i,length:n}},s.readVarint32ZigZag=function(e){var t=this.readVarint32(e);return"object"==typeof t?t.value=d.zigZagDecode32(t.value):t=d.zigZagDecode32(t),t},f&&(d.MAX_VARINT64_BYTES=10,d.calculateVarint64=function(e){"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e));var t=e.toInt()>>>0,r=e.shiftRightUnsigned(28).toInt()>>>0,n=e.shiftRightUnsigned(56).toInt()>>>0;return 0==n?0==r?t<16384?t<128?1:2:t<1<<21?3:4:r<16384?r<128?5:6:r<1<<21?7:8:n<128?9:10},d.zigZagEncode64=function(e){return"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftLeft(1).xor(e.shiftRight(63)).toUnsigned()},d.zigZagDecode64=function(e){return"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftRightUnsigned(1).xor(e.and(f.ONE).toSigned().negate()).toSigned()},s.writeVarint64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned());var n=d.calculateVarint64(e),i=e.toInt()>>>0,o=e.shiftRightUnsigned(28).toInt()>>>0,s=e.shiftRightUnsigned(56).toInt()>>>0;t+=n;var a=this.buffer.byteLength;switch(at?a:t),t-=n,n){case 10:this.view[t+9]=s>>>7&1;case 9:this.view[t+8]=9!==n?128|s:127&s;case 8:this.view[t+7]=8!==n?o>>>21|128:o>>>21&127;case 7:this.view[t+6]=7!==n?o>>>14|128:o>>>14&127;case 6:this.view[t+5]=6!==n?o>>>7|128:o>>>7&127;case 5:this.view[t+4]=5!==n?128|o:127&o;case 4:this.view[t+3]=4!==n?i>>>21|128:i>>>21&127;case 3:this.view[t+2]=3!==n?i>>>14|128:i>>>14&127;case 2:this.view[t+1]=2!==n?i>>>7|128:i>>>7&127;case 1:this.view[t]=1!==n?128|i:127&i}return r?(this.offset+=n,this):n},s.writeVarint64ZigZag=function(e,t){return this.writeVarint64(d.zigZagEncode64(e),t)},s.readVarint64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=e,n=0,i=0,o=0,s=0;if(n=127&(s=this.view[e++]),128&s&&(n|=(127&(s=this.view[e++]))<<7,(128&s||this.noAssert&&void 0===s)&&(n|=(127&(s=this.view[e++]))<<14,(128&s||this.noAssert&&void 0===s)&&(n|=(127&(s=this.view[e++]))<<21,(128&s||this.noAssert&&void 0===s)&&(i=127&(s=this.view[e++]),(128&s||this.noAssert&&void 0===s)&&(i|=(127&(s=this.view[e++]))<<7,(128&s||this.noAssert&&void 0===s)&&(i|=(127&(s=this.view[e++]))<<14,(128&s||this.noAssert&&void 0===s)&&(i|=(127&(s=this.view[e++]))<<21,(128&s||this.noAssert&&void 0===s)&&(o=127&(s=this.view[e++]),(128&s||this.noAssert&&void 0===s)&&(o|=(127&(s=this.view[e++]))<<7,128&s||this.noAssert&&void 0===s))))))))))throw Error("Buffer overrun");var a=f.fromBits(n|i<<28,i>>>4|o<<24,!1);return t?(this.offset=e,a):{value:a,length:e-r}},s.readVarint64ZigZag=function(e){var t=this.readVarint64(e);return t&&t.value instanceof f?t.value=d.zigZagDecode64(t.value):t=d.zigZagDecode64(t),t}),s.writeCString=function(e,t){var r=void 0===t;r&&(t=this.offset);var n,i=e.length;if(!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");for(n=0;n>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}i=l.calculateUTF16asUTF8(a(e))[1],t+=i+1;var o=this.buffer.byteLength;return ot?o:t),t-=i+1,l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),this.view[t++]=0,r?(this.offset=t,this):i},s.readCString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,n=e,i=-1;return l.decodeUTF8toUTF16(function(){if(0===i)return null;if(e>=this.limit)throw RangeError("Illegal range: Truncated data, "+e+" < "+this.limit);return 0===(i=this.view[e++])?null:i}.bind(this),r=u(),!0),t?(this.offset=e,r()):{string:r(),length:e-n}},s.writeIString=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i=t;n=l.calculateUTF16asUTF8(a(e),this.noAssert)[1],t+=4+n;var o=this.buffer.byteLength;if(ot?o:t),t-=4+n,this.littleEndian?(this.view[t+3]=n>>>24&255,this.view[t+2]=n>>>16&255,this.view[t+1]=n>>>8&255,this.view[t]=255&n):(this.view[t]=n>>>24&255,this.view[t+1]=n>>>16&255,this.view[t+2]=n>>>8&255,this.view[t+3]=255&n),t+=4,l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),t!==i+4+n)throw RangeError("Illegal range: Truncated data, "+t+" == "+(t+4+n));return r?(this.offset=t,this):t-i},s.readIString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=e,n=this.readUint32(e),i=this.readUTF8String(n,d.METRICS_BYTES,e+=4);return e+=i.length,t?(this.offset=e,i.string):{string:i.string,length:e-r}},d.METRICS_CHARS="c",d.METRICS_BYTES="b",s.writeUTF8String=function(e,t){var r,n=void 0===t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var i=t;r=l.calculateUTF16asUTF8(a(e))[1],t+=r;var o=this.buffer.byteLength;return ot?o:t),t-=r,l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),n?(this.offset=t,this):t-i},s.writeString=s.writeUTF8String,d.calculateUTF8Chars=function(e){return l.calculateUTF16asUTF8(a(e))[0]},d.calculateUTF8Bytes=function(e){return l.calculateUTF16asUTF8(a(e))[1]},d.calculateString=d.calculateUTF8Bytes,s.readUTF8String=function(e,t,r){"number"==typeof t&&(r=t,t=void 0);var n=void 0===r;if(n&&(r=this.offset),void 0===t&&(t=d.METRICS_CHARS),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal length: "+e+" (not an integer)");if(e|=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}var i,o=0,s=r;if(t===d.METRICS_CHARS){if(i=u(),l.decodeUTF8(function(){return o>>=0)<0||r+e>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+"+e+") <= "+this.buffer.byteLength)}var a=r+e;if(l.decodeUTF8toUTF16(function(){return r>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i,o=t;n=l.calculateUTF16asUTF8(a(e),this.noAssert)[1],i=d.calculateVarint32(n),t+=i+n;var s=this.buffer.byteLength;if(st?s:t),t-=i+n,t+=this.writeVarint32(n,t),l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),t!==o+n+i)throw RangeError("Illegal range: Truncated data, "+t+" == "+(t+n+i));return r?(this.offset=t,this):t-o},s.readVString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=e,n=this.readVarint32(e),i=this.readUTF8String(n.value,d.METRICS_BYTES,e+=n.length);return e+=i.length,t?(this.offset=e,i.string):{string:i.string,length:e-r}},s.append=function(e,t,r){"number"!=typeof t&&"string"==typeof t||(r=t,t=void 0);var n=void 0===r;if(n&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}e instanceof d||(e=d.wrap(e,t));var i=e.limit-e.offset;if(i<=0)return this;r+=i;var o=this.buffer.byteLength;return or?o:r),r-=i,this.view.set(e.view.subarray(e.offset,e.limit),r),e.offset+=i,n&&(this.offset+=i),this},s.appendTo=function(e,t){return e.append(this,t),this},s.assert=function(e){return this.noAssert=!e,this},s.capacity=function(){return this.buffer.byteLength},s.clear=function(){return this.offset=0,this.limit=this.buffer.byteLength,this.markedOffset=-1,this},s.clone=function(e){var t=new d(0,this.littleEndian,this.noAssert);return t.view=e?(t.buffer=new ArrayBuffer(this.buffer.byteLength),new Uint8Array(t.buffer)):(t.buffer=this.buffer,this.view),t.offset=this.offset,t.markedOffset=this.markedOffset,t.limit=this.limit,t},s.compact=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(0===e&&t===this.buffer.byteLength)return this;var r=t-e;if(0===r)return this.buffer=o,this.view=null,0<=this.markedOffset&&(this.markedOffset-=e),this.offset=0,this.limit=0,this;var n=new ArrayBuffer(r),i=new Uint8Array(n);return i.set(this.view.subarray(e,t)),this.buffer=n,this.view=i,0<=this.markedOffset&&(this.markedOffset-=e),this.offset=0,this.limit=r,this},s.copy=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(e===t)return new d(0,this.littleEndian,this.noAssert);var r=t-e,n=new d(r,this.littleEndian,this.noAssert);return n.offset=0,n.limit=r,0<=n.markedOffset&&(n.markedOffset-=e),this.copyTo(n,0,e,t),n},s.copyTo=function(e,t,r,n){var i,o;if(!this.noAssert&&!d.isByteBuffer(e))throw TypeError("Illegal target: Not a ByteBuffer");if(t=(o=void 0===t)?e.offset:0|t,r=(i=void 0===r)?this.offset:0|r,n=void 0===n?this.limit:0|n,t<0||t>e.buffer.byteLength)throw RangeError("Illegal target range: 0 <= "+t+" <= "+e.buffer.byteLength);if(r<0||n>this.buffer.byteLength)throw RangeError("Illegal source range: 0 <= "+r+" <= "+this.buffer.byteLength);var s=n-r;return 0===s?e:(e.ensureCapacity(t+s),e.view.set(this.view.subarray(r,n),t),i&&(this.offset+=s),o&&(e.offset+=s),this)},s.ensureCapacity=function(e){var t=this.buffer.byteLength;return te?t:e):this},s.fill=function(e,t,r){var n=void 0===t;if(n&&(t=this.offset),"string"==typeof e&&0>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal end: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}if(r<=t)return this;for(;t>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}return this.markedOffset=e,this},s.order=function(e){if(!this.noAssert&&"boolean"!=typeof e)throw TypeError("Illegal littleEndian: Not a boolean");return this.littleEndian=!!e,this},s.LE=function(e){return this.littleEndian=void 0===e||!!e,this},s.BE=function(e){return this.littleEndian=void 0!==e&&!e,this},s.prepend=function(e,t,r){"number"!=typeof t&&"string"==typeof t||(r=t,t=void 0);var n=void 0===r;if(n&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}e instanceof d||(e=d.wrap(e,t));var i=e.limit-e.offset;if(i<=0)return this;var o=i-r;if(0>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}return e===t||Array.prototype.reverse.call(this.view.subarray(e,t)),this},s.skip=function(e){if(!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal length: "+e+" (not an integer)");e|=0}var t=this.offset+e;if(!this.noAssert&&(t<0||t>this.buffer.byteLength))throw RangeError("Illegal length: 0 <= "+this.offset+" + "+e+" <= "+this.buffer.byteLength);return this.offset=t,this},s.slice=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}var r=this.clone();return r.offset=e,r.limit=t,r},s.toBuffer=function(e){var t=this.offset,r=this.limit;if(!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: Not an integer");if(t>>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal limit: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}if(!e&&0===t&&r===this.buffer.byteLength)return this.buffer;if(t===r)return o;var n=new ArrayBuffer(r-t);return new Uint8Array(n).set(new Uint8Array(this.buffer).subarray(t,r),0),n},s.toArrayBuffer=s.toBuffer,s.toString=function(e,t,r){if(void 0===e)return"ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";switch("number"==typeof e&&(r=t=e="utf8"),e){case"utf8":return this.toUTF8(t,r);case"base64":return this.toBase64(t,r);case"hex":return this.toHex(t,r);case"binary":return this.toBinary(t,r);case"debug":return this.toDebug();case"columns":return this.toColumns();default:throw Error("Unsupported encoding: "+e)}};var c=function(){for(var e={},i=[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47],s=[],t=0,r=i.length;t>2&63]),n=(3&r)<<4,null!==(r=e())?(t(i[63&((n|=r>>4&15)|r>>4&15)]),n=(15&r)<<2,null!==(r=e())?(t(i[63&(n|r>>6&3)]),t(i[63&r])):(t(i[63&n]),t(61))):(t(i[63&n]),t(61),t(61))},e.decode=function(e,t){var r,n,i;function o(e){throw Error("Illegal character code: "+e)}for(;null!==(r=e());)if(void 0===(n=s[r])&&o(r),null!==(r=e())&&(void 0===(i=s[r])&&o(r),t(n<<2>>>0|(48&i)>>4),null!==(r=e()))){if(void 0===(n=s[r])){if(61===r)break;o(r)}if(t((15&i)<<4>>>0|(60&n)>>2),null!==(r=e())){if(void 0===(i=s[r])){if(61===r)break;o(r)}t((3&n)<<6>>>0|i)}}},e.test=function(e){return/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e)},e}();s.toBase64=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),t|=0,(e|=0)<0||t>this.capacity||tthis.capacity()||t":i+=r===this.markedOffset?"'":e||0!==r&&r!==n?" ":""}if(e&&" "!==i){for(;i.length<51;)i+=" ";s+=i+o+"\n"}return e?s:i},d.fromDebug=function(e,t,r){for(var n,i,o=e.length,s=new d((o+1)/3|0,t,r),a=0,f=0,u=!1,c=!1,h=!1,l=!1,p=!1;a":if(!r){if(l){p=!0;break}l=!0}s.limit=f,u=!1;break;case"'":if(!r){if(h){p=!0;break}h=!0}s.markedOffset=f,u=!1;break;case" ":u=!1;break;default:if(!r&&u){p=!0;break}if(i=parseInt(n+e.charAt(a++),16),!r&&(isNaN(i)||i<0||255>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}for(var r,n=new Array(t-e);e>6&31|192):(r<65536?t(r>>12&15|224):(t(r>>18&7|240),t(r>>12&63|128)),t(r>>6&63|128)),t(63&r|128)),r=null},decodeUTF8:function(e,t){for(var r,n,i,o,s=function(e){e=e.slice(0,e.indexOf(null));var t=Error(e.toString());throw t.name="TruncatedError",t.bytes=e,t};null!==(r=e());)if(0==(128&r))t(r);else if(192==(224&r))null===(n=e())&&s([r,n]),t((31&r)<<6|63&n);else if(224==(240&r))(null===(n=e())||null===(i=e()))&&s([r,n,i]),t((15&r)<<12|(63&n)<<6|63&i);else{if(240!=(248&r))throw RangeError("Illegal starting byte: "+r);(null===(n=e())||null===(i=e())||null===(o=e()))&&s([r,n,i,o]),t((7&r)<<18|(63&n)<<12|(63&i)<<6|63&o)}},UTF16toUTF8:function(e,t){for(var r,n=null;null!==(r=null!==n?n:e());)55296<=r&&r<=57343&&null!==(n=e())&&56320<=n&&n<=57343?(t(1024*(r-55296)+n-56320+65536),n=null):t(r);null!==n&&t(n)},UTF8toUTF16:function(e,t){var r=null;for("number"==typeof e&&(r=e,e=function(){return null});null!==r||null!==(r=e());)r<=65535?t(r):(t(55296+((r-=65536)>>10)),t(r%1024+56320)),r=null},encodeUTF16toUTF8:function(e,t){h.UTF16toUTF8(e,function(e){h.encodeUTF8(e,t)})},decodeUTF8toUTF16:function(e,t){h.decodeUTF8(e,function(e){h.UTF8toUTF16(e,t)})},calculateCodePoint:function(e){return e<128?1:e<2048?2:e<65536?3:4},calculateUTF8:function(e){for(var t,r=0;null!==(t=e());)r+=t<128?1:t<2048?2:t<65536?3:4;return r},calculateUTF16asUTF8:function(e){var t=0,r=0;return h.UTF16toUTF8(e,function(e){++t,r+=e<128?1:e<2048?2:e<65536?3:4}),[t,r]}};return s.toUTF8=function(t,r){if(void 0===t&&(t=this.offset),void 0===r&&(r=this.limit),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal begin: Not an integer");if(t>>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal end: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}var e;try{l.decodeUTF8toUTF16(function(){return tr)?t=("rmd160"===e?new f:u(e)).update(t).digest():t.length>>8^255&i^99,u[r]=i;var o=e[c[i]=r],s=e[o],a=e[s],f=257*e[i]^16843008*i;h[r]=f<<24|f>>>8,l[r]=f<<16|f>>>16,p[r]=f<<8|f>>>24,d[r]=f;f=16843009*a^65537*s^257*o^16843008*r;_[i]=f<<24|f>>>8,g[i]=f<<16|f>>>16,m[i]=f<<8|f>>>24,v[i]=f,r?(r=o^e[e[e[a^o]]],n^=e[e[n]]):r=n=1}}();var y=[0,1,2,4,8,16,32,64,128,27,54],n=r.AES=t.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var e=this._keyPriorReset=this._key,t=e.words,r=e.sigBytes/4,n=4*((this._nRounds=r+6)+1),i=this._keySchedule=[],o=0;o>>24]<<24|u[s>>>16&255]<<16|u[s>>>8&255]<<8|u[255&s]):(s=u[(s=s<<8|s>>>24)>>>24]<<24|u[s>>>16&255]<<16|u[s>>>8&255]<<8|u[255&s],s^=y[o/r|0]<<24),i[o]=i[o-r]^s}for(var a=this._invKeySchedule=[],f=0;f>>24]]^g[u[s>>>16&255]]^m[u[s>>>8&255]]^v[u[255&s]]}}},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,h,l,p,d,u)},decryptBlock:function(e,t){var r=e[t+1];e[t+1]=e[t+3],e[t+3]=r,this._doCryptBlock(e,t,this._invKeySchedule,_,g,m,v,c);r=e[t+1];e[t+1]=e[t+3],e[t+3]=r},_doCryptBlock:function(e,t,r,n,i,o,s,a){for(var f=this._nRounds,u=e[t]^r[0],c=e[t+1]^r[1],h=e[t+2]^r[2],l=e[t+3]^r[3],p=4,d=1;d>>24]^i[c>>>16&255]^o[h>>>8&255]^s[255&l]^r[p++],g=n[c>>>24]^i[h>>>16&255]^o[l>>>8&255]^s[255&u]^r[p++],m=n[h>>>24]^i[l>>>16&255]^o[u>>>8&255]^s[255&c]^r[p++],v=n[l>>>24]^i[u>>>16&255]^o[c>>>8&255]^s[255&h]^r[p++];u=_,c=g,h=m,l=v}_=(a[u>>>24]<<24|a[c>>>16&255]<<16|a[h>>>8&255]<<8|a[255&l])^r[p++],g=(a[c>>>24]<<24|a[h>>>16&255]<<16|a[l>>>8&255]<<8|a[255&u])^r[p++],m=(a[h>>>24]<<24|a[l>>>16&255]<<16|a[u>>>8&255]<<8|a[255&c])^r[p++],v=(a[l>>>24]<<24|a[u>>>16&255]<<16|a[c>>>8&255]<<8|a[255&h])^r[p++];e[t]=_,e[t+1]=g,e[t+2]=m,e[t+3]=v},keySize:8});e.AES=t._createHelper(n)}(),i.AES},"object"==typeof r?t.exports=r=i(e(47),e(48),e(52),e(50),e(46)):i(n.CryptoJS)},{46:46,47:47,48:48,50:50,52:52}],46:[function(e,t,r){var n,i;n=this,i=function(e){var t,r,n,f,i,o,s,a,u,c,h,l,p,d,_,g,m,v;e.lib.Cipher||(r=(t=e).lib,n=r.Base,f=r.WordArray,i=r.BufferedBlockAlgorithm,(o=t.enc).Utf8,s=o.Base64,a=t.algo.EvpKDF,u=r.Cipher=i.extend({cfg:n.extend(),createEncryptor:function(e,t){return this.create(this._ENC_XFORM_MODE,e,t)},createDecryptor:function(e,t){return this.create(this._DEC_XFORM_MODE,e,t)},init:function(e,t,r){this.cfg=this.cfg.extend(r),this._xformMode=e,this._key=t,this.reset()},reset:function(){i.reset.call(this),this._doReset()},process:function(e){return this._append(e),this._process()},finalize:function(e){return e&&this._append(e),this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(){function i(e){return"string"==typeof e?v:g}return function(n){return{encrypt:function(e,t,r){return i(t).encrypt(n,e,t,r)},decrypt:function(e,t,r){return i(t).decrypt(n,e,t,r)}}}}()}),r.StreamCipher=u.extend({_doFinalize:function(){return this._process(!0)},blockSize:1}),c=t.mode={},h=r.BlockCipherMode=n.extend({createEncryptor:function(e,t){return this.Encryptor.create(e,t)},createDecryptor:function(e,t){return this.Decryptor.create(e,t)},init:function(e,t){this._cipher=e,this._iv=t}}),l=c.CBC=function(){var e=h.extend();function o(e,t,r){var n=this._iv;if(n){var i=n;this._iv=void 0}else i=this._prevBlock;for(var o=0;o>>2];e.sigBytes-=t}},r.BlockCipher=u.extend({cfg:u.cfg.extend({mode:l,padding:p}),reset:function(){u.reset.call(this);var e=this.cfg,t=e.iv,r=e.mode;if(this._xformMode==this._ENC_XFORM_MODE)var n=r.createEncryptor;else{n=r.createDecryptor;this._minBufferSize=1}this._mode&&this._mode.__creator==n?this._mode.init(this,t&&t.words):(this._mode=n.call(r,this,t&&t.words),this._mode.__creator=n)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else{t=this._process(!0);e.unpad(t)}return t},blockSize:4}),d=r.CipherParams=n.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),_=(t.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext,r=e.salt;if(r)var n=f.create([1398893684,1701076831]).concat(r).concat(t);else n=t;return n.toString(s)},parse:function(e){var t=s.parse(e),r=t.words;if(1398893684==r[0]&&1701076831==r[1]){var n=f.create(r.slice(2,4));r.splice(0,4),t.sigBytes-=16}return d.create({ciphertext:t,salt:n})}},g=r.SerializableCipher=n.extend({cfg:n.extend({format:_}),encrypt:function(e,t,r,n){n=this.cfg.extend(n);var i=e.createEncryptor(r,n),o=i.finalize(t),s=i.cfg;return d.create({ciphertext:o,key:r,iv:s.iv,algorithm:e,mode:s.mode,padding:s.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,r,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(r,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}}),m=(t.kdf={}).OpenSSL={execute:function(e,t,r,n){n||(n=f.random(8));var i=a.create({keySize:t+r}).compute(e,n),o=f.create(i.words.slice(t),4*r);return i.sigBytes=4*t,d.create({key:i,iv:o,salt:n})}},v=r.PasswordBasedCipher=g.extend({cfg:g.cfg.extend({kdf:m}),encrypt:function(e,t,r,n){var i=(n=this.cfg.extend(n)).kdf.execute(r,e.keySize,e.ivSize);n.iv=i.iv;var o=g.encrypt.call(this,e,t,i.key,n);return o.mixIn(i),o},decrypt:function(e,t,r,n){n=this.cfg.extend(n),t=this._parse(t,n.format);var i=n.kdf.execute(r,e.keySize,e.ivSize,t.salt);return n.iv=i.iv,g.decrypt.call(this,e,t,i.key,n)}}))},"object"==typeof r?t.exports=r=i(e(47),e(50)):i(n.CryptoJS)},{47:47,50:50}],47:[function(e,t,r){var n,i;n=this,i=function(){var c,r,e,t,n,h,i,o,s,a,f,u,l=l||(c=Math,r=Object.create||function(){function r(){}return function(e){var t;return r.prototype=e,t=new r,r.prototype=null,t}}(),t=(e={}).lib={},n=t.Base={extend:function(e){var t=r(this);return e&&t.mixIn(e),t.hasOwnProperty("init")&&this.init!==t.init||(t.init=function(){t.$super.init.apply(this,arguments)}),(t.init.prototype=t).$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},h=t.WordArray=n.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,r=e.words,n=this.sigBytes,i=e.sigBytes;if(this.clamp(),n%4)for(var o=0;o>>2]>>>24-o%4*8&255;t[n+o>>>2]|=s<<24-(n+o)%4*8}else for(o=0;o>>2]=r[o>>>2];return this.sigBytes+=i,this},clamp:function(){var e=this.words,t=this.sigBytes;e[t>>>2]&=4294967295<<32-t%4*8,e.length=c.ceil(t/4)},clone:function(){var e=n.clone.call(this);return e.words=this.words.slice(0),e},random:function(e){for(var t,r=[],n=function(t){t=t;var r=987654321,n=4294967295;return function(){var e=((r=36969*(65535&r)+(r>>16)&n)<<16)+(t=18e3*(65535&t)+(t>>16)&n)&n;return e/=4294967296,(e+=.5)*(.5>>2]>>>24-i%4*8&255;n.push((o>>>4).toString(16)),n.push((15&o).toString(16))}return n.join("")},parse:function(e){for(var t=e.length,r=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new h.init(r,t/2)}},s=i.Latin1={stringify:function(e){for(var t=e.words,r=e.sigBytes,n=[],i=0;i>>2]>>>24-i%4*8&255;n.push(String.fromCharCode(o))}return n.join("")},parse:function(e){for(var t=e.length,r=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new h.init(r,t)}},a=i.Utf8={stringify:function(e){try{return decodeURIComponent(escape(s.stringify(e)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(e){return s.parse(unescape(encodeURIComponent(e)))}},f=t.BufferedBlockAlgorithm=n.extend({reset:function(){this._data=new h.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=a.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(e){var t=this._data,r=t.words,n=t.sigBytes,i=this.blockSize,o=n/(4*i),s=(o=e?c.ceil(o):c.max((0|o)-this._minBufferSize,0))*i,a=c.min(4*s,n);if(s){for(var f=0;f>>2]>>>24-o%4*8&255)<<16|(t[o+1>>>2]>>>24-(o+1)%4*8&255)<<8|t[o+2>>>2]>>>24-(o+2)%4*8&255,a=0;a<4&&o+.75*a>>6*(3-a)&63));var f=n.charAt(64);if(f)for(;i.length%4;)i.push(f);return i.join("")},parse:function(e){var t=e.length,r=this._map,n=this._reverseMap;if(!n){n=this._reverseMap=[];for(var i=0;i>>6-o%4*2;n[i>>>2]|=(s|a)<<24-i%4*8,i++}return f.create(n,i)}(e,t,n)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},e.enc.Base64},"object"==typeof r?t.exports=r=i(e(47)):i(n.CryptoJS)},{47:47}],49:[function(e,t,r){var n,i;n=this,i=function(e){return e.enc.Hex},"object"==typeof r?t.exports=r=i(e(47)):i(n.CryptoJS)},{47:47}],50:[function(e,t,r){var n,i;n=this,i=function(e){var t,r,n,c,i,o,s;return r=(t=e).lib,n=r.Base,c=r.WordArray,i=t.algo,o=i.MD5,s=i.EvpKDF=n.extend({cfg:n.extend({keySize:4,hasher:o,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var r=this.cfg,n=r.hasher.create(),i=c.create(),o=i.words,s=r.keySize,a=r.iterations;o.lengthn&&(t=e.finalize(t)),t.clamp();for(var i=this._oKey=t.clone(),o=this._iKey=t.clone(),s=i.words,a=o.words,f=0;f>>24)|4278255360&(i<<24|i>>>8)}var o=this._hash.words,s=e[t+0],a=e[t+1],f=e[t+2],u=e[t+3],c=e[t+4],h=e[t+5],l=e[t+6],p=e[t+7],d=e[t+8],_=e[t+9],g=e[t+10],m=e[t+11],v=e[t+12],y=e[t+13],b=e[t+14],w=e[t+15],E=o[0],B=o[1],k=o[2],T=o[3];B=O(B=O(B=O(B=O(B=A(B=A(B=A(B=A(B=I(B=I(B=I(B=I(B=x(B=x(B=x(B=x(B,k=x(k,T=x(T,E=x(E,B,k,T,s,7,S[0]),B,k,a,12,S[1]),E,B,f,17,S[2]),T,E,u,22,S[3]),k=x(k,T=x(T,E=x(E,B,k,T,c,7,S[4]),B,k,h,12,S[5]),E,B,l,17,S[6]),T,E,p,22,S[7]),k=x(k,T=x(T,E=x(E,B,k,T,d,7,S[8]),B,k,_,12,S[9]),E,B,g,17,S[10]),T,E,m,22,S[11]),k=x(k,T=x(T,E=x(E,B,k,T,v,7,S[12]),B,k,y,12,S[13]),E,B,b,17,S[14]),T,E,w,22,S[15]),k=I(k,T=I(T,E=I(E,B,k,T,a,5,S[16]),B,k,l,9,S[17]),E,B,m,14,S[18]),T,E,s,20,S[19]),k=I(k,T=I(T,E=I(E,B,k,T,h,5,S[20]),B,k,g,9,S[21]),E,B,w,14,S[22]),T,E,c,20,S[23]),k=I(k,T=I(T,E=I(E,B,k,T,_,5,S[24]),B,k,b,9,S[25]),E,B,u,14,S[26]),T,E,d,20,S[27]),k=I(k,T=I(T,E=I(E,B,k,T,y,5,S[28]),B,k,f,9,S[29]),E,B,p,14,S[30]),T,E,v,20,S[31]),k=A(k,T=A(T,E=A(E,B,k,T,h,4,S[32]),B,k,d,11,S[33]),E,B,m,16,S[34]),T,E,b,23,S[35]),k=A(k,T=A(T,E=A(E,B,k,T,a,4,S[36]),B,k,c,11,S[37]),E,B,p,16,S[38]),T,E,g,23,S[39]),k=A(k,T=A(T,E=A(E,B,k,T,y,4,S[40]),B,k,s,11,S[41]),E,B,u,16,S[42]),T,E,l,23,S[43]),k=A(k,T=A(T,E=A(E,B,k,T,_,4,S[44]),B,k,v,11,S[45]),E,B,w,16,S[46]),T,E,f,23,S[47]),k=O(k,T=O(T,E=O(E,B,k,T,s,6,S[48]),B,k,p,10,S[49]),E,B,b,15,S[50]),T,E,h,21,S[51]),k=O(k,T=O(T,E=O(E,B,k,T,v,6,S[52]),B,k,u,10,S[53]),E,B,g,15,S[54]),T,E,a,21,S[55]),k=O(k,T=O(T,E=O(E,B,k,T,d,6,S[56]),B,k,w,10,S[57]),E,B,l,15,S[58]),T,E,y,21,S[59]),k=O(k,T=O(T,E=O(E,B,k,T,c,6,S[60]),B,k,m,10,S[61]),E,B,f,15,S[62]),T,E,_,21,S[63]),o[0]=o[0]+E|0,o[1]=o[1]+B|0,o[2]=o[2]+k|0,o[3]=o[3]+T|0},_doFinalize:function(){var e=this._data,t=e.words,r=8*this._nDataBytes,n=8*e.sigBytes;t[n>>>5]|=128<<24-n%32;var i=c.floor(r/4294967296),o=r;t[15+(n+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),t[14+(n+64>>>9<<4)]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),e.sigBytes=4*(t.length+1),this._process();for(var s=this._hash,a=s.words,f=0;f<4;f++){var u=a[f];a[f]=16711935&(u<<8|u>>>24)|4278255360&(u<<24|u>>>8)}return s},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});function x(e,t,r,n,i,o,s){var a=e+(t&r|~t&n)+i+s;return(a<>>32-o)+t}function I(e,t,r,n,i,o,s){var a=e+(t&n|r&~n)+i+s;return(a<>>32-o)+t}function A(e,t,r,n,i,o,s){var a=e+(t^r^n)+i+s;return(a<>>32-o)+t}function O(e,t,r,n,i,o,s){var a=e+(r^(t|~n))+i+s;return(a<>>32-o)+t}e.MD5=n._createHelper(o),e.HmacMD5=n._createHmacHelper(o)}(Math),s.MD5},"object"==typeof r?t.exports=r=i(e(47)):i(n.CryptoJS)},{47:47}],53:[function(e,t,r){var n,i;n=this,i=function(e){var t,r,n,i,o,h,s;return r=(t=e).lib,n=r.WordArray,i=r.Hasher,o=t.algo,h=[],s=o.SHA1=i.extend({_doReset:function(){this._hash=new n.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(e,t){for(var r=this._hash.words,n=r[0],i=r[1],o=r[2],s=r[3],a=r[4],f=0;f<80;f++){if(f<16)h[f]=0|e[t+f];else{var u=h[f-3]^h[f-8]^h[f-14]^h[f-16];h[f]=u<<1|u>>>31}var c=(n<<5|n>>>27)+a+h[f];c+=f<20?1518500249+(i&o|~i&s):f<40?1859775393+(i^o^s):f<60?(i&o|i&s|o&s)-1894007588:(i^o^s)-899497514,a=s,s=o,o=i<<30|i>>>2,i=n,n=c}r[0]=r[0]+n|0,r[1]=r[1]+i|0,r[2]=r[2]+o|0,r[3]=r[3]+s|0,r[4]=r[4]+a|0},_doFinalize:function(){var e=this._data,t=e.words,r=8*this._nDataBytes,n=8*e.sigBytes;return t[n>>>5]|=128<<24-n%32,t[14+(n+64>>>9<<4)]=Math.floor(r/4294967296),t[15+(n+64>>>9<<4)]=r,e.sigBytes=4*t.length,this._process(),this._hash},clone:function(){var e=i.clone.call(this);return e._hash=this._hash.clone(),e}}),t.SHA1=i._createHelper(s),t.HmacSHA1=i._createHmacHelper(s),e.SHA1},"object"==typeof r?t.exports=r=i(e(47)):i(n.CryptoJS)},{47:47}],54:[function(e,t,r){var a=Array.prototype.slice,f=e(56),u=e(55),c=t.exports=function(e,t,r){return r||(r={}),e===t||(e instanceof Date&&t instanceof Date?e.getTime()===t.getTime():!e||!t||"object"!=typeof e&&"object"!=typeof t?r.strict?e===t:e==t:function(e,t,r){var n,i;if(h(e)||h(t))return!1;if(e.prototype!==t.prototype)return!1;if(u(e))return!!u(t)&&(e=a.call(e),t=a.call(t),c(e,t,r));if(l(e)){if(!l(t))return!1;if(e.length!==t.length)return!1;for(n=0;nr&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},n.prototype.once=function(e,t){if(!f(t))throw TypeError("listener must be a function");var r=!1;function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}return n.listener=t,this.on(e,n),this},n.prototype.removeListener=function(e,t){var r,n,i,o;if(!f(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(i=(r=this._events[e]).length,n=-1,r===t||f(r.listener)&&r.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(u(r)){for(o=i;0=this._blockSize;){for(var i=this._blockOffset;i>1,c=-7,h=r?i-1:0,l=r?-1:1,p=e[t+h];for(h+=l,o=p&(1<<-c)-1,p>>=-c,c+=a;0>=-c,c+=n;0>1,l=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:o-1,d=n?1:-1,_=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,s=c):(s=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-s))<1&&(s--,f*=2),2<=(t+=1<=s+h?l/f:l*Math.pow(2,1-h))*f&&(s++,f/=2),c<=s+h?(a=0,s=c):1<=s+h?(a=(t*f-1)*Math.pow(2,i),s+=h):(a=t*Math.pow(2,h-1)*Math.pow(2,i),s=0));8<=i;e[r+p]=255&a,p+=d,a/=256,i-=8);for(s=s<>>=0)&&e<256)&&(n=s[e])?n:(r=_(e,(0|e)<0?-1:0,!0),i&&(s[e]=r),r):(i=-128<=(e|=0)&&e<128)&&(n=o[e])?n:(r=_(e,e<0?-1:0,!1),i&&(o[e]=r),r)}function d(e,t){if(isNaN(e)||!isFinite(e))return t?f:v;if(t){if(e<0)return f;if(i<=e)return w}else{if(e<=-a)return E;if(a<=e+1)return b}return e<0?d(-e,t).neg():_(e%r|0,e/r|0,t)}function _(e,t,r){return new n(e,t,r)}n.fromInt=e,n.fromNumber=d,n.fromBits=_;var c=Math.pow;function h(e,t,r){if(0===e.length)throw Error("empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return v;if(t="number"==typeof t?(r=t,!1):!!t,(r=r||10)<2||36>>0:this.low},t.toNumber=function(){return this.unsigned?(this.high>>>0)*r+(this.low>>>0):this.high*r+(this.low>>>0)},t.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((o=a).isZero())return f+s;for(;f.length<6;)f="0"+f;s=""+f+s}},t.getHighBits=function(){return this.high},t.getHighBitsUnsigned=function(){return this.high>>>0},t.getLowBits=function(){return this.low},t.getLowBitsUnsigned=function(){return this.low>>>0},t.getNumBitsAbs=function(){if(this.isNegative())return this.eq(E)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;0>>31!=1||e.high>>>31!=1)&&(this.high===e.high&&this.low===e.low)},t.eq=t.equals,t.notEquals=function(e){return!this.eq(e)},t.neq=t.notEquals,t.lessThan=function(e){return this.comp(e)<0},t.lt=t.lessThan,t.lessThanOrEqual=function(e){return this.comp(e)<=0},t.lte=t.lessThanOrEqual,t.greaterThan=function(e){return 0>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},t.comp=t.compare,t.negate=function(){return!this.unsigned&&this.eq(E)?E:this.not().add(u)},t.neg=t.negate,t.add=function(e){p(e)||(e=g(e));var t=this.high>>>16,r=65535&this.high,n=this.low>>>16,i=65535&this.low,o=e.high>>>16,s=65535&e.high,a=e.low>>>16,f=0,u=0,c=0,h=0;return c+=(h+=i+(65535&e.low))>>>16,u+=(c+=n+a)>>>16,f+=(u+=r+s)>>>16,f+=t+o,_((c&=65535)<<16|(h&=65535),(f&=65535)<<16|(u&=65535),this.unsigned)},t.subtract=function(e){return p(e)||(e=g(e)),this.add(e.neg())},t.sub=t.subtract,t.multiply=function(e){if(this.isZero())return v;if(p(e)||(e=g(e)),e.isZero())return v;if(this.eq(E))return e.isOdd()?E:v;if(e.eq(E))return this.isOdd()?E:v;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(m)&&e.lt(m))return d(this.toNumber()*e.toNumber(),this.unsigned);var t=this.high>>>16,r=65535&this.high,n=this.low>>>16,i=65535&this.low,o=e.high>>>16,s=65535&e.high,a=e.low>>>16,f=65535&e.low,u=0,c=0,h=0,l=0;return h+=(l+=i*f)>>>16,c+=(h+=n*f)>>>16,h&=65535,c+=(h+=i*a)>>>16,u+=(c+=r*f)>>>16,c&=65535,u+=(c+=n*a)>>>16,c&=65535,u+=(c+=i*s)>>>16,u+=t*f+r*a+n*s+i*o,_((h&=65535)<<16|(l&=65535),(u&=65535)<<16|(c&=65535),this.unsigned)},t.mul=t.multiply,t.divide=function(e){if(p(e)||(e=g(e)),e.isZero())throw Error("division by zero");if(this.isZero())return this.unsigned?f:v;var t,r,n;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return f;if(e.gt(this.shru(1)))return l;n=f}else{if(this.eq(E))return e.eq(u)||e.eq(y)?E:e.eq(E)?u:(t=this.shr(1).div(e).shl(1)).eq(v)?e.isNegative()?u:y:(r=this.sub(e.mul(t)),n=t.add(r.div(e)));else if(e.eq(E))return this.unsigned?f:v;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();n=v}for(r=this;r.gte(e);){t=Math.max(1,Math.floor(r.toNumber()/e.toNumber()));for(var i=Math.ceil(Math.log(t)/Math.LN2),o=i<=48?1:c(2,i-48),s=d(t),a=s.mul(e);a.isNegative()||a.gt(r);)a=(s=d(t-=o,this.unsigned)).mul(e);s.isZero()&&(s=u),n=n.add(s),r=r.sub(a)}return n},t.div=t.divide,t.modulo=function(e){return p(e)||(e=g(e)),this.sub(this.div(e).mul(e))},t.mod=t.modulo,t.not=function(){return _(~this.low,~this.high,this.unsigned)},t.and=function(e){return p(e)||(e=g(e)),_(this.low&e.low,this.high&e.high,this.unsigned)},t.or=function(e){return p(e)||(e=g(e)),_(this.low|e.low,this.high|e.high,this.unsigned)},t.xor=function(e){return p(e)||(e=g(e)),_(this.low^e.low,this.high^e.high,this.unsigned)},t.shiftLeft=function(e){return p(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?_(this.low<>>32-e,this.unsigned):_(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):_(this.high>>e-32,0<=this.high?0:-1,this.unsigned)},t.shr=t.shiftRight,t.shiftRightUnsigned=function(e){if(p(e)&&(e=e.toInt()),0===(e&=63))return this;var t=this.high;return e<32?_(this.low>>>e|t<<32-e,t>>>e,this.unsigned):_(32===e?t:t>>>e-32,0,this.unsigned)},t.shru=t.shiftRightUnsigned,t.toSigned=function(){return this.unsigned?_(this.low,this.high,!1):this},t.toUnsigned=function(){return this.unsigned?this:_(this.low,this.high,!0)},t.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},t.toBytesLE=function(){var e=this.high,t=this.low;return[255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255]},t.toBytesBE=function(){var e=this.high,t=this.low;return[e>>>24&255,e>>>16&255,e>>>8&255,255&e,t>>>24&255,t>>>16&255,t>>>8&255,255&t]},n},"function"==typeof e&&"object"==typeof t&&t&&t.exports?t.exports=i():(n.dcodeIO=n.dcodeIO||{}).Long=i()},{}],69:[function(i,o,e){(function(t){"use strict";var e=i(65),r=i(63),s=new Array(16);function n(){r.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878}function a(e,t){return e<>>32-t}function f(e,t,r,n,i,o,s){return a(e+(t&r|~t&n)+i+o|0,s)+t|0}function u(e,t,r,n,i,o,s){return a(e+(t&n|r&~n)+i+o|0,s)+t|0}function c(e,t,r,n,i,o,s){return a(e+(t^r^n)+i+o|0,s)+t|0}function h(e,t,r,n,i,o,s){return a(e+(r^(t|~n))+i+o|0,s)+t|0}e(n,r),n.prototype._update=function(){for(var e=s,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);var r=this._a,n=this._b,i=this._c,o=this._d;n=h(n=h(n=h(n=h(n=c(n=c(n=c(n=c(n=u(n=u(n=u(n=u(n=f(n=f(n=f(n=f(n,i=f(i,o=f(o,r=f(r,n,i,o,e[0],3614090360,7),n,i,e[1],3905402710,12),r,n,e[2],606105819,17),o,r,e[3],3250441966,22),i=f(i,o=f(o,r=f(r,n,i,o,e[4],4118548399,7),n,i,e[5],1200080426,12),r,n,e[6],2821735955,17),o,r,e[7],4249261313,22),i=f(i,o=f(o,r=f(r,n,i,o,e[8],1770035416,7),n,i,e[9],2336552879,12),r,n,e[10],4294925233,17),o,r,e[11],2304563134,22),i=f(i,o=f(o,r=f(r,n,i,o,e[12],1804603682,7),n,i,e[13],4254626195,12),r,n,e[14],2792965006,17),o,r,e[15],1236535329,22),i=u(i,o=u(o,r=u(r,n,i,o,e[1],4129170786,5),n,i,e[6],3225465664,9),r,n,e[11],643717713,14),o,r,e[0],3921069994,20),i=u(i,o=u(o,r=u(r,n,i,o,e[5],3593408605,5),n,i,e[10],38016083,9),r,n,e[15],3634488961,14),o,r,e[4],3889429448,20),i=u(i,o=u(o,r=u(r,n,i,o,e[9],568446438,5),n,i,e[14],3275163606,9),r,n,e[3],4107603335,14),o,r,e[8],1163531501,20),i=u(i,o=u(o,r=u(r,n,i,o,e[13],2850285829,5),n,i,e[2],4243563512,9),r,n,e[7],1735328473,14),o,r,e[12],2368359562,20),i=c(i,o=c(o,r=c(r,n,i,o,e[5],4294588738,4),n,i,e[8],2272392833,11),r,n,e[11],1839030562,16),o,r,e[14],4259657740,23),i=c(i,o=c(o,r=c(r,n,i,o,e[1],2763975236,4),n,i,e[4],1272893353,11),r,n,e[7],4139469664,16),o,r,e[10],3200236656,23),i=c(i,o=c(o,r=c(r,n,i,o,e[13],681279174,4),n,i,e[0],3936430074,11),r,n,e[3],3572445317,16),o,r,e[6],76029189,23),i=c(i,o=c(o,r=c(r,n,i,o,e[9],3654602809,4),n,i,e[12],3873151461,11),r,n,e[15],530742520,16),o,r,e[2],3299628645,23),i=h(i,o=h(o,r=h(r,n,i,o,e[0],4096336452,6),n,i,e[7],1126891415,10),r,n,e[14],2878612391,15),o,r,e[5],4237533241,21),i=h(i,o=h(o,r=h(r,n,i,o,e[12],1700485571,6),n,i,e[3],2399980690,10),r,n,e[10],4293915773,15),o,r,e[1],2240044497,21),i=h(i,o=h(o,r=h(r,n,i,o,e[8],1873313359,6),n,i,e[15],4264355552,10),r,n,e[6],2734768916,15),o,r,e[13],1309151649,21),i=h(i,o=h(o,r=h(r,n,i,o,e[4],4149444226,6),n,i,e[11],3174756917,10),r,n,e[2],718787259,15),o,r,e[9],3951481745,21),this._a=this._a+r|0,this._b=this._b+n|0,this._c=this._c+i|0,this._d=this._d+o|0},n.prototype._digest=function(){this._block[this._blockOffset++]=128,56this.urls.length-1)return t(new Error("Tried "+(i+1)+" connections, none of which worked: "+JSON.stringify(this.urls.concat(this.url))));var s=function(e,t){return o.logFailure(n),o.connectWithFallback(r,o.urls[i],i+1,e,t)};return e&&t?this.connect(r,n).then(e).catch(function(){s(e,t)}):new Promise(function(e,t){o.connect(r).then(e).catch(function(){s(e,t)})})},n.prototype.checkConnections=function(){var i=0t.highWaterMark&&(t.highWaterMark=(_<=(r=e)?r=_:(r--,r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r++),r)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0));var r}function E(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(b("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?m.nextTick(B,e):B(e))}function B(e){b("emit readable"),e.emit("readable"),I(e)}function k(e,t){t.readingMore||(t.readingMore=!0,m.nextTick(T,e,t))}function T(e,t){for(var r=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):r=function(e,t,r){var n;eo.length?o.length:e;if(s===o.length?i+=o:i+=o.slice(0,e),0===(e-=s)){s===o.length?(++n,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r).data=o.slice(s);break}++n}return t.length-=n,i}(e,t):function(e,t){var r=u.allocUnsafe(e),n=t.head,i=1;n.data.copy(r),e-=n.data.length;for(;n=n.next;){var o=n.data,s=e>o.length?o.length:e;if(o.copy(r,r.length-e,0,s),0===(e-=s)){s===o.length?(++i,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n).data=o.slice(s);break}++i}return t.length-=i,r}(e,t);return n}(e,t.buffer,t.decoder),r);var r}function O(e){var t=e._readableState;if(0=t.highWaterMark||t.ended))return b("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?O(this):E(this),null;if(0===(e=w(e,t))&&t.ended)return 0===t.length&&O(this),null;var n,i=t.needReadable;return b("need readable",i),(0===t.length||t.length-e>>0),o=this.head,s=0;o;)t=o.data,r=i,n=s,t.copy(r,n),s+=o.data.length,o=o.next;return i},e}(),n&&n.inspect&&n.inspect.custom&&(t.exports.prototype[n.inspect.custom]=function(){var e=n.inspect({length:this.length});return this.constructor.name+" "+e})},{34:34,93:93}],85:[function(e,t,r){"use strict";var o=e(76);function s(e,t){e.emit("error",t)}t.exports={destroy:function(e,t){var r=this,n=this._readableState&&this._readableState.destroyed,i=this._writableState&&this._writableState.destroyed;return n||i?t?t(e):!e||this._writableState&&this._writableState.errorEmitted||o.nextTick(s,this,e):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(o.nextTick(s,r,e),r._writableState&&(r._writableState.errorEmitted=!0)):t&&t(e)})),this},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},{76:76}],86:[function(e,t,r){t.exports=e(62).EventEmitter},{62:62}],87:[function(e,t,r){arguments[4][65][0].apply(r,arguments)},{65:65}],88:[function(e,t,r){t.exports=e(89).PassThrough},{89:89}],89:[function(e,t,r){(((r=t.exports=e(81)).Stream=r).Readable=r).Writable=e(83),r.Duplex=e(79),r.Transform=e(82),r.PassThrough=e(80)},{79:79,80:80,81:81,82:82,83:83}],90:[function(e,t,r){t.exports=e(89).Transform},{89:89}],91:[function(e,t,r){t.exports=e(83)},{83:83}],92:[function(e,t,r){"use strict";var n=e(35).Buffer,i=e(65),o=e(63),g=new Array(16),m=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],v=[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11],y=[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],b=[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11],w=[0,1518500249,1859775393,2400959708,2840853838],E=[1352829926,1548603684,1836072691,2053994217,0];function s(){o.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520}function B(e,t){return e<>>32-t}function k(e,t,r,n,i,o,s,a){return B(e+(t^r^n)+o+s|0,a)+i|0}function T(e,t,r,n,i,o,s,a){return B(e+(t&r|~t&n)+o+s|0,a)+i|0}function S(e,t,r,n,i,o,s,a){return B(e+((t|~r)^n)+o+s|0,a)+i|0}function x(e,t,r,n,i,o,s,a){return B(e+(t&n|r&~n)+o+s|0,a)+i|0}function I(e,t,r,n,i,o,s,a){return B(e+(t^(r|~n))+o+s|0,a)+i|0}i(s,o),s.prototype._update=function(){for(var e=g,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);for(var r=0|this._a,n=0|this._b,i=0|this._c,o=0|this._d,s=0|this._e,a=0|this._a,f=0|this._b,u=0|this._c,c=0|this._d,h=0|this._e,l=0;l<80;l+=1){var p,d;d=l<16?(p=k(r,n,i,o,s,e[m[l]],w[0],y[l]),I(a,f,u,c,h,e[v[l]],E[0],b[l])):l<32?(p=T(r,n,i,o,s,e[m[l]],w[1],y[l]),x(a,f,u,c,h,e[v[l]],E[1],b[l])):l<48?(p=S(r,n,i,o,s,e[m[l]],w[2],y[l]),S(a,f,u,c,h,e[v[l]],E[2],b[l])):l<64?(p=x(r,n,i,o,s,e[m[l]],w[3],y[l]),T(a,f,u,c,h,e[v[l]],E[3],b[l])):(p=I(r,n,i,o,s,e[m[l]],w[4],y[l]),k(a,f,u,c,h,e[v[l]],E[4],b[l])),r=s,s=o,o=B(i,10),i=n,n=p,a=h,h=c,c=B(u,10),u=f,f=d}var _=this._b+i+c|0;this._b=this._c+o+h|0,this._c=this._d+s+a|0,this._d=this._e+r+f|0,this._e=this._a+n+u|0,this._a=_},s.prototype._digest=function(){this._block[this._blockOffset++]=128,56=this._finalSize&&(this._update(this._block),this._block.fill(0));var r=8*this._len;if(r<=4294967295)this._block.writeUInt32BE(r,this._blockSize-4);else{var n=(4294967295&r)>>>0,i=(r-n)/4294967296;this._block.writeUInt32BE(i,this._blockSize-8),this._block.writeUInt32BE(n,this._blockSize-4)}this._update(this._block);var o=this._hash();return e?o.toString(e):o},n.prototype._update=function(){throw new Error("_update must be implemented by subclass")},t.exports=n},{93:93}],96:[function(e,t,r){(r=t.exports=function(e){e=e.toLowerCase();var t=r[e];if(!t)throw new Error(e+" is not supported (we accept pull requests)");return new t}).sha=e(97),r.sha1=e(98),r.sha224=e(99),r.sha256=e(100),r.sha384=e(101),r.sha512=e(102)},{100:100,101:101,102:102,97:97,98:98,99:99}],97:[function(e,t,r){var n=e(65),i=e(95),o=e(93).Buffer,m=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function a(){this.init(),this._w=s,i.call(this,64,56)}n(a,i),a.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},a.prototype._update=function(e){for(var t,r,n,i,o,s,a=this._w,f=0|this._a,u=0|this._b,c=0|this._c,h=0|this._d,l=0|this._e,p=0;p<16;++p)a[p]=e.readInt32BE(4*p);for(;p<80;++p)a[p]=a[p-3]^a[p-8]^a[p-14]^a[p-16];for(var d=0;d<80;++d){var _=~~(d/20),g=0|((s=f)<<5|s>>>27)+(n=u,i=c,o=h,0===(r=_)?n&i|~n&o:2===r?n&i|n&o|i&o:n^i^o)+l+a[d]+m[_];l=h,h=c,c=(t=u)<<30|t>>>2,u=f,f=g}this._a=f+this._a|0,this._b=u+this._b|0,this._c=c+this._c|0,this._d=h+this._d|0,this._e=l+this._e|0},a.prototype._hash=function(){var e=o.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},t.exports=a},{65:65,93:93,95:95}],98:[function(e,t,r){var n=e(65),i=e(95),o=e(93).Buffer,v=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function a(){this.init(),this._w=s,i.call(this,64,56)}n(a,i),a.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},a.prototype._update=function(e){for(var t,r,n,i,o,s,a,f=this._w,u=0|this._a,c=0|this._b,h=0|this._c,l=0|this._d,p=0|this._e,d=0;d<16;++d)f[d]=e.readInt32BE(4*d);for(;d<80;++d)f[d]=(t=f[d-3]^f[d-8]^f[d-14]^f[d-16])<<1|t>>>31;for(var _=0;_<80;++_){var g=~~(_/20),m=0|((a=u)<<5|a>>>27)+(i=c,o=h,s=l,0===(n=g)?i&o|~i&s:2===n?i&o|i&s|o&s:i^o^s)+p+f[_]+v[g];p=l,l=h,h=(r=c)<<30|r>>>2,c=u,u=m}this._a=u+this._a|0,this._b=c+this._b|0,this._c=h+this._c|0,this._d=l+this._d|0,this._e=p+this._e|0},a.prototype._hash=function(){var e=o.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},t.exports=a},{65:65,93:93,95:95}],99:[function(e,t,r){var n=e(65),i=e(100),o=e(95),s=e(93).Buffer,a=new Array(64);function f(){this.init(),this._w=a,o.call(this,64,56)}n(f,i),f.prototype.init=function(){return this._a=3238371032,this._b=914150663,this._c=812702999,this._d=4144912697,this._e=4290775857,this._f=1750603025,this._g=1694076839,this._h=3204075428,this},f.prototype._hash=function(){var e=s.allocUnsafe(28);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e},t.exports=f},{100:100,65:65,93:93,95:95}],100:[function(e,t,r){var n=e(65),i=e(95),o=e(93).Buffer,w=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],s=new Array(64);function a(){this.init(),this._w=s,i.call(this,64,56)}n(a,i),a.prototype.init=function(){return this._a=1779033703,this._b=3144134277,this._c=1013904242,this._d=2773480762,this._e=1359893119,this._f=2600822924,this._g=528734635,this._h=1541459225,this},a.prototype._update=function(e){for(var t,r,n,i,o,s,a,f=this._w,u=0|this._a,c=0|this._b,h=0|this._c,l=0|this._d,p=0|this._e,d=0|this._f,_=0|this._g,g=0|this._h,m=0;m<16;++m)f[m]=e.readInt32BE(4*m);for(;m<64;++m)f[m]=0|(((r=f[m-2])>>>17|r<<15)^(r>>>19|r<<13)^r>>>10)+f[m-7]+(((t=f[m-15])>>>7|t<<25)^(t>>>18|t<<14)^t>>>3)+f[m-16];for(var v=0;v<64;++v){var y=g+(((a=p)>>>6|a<<26)^(a>>>11|a<<21)^(a>>>25|a<<7))+((s=_)^p&(d^s))+w[v]+f[v]|0,b=0|(((o=u)>>>2|o<<30)^(o>>>13|o<<19)^(o>>>22|o<<10))+((n=u)&(i=c)|h&(n|i));g=_,_=d,d=p,p=l+y|0,l=h,h=c,c=u,u=y+b|0}this._a=u+this._a|0,this._b=c+this._b|0,this._c=h+this._c|0,this._d=l+this._d|0,this._e=p+this._e|0,this._f=d+this._f|0,this._g=_+this._g|0,this._h=g+this._h|0},a.prototype._hash=function(){var e=o.allocUnsafe(32);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e.writeInt32BE(this._h,28),e},t.exports=a},{65:65,93:93,95:95}],101:[function(e,t,r){var n=e(65),i=e(102),o=e(95),s=e(93).Buffer,a=new Array(160);function f(){this.init(),this._w=a,o.call(this,128,112)}n(f,i),f.prototype.init=function(){return this._ah=3418070365,this._bh=1654270250,this._ch=2438529370,this._dh=355462360,this._eh=1731405415,this._fh=2394180231,this._gh=3675008525,this._hh=1203062813,this._al=3238371032,this._bl=914150663,this._cl=812702999,this._dl=4144912697,this._el=4290775857,this._fl=1750603025,this._gl=1694076839,this._hl=3204075428,this},f.prototype._hash=function(){var n=s.allocUnsafe(48);function e(e,t,r){n.writeInt32BE(e,r),n.writeInt32BE(t,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),n},t.exports=f},{102:102,65:65,93:93,95:95}],102:[function(e,t,r){var n=e(65),i=e(95),o=e(93).Buffer,ee=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591],s=new Array(160);function a(){this.init(),this._w=s,i.call(this,128,112)}function te(e,t,r){return r^e&(t^r)}function re(e,t,r){return e&t|r&(e|t)}function ne(e,t){return(e>>>28|t<<4)^(t>>>2|e<<30)^(t>>>7|e<<25)}function ie(e,t){return(e>>>14|t<<18)^(e>>>18|t<<14)^(t>>>9|e<<23)}function oe(e,t){return e>>>0>>0?1:0}n(a,i),a.prototype.init=function(){return this._ah=1779033703,this._bh=3144134277,this._ch=1013904242,this._dh=2773480762,this._eh=1359893119,this._fh=2600822924,this._gh=528734635,this._hh=1541459225,this._al=4089235720,this._bl=2227873595,this._cl=4271175723,this._dl=1595750129,this._el=2917565137,this._fl=725511199,this._gl=4215389547,this._hl=327033209,this},a.prototype._update=function(e){for(var t,r,n,i,o,s,a,f,u=this._w,c=0|this._ah,h=0|this._bh,l=0|this._ch,p=0|this._dh,d=0|this._eh,_=0|this._fh,g=0|this._gh,m=0|this._hh,v=0|this._al,y=0|this._bl,b=0|this._cl,w=0|this._dl,E=0|this._el,B=0|this._fl,k=0|this._gl,T=0|this._hl,S=0;S<32;S+=2)u[S]=e.readInt32BE(4*S),u[S+1]=e.readInt32BE(4*S+4);for(;S<160;S+=2){var x=u[S-30],I=u[S-30+1],A=((a=x)>>>1|(f=I)<<31)^(a>>>8|f<<24)^a>>>7,O=((o=I)>>>1|(s=x)<<31)^(o>>>8|s<<24)^(o>>>7|s<<25);x=u[S-4],I=u[S-4+1];var L=((n=x)>>>19|(i=I)<<13)^(i>>>29|n<<3)^n>>>6,C=((t=I)>>>19|(r=x)<<13)^(r>>>29|t<<3)^(t>>>6|r<<26),R=u[S-14],U=u[S-14+1],j=u[S-32],M=u[S-32+1],D=O+U|0,q=A+R+oe(D,O)|0;q=(q=q+L+oe(D=D+C|0,C)|0)+j+oe(D=D+M|0,M)|0,u[S]=q,u[S+1]=D}for(var P=0;P<160;P+=2){q=u[P],D=u[P+1];var N=re(c,h,l),z=re(v,y,b),F=ne(c,v),H=ne(v,c),V=ie(d,E),Y=ie(E,d),K=ee[P],W=ee[P+1],Z=te(d,_,g),G=te(E,B,k),J=T+Y|0,X=m+V+oe(J,T)|0;X=(X=(X=X+Z+oe(J=J+G|0,G)|0)+K+oe(J=J+W|0,W)|0)+q+oe(J=J+D|0,D)|0;var $=H+z|0,Q=F+N+oe($,H)|0;m=g,T=k,g=_,k=B,_=d,B=E,d=p+X+oe(E=w+J|0,w)|0,p=l,w=b,l=h,b=y,h=c,y=v,c=X+Q+oe(v=J+$|0,J)|0}this._al=this._al+v|0,this._bl=this._bl+y|0,this._cl=this._cl+b|0,this._dl=this._dl+w|0,this._el=this._el+E|0,this._fl=this._fl+B|0,this._gl=this._gl+k|0,this._hl=this._hl+T|0,this._ah=this._ah+c+oe(this._al,v)|0,this._bh=this._bh+h+oe(this._bl,y)|0,this._ch=this._ch+l+oe(this._cl,b)|0,this._dh=this._dh+p+oe(this._dl,w)|0,this._eh=this._eh+d+oe(this._el,E)|0,this._fh=this._fh+_+oe(this._fl,B)|0,this._gh=this._gh+g+oe(this._gl,k)|0,this._hh=this._hh+m+oe(this._hl,T)|0},a.prototype._hash=function(){var n=o.allocUnsafe(64);function e(e,t,r){n.writeInt32BE(e,r),n.writeInt32BE(t,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),e(this._gh,this._gl,48),e(this._hh,this._hl,56),n},t.exports=a},{65:65,93:93,95:95}],103:[function(e,t,r){t.exports=n;var c=e(62).EventEmitter;function n(){c.call(this)}e(65)(n,c),n.Readable=e(89),n.Writable=e(91),n.Duplex=e(78),n.Transform=e(90),n.PassThrough=e(88),(n.Stream=n).prototype.pipe=function(t,e){var r=this;function n(e){t.writable&&!1===t.write(e)&&r.pause&&r.pause()}function i(){r.readable&&r.resume&&r.resume()}r.on("data",n),t.on("drain",i),t._isStdio||e&&!1===e.end||(r.on("end",s),r.on("close",a));var o=!1;function s(){o||(o=!0,t.end())}function a(){o||(o=!0,"function"==typeof t.destroy&&t.destroy())}function f(e){if(u(),0===c.listenerCount(this,"error"))throw e}function u(){r.removeListener("data",n),t.removeListener("drain",i),r.removeListener("end",s),r.removeListener("close",a),r.removeListener("error",f),t.removeListener("error",f),r.removeListener("end",u),r.removeListener("close",u),t.removeListener("close",u)}return r.on("error",f),t.on("error",f),r.on("end",u),r.on("close",u),t.on("close",u),t.emit("pipe",r),t}},{62:62,65:65,78:78,88:88,89:89,90:90,91:91}],104:[function(e,t,r){"use strict";var n=e(93).Buffer,i=n.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function o(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(n.isEncoding===i||!i(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=f,this.end=u,t=4;break;case"utf8":this.fillLast=a,t=4;break;case"base64":this.text=c,this.end=h,t=3;break;default:return this.write=l,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=n.allocUnsafe(t)}function s(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function a(e){var t=this.lastTotal-this.lastNeed,r=function(e,t,r){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(1 %s (%d bytes)",i.operation_name,t[1],s,s.length/2)}o.tr_buffer=d.transaction.toBuffer(o)}))})}},{key:"id",value:function(){if(!this.tr_buffer)throw new Error("not finalized");return s.sha256(this.tr_buffer).toString("hex").substring(0,40)}},{key:"add_operation",value:function(e){if(this.tr_buffer)throw new Error("already finalized");if(u(e,"operation"),!Array.isArray(e))throw new Error("Expecting array [operation_id, operation]");this.operations.push(e)}},{key:"get_type_operation",value:function(e,t){if(this.tr_buffer)throw new Error("already finalized");u(e,"name"),u(t,"operation");var r=d[e];u(r,"Unknown operation "+e);var n=i.operations[r.operation_name];if(void 0===n)throw new Error("unknown operation: "+r.operation_name);return t.fee||(t.fee={amount:0,asset_id:0}),"proposal_create"===e&&(t.expiration_time||(t.expiration_time=y()+m.expire_in_secs_proposal)),[n,r.fromObject(t)]}},{key:"set_expire_seconds",value:function(e){if(this.tr_buffer)throw new Error("already finalized");return this.expiration=y()+e}},{key:"propose",value:function(e){if(this.tr_buffer)throw new Error("already finalized");if(!this.operations.length)throw new Error("add operation first");u(e,"proposal_create_options"),u(e.fee_paying_account,"proposal_create_options.fee_paying_account");var t=this.operations.map(function(e){return{op:e}});return this.operations=[],this.signatures=[],this.signer_private_keys=[],e.proposed_ops=t,this.add_type_operation("proposal_create",e),this}},{key:"has_proposed_operation",value:function(){for(var e=!1,t=0;tparseInt(c,10)&&(a=f,u="1.3.0")}var i=[];!function e(t){if(Array.isArray(t))for(var r=0;r>1?o.add(i):o,c=e.pointFromX(f,u),l=c.multiply(i);m(e.isInfinity(l),"nR is not a valid curve point");var h=t.negate().mod(i),d=o.modInverse(i),p=c.multiplyTwo(a,s,h).multiply(d);return e.validate(p),p}t.exports={calcPubKeyRecoveryParam:function(e,t,r,n){for(var i=0;i<4;i++)if(s(e,t,r,i).equals(n))return i;throw new Error("Unable to find valid recovery factor")},deterministicGenerateK:p,recoverPubKey:s,sign:function(r,e,n,t){var i,s,o=h.fromBuffer(e),a=r.n,f=r.G,u=(p(r,e,n,function(e){var t=f.multiply(e);return!r.isInfinity(t)&&0!==(i=t.affineX.mod(a)).signum()&&0!==(s=e.modInverse(a).multiply(o.add(n.multiply(i))).mod(a)).signum()},t),a.shiftRight(1));return 0i.length;)e.writeUint8(0)}}},{key:"public_key",value:function(e,t){if(e){if(!t)return r=n.fixed_data(e,33),i.fromBuffer(r);var r=t.toBuffer();e.append(r.toString("binary"),"binary")}}},{key:"ripemd160",value:function(e,t){if(e)return t?void n.fixed_data(e,20,t):n.fixed_data(e,20)}},{key:"sha256",value:function(e,t){if(e)return t?void n.fixed_data(e,32,t):n.fixed_data(e,32)}},{key:"time_point_sec",value:function(e,t){return t?(t=Math.ceil(t/1e3),void e.writeInt32(t)):(t=e.readInt32(),new Date(1e3*t))}}]),n}();n.exports=t}).call(this,r("buffer").Buffer)},{"../../ecc/src/PublicKey":"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/ecc/src/PublicKey.js",buffer:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/dist/serializer/src/SerializerValidation.js":[function(e,t,r){"use strict";var n="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},i=e("bytebuffer").Long,s=e("../../chain/src/ChainTypes"),o=9007199254740991,a=-9007199254740991,f={is_empty:function(e){return null==e},required:function(e){var t=1>=8;for(;0>=8}for(var o=0;e[o]===c&&o>16&255,s[o++]=t>>8&255,s[o++]=255&t;var u,c;2===i&&(t=l[e.charCodeAt(f)]<<2|l[e.charCodeAt(f+1)]>>4,s[o++]=255&t);1===i&&(t=l[e.charCodeAt(f)]<<10|l[e.charCodeAt(f+1)]<<4|l[e.charCodeAt(f+2)]>>2,s[o++]=t>>8&255,s[o++]=255&t);return s},r.fromByteArray=function(e){for(var t,r=e.length,n=r%3,i=[],s=0,o=r-n;s>2]+a[t<<4&63]+"==")):2===n&&(t=(e[r-2]<<8)+e[r-1],i.push(a[t>>10]+a[t>>4&63]+a[t<<2&63]+"="));return i.join("")};for(var a=[],l=[],h="undefined"!=typeof Uint8Array?Uint8Array:Array,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,s=n.length;i>18&63]+a[i>>12&63]+a[i>>6&63]+a[63&i]);return s.join("")}l["-".charCodeAt(0)]=62,l["_".charCodeAt(0)]=63},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bigi/lib/bigi.js":[function(e,t,r){function w(e,t,r){if(!(this instanceof w))return new w(e,t,r);null!=e&&("number"==typeof e?this.fromNumber(e,t,r):null==t&&"string"!=typeof e?this.fromString(e,256):this.fromString(e,t))}var n=w.prototype;n.__bigi=e("../package.json").version,w.isBigInteger=function(e,t){return e&&e.__bigi&&(!t||e.__bigi===n.__bigi)},w.prototype.am=function(e,t,r,n,i,s){for(;0<=--s;){var o=t*this[e++]+r[n]+i;i=Math.floor(o/67108864),r[n++]=67108863&o}return i},w.prototype.DB=26,w.prototype.DM=67108863;var i=w.prototype.DV=1<<26;w.prototype.FV=Math.pow(2,52),w.prototype.F1=26,w.prototype.F2=0;var s,o,a="0123456789abcdefghijklmnopqrstuvwxyz",f=new Array;for(s="0".charCodeAt(0),o=0;o<=9;++o)f[s++]=o;for(s="a".charCodeAt(0),o=10;o<36;++o)f[s++]=o;for(s="A".charCodeAt(0),o=10;o<36;++o)f[s++]=o;function u(e){return a.charAt(e)}function c(e,t){var r=f[e.charCodeAt(t)];return null==r?-1:r}function y(e){var t=new w;return t.fromInt(e),t}function v(e){var t,r=1;return 0!=(t=e>>>16)&&(e=t,r+=16),0!=(t=e>>8)&&(e=t,r+=8),0!=(t=e>>4)&&(e=t,r+=4),0!=(t=e>>2)&&(e=t,r+=2),0!=(t=e>>1)&&(e=t,r+=1),r}function b(e){this.m=e}function _(e){this.m=e,this.mp=e.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<>=16,t+=16),0==(255&e)&&(e>>=8,t+=8),0==(15&e)&&(e>>=4,t+=4),0==(3&e)&&(e>>=2,t+=2),0==(1&e)&&++t,t}function g(e){for(var t=0;0!=e;)e&=e-1,++t;return t}function j(){}function E(e){return e}function B(e){this.r2=new w,this.q3=new w,w.ONE.dlShiftTo(2*e.t,this.r2),this.mu=this.r2.divide(e),this.m=e}b.prototype.convert=function(e){return e.s<0||0<=e.compareTo(this.m)?e.mod(this.m):e},b.prototype.revert=function(e){return e},b.prototype.reduce=function(e){e.divRemTo(this.m,null,e)},b.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},b.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},_.prototype.convert=function(e){var t=new w;return e.abs().dlShiftTo(this.m.t,t),t.divRemTo(this.m,null,t),e.s<0&&0>15)*this.mpl&this.um)<<15)&e.DM;for(e[r=t+this.m.t]+=this.m.am(0,n,e,t,0,this.m.t);e[r]>=e.DV;)e[r]-=e.DV,e[++r]++}e.clamp(),e.drShiftTo(this.m.t,e),0<=e.compareTo(this.m)&&e.subTo(this.m,e)},_.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},_.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},n.copyTo=function(e){for(var t=this.t-1;0<=t;--t)e[t]=this[t];e.t=this.t,e.s=this.s},n.fromInt=function(e){this.t=1,this.s=e<0?-1:0,0n.DB?(n[n.t-1]|=(a&(1<>n.DB-o):n[n.t-1]|=a<=n.DB&&(o-=n.DB))}8==r&&0!=(128&e[0])&&(n.s=-1,0>s|f,f=(n[r]&o)<=r.t)t.t=0;else{var i=e%r.DB,s=r.DB-i,o=(1<>i;for(var a=n+1;a>i;0>=r.DB;if(e.t>=r.DB;i+=r.s}else{for(i+=r.s;n>=r.DB;i-=e.s}t.s=i<0?-1:0,i<-1?t[n++]=r.DV+i:0=t.DV&&(e[r+t.t]-=t.DV,e[r+t.t+1]=1)}0>n.F2:0),d=n.FV/h,p=(1<>f)&&(s=!0,o=u(n));0<=a;)f>(f+=r.DB-t)):(n=r[a]>>(f-=t)&i,f<=0&&(f+=r.DB,--a)),0>3},n.mod=function(e){var t=new w;return this.abs().divRemTo(e,null,t),this.s<0&&02*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=new w;return e.copyTo(t),this.reduce(t),t},B.prototype.revert=function(e){return e},B.prototype.reduce=function(e){var t=this;for(e.drShiftTo(t.m.t-1,t.r2),e.t>t.m.t+1&&(e.t=t.m.t+1,e.clamp()),t.mu.multiplyUpperTo(t.r2,t.m.t+1,t.q3),t.m.multiplyLowerTo(t.q3,t.m.t+1,t.r2);e.compareTo(t.r2)<0;)e.dAddOffset(1,t.m.t+1);for(e.subTo(t.r2,e);0<=e.compareTo(t.m);)e.subTo(t.m,e)},B.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},B.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)};var x=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],U=(1<<26)/x[x.length-1];n.chunkSize=function(e){return Math.floor(Math.LN2*this.DB/Math.log(e))},n.toRadix=function(e){if(null==e&&(e=10),0==this.signum()||e<2||36=n&&(r.dMultiply(i),r.dAddOffset(a,0),a=o=0))}0e&&n.subTo(w.ONE.shiftLeft(e-1),n);else{var i=new Array,s=7&e;i.length=1+(e>>3),t.nextBytes(i),0>=r.DB;if(e.t>=r.DB;i+=r.s}else{for(i+=r.s;n>=r.DB;i+=e.s}t.s=i<0?-1:0,0=this.DV;)this[t]-=this.DV,++t>=this.t&&(this[this.t++]=0),++this[t]}},n.multiplyLowerTo=function(e,t,r){var n,i=Math.min(this.t+e.t,t);for(r.s=0,r.t=i;0>1)&&(e=x.length);for(var i=new w(null),s=[],o=0;o>24},n.shortValue=function(){return 0==this.t?this.s:this[0]<<16>>16},n.signum=function(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1},n.toByteArray=function(){var e=this,t=e.t,r=new Array;r[0]=e.s;var n,i=e.DB-t*e.DB%8,s=0;if(0>i)!=(e.s&e.DM)>>i&&(r[s++]=n|e.s<>(i+=e.DB-8)):(n=e[t]>>(i-=8)&255,i<=0&&(i+=e.DB,--t)),0!=(128&n)&&(n|=-256),0===s&&(128&e.s)!=(128&n)&&++s,(0=this.t?0!=this.s:0!=(this[t]&1<>i-f&u:(l=(e[d]&(1<>this.DB+i-f)),a=r;0==(1&l);)l>>=1,--a;if((i-=a)<0&&(i+=this.DB,--d),p)o[l].copyTo(s),p=!1;else{for(;1=r())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+r().toString(16)+" bytes");return 0|e}function d(e,t){if(l.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var r=e.length;if(0===r)return 0;for(var n=!1;;)switch(t){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return C(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return R(e).length;default:if(n)return C(e).length;t=(""+t).toLowerCase(),n=!0}}function p(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}function m(e,t,r,n,i){if(0===e.length)return-1;if("string"==typeof r?(n=r,r=0):2147483647=e.length){if(i)return-1;r=e.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof t&&(t=l.from(t,n)),l.isBuffer(t))return 0===t.length?-1:y(e,t,r,n,i);if("number"==typeof t)return t&=255,l.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):y(e,[t],r,n,i);throw new TypeError("val must be string, number or Buffer")}function y(e,t,r,n,i){var s,o=1,a=e.length,f=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;a/=o=2,f/=2,r/=2}function u(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}if(i){var c=-1;for(s=r;s>>10&1023|55296),c=56320|1023&c),n.push(c),i+=l}return function(e){var t=e.length;if(t<=v)return String.fromCharCode.apply(String,e);var r="",n=0;for(;nthis.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return B(this,t,r);case"utf8":case"utf-8":return w(this,t,r);case"ascii":return j(this,t,r);case"latin1":case"binary":return E(this,t,r);case"base64":return g(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return x(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}.apply(this,arguments)},l.prototype.equals=function(e){if(!l.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===l.compare(this,e)},l.prototype.inspect=function(){var e="",t=q.INSPECT_MAX_BYTES;return 0t&&(e+=" ... ")),""},l.prototype.compare=function(e,t,r,n,i){if(!l.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),t<0||r>e.length||n<0||i>this.length)throw new RangeError("out of range index");if(i<=n&&r<=t)return 0;if(i<=n)return-1;if(r<=t)return 1;if(this===e)return 0;for(var s=(i>>>=0)-(n>>>=0),o=(r>>>=0)-(t>>>=0),a=Math.min(s,o),f=this.slice(n,i),u=e.slice(t,r),c=0;cthis.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var s,o,a,f,u,c,l,h,d,p=!1;;)switch(n){case"hex":return b(this,e,t,r);case"utf8":case"utf-8":return h=t,d=r,P(C(e,(l=this).length-h),l,h,d);case"ascii":return _(this,e,t,r);case"latin1":case"binary":return _(this,e,t,r);case"base64":return f=this,u=t,c=r,P(R(e),f,u,c);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return o=t,a=r,P(function(e,t){for(var r,n,i,s=[],o=0;o>8,i=r%256,s.push(i),s.push(n);return s}(e,(s=this).length-o),s,o,a);default:if(p)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),p=!0}},l.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var v=4096;function j(e,t,r){var n="";r=Math.min(e.length,r);for(var i=t;ie.length)throw new RangeError("Index out of range")}function D(e,t,r,n){t<0&&(t=65535+t+1);for(var i=0,s=Math.min(e.length-r,2);i>>8*(n?i:1-i)}function T(e,t,r,n){t<0&&(t=4294967295+t+1);for(var i=0,s=Math.min(e.length-r,4);i>>8*(n?i:3-i)&255}function S(e,t,r,n,i,s){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function I(e,t,r,n,i){return i||S(e,0,r,4),s.write(e,t,r,n,23,4),r+4}function A(e,t,r,n,i){return i||S(e,0,r,8),s.write(e,t,r,n,52,8),r+8}l.prototype.slice=function(e,t){var r,n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):n>>8):D(this,e,t,!0),t+2},l.prototype.writeUInt16BE=function(e,t,r){return e=+e,t|=0,r||k(this,e,t,2,65535,0),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):D(this,e,t,!1),t+2},l.prototype.writeUInt32LE=function(e,t,r){return e=+e,t|=0,r||k(this,e,t,4,4294967295,0),l.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):T(this,e,t,!0),t+4},l.prototype.writeUInt32BE=function(e,t,r){return e=+e,t|=0,r||k(this,e,t,4,4294967295,0),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):T(this,e,t,!1),t+4},l.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t|=0,!n){var i=Math.pow(2,8*r-1);k(this,e,t,r,i-1,-i)}var s=0,o=1,a=0;for(this[t]=255&e;++s>0)-a&255;return t+r},l.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t|=0,!n){var i=Math.pow(2,8*r-1);k(this,e,t,r,i-1,-i)}var s=r-1,o=1,a=0;for(this[t+s]=255&e;0<=--s&&(o*=256);)e<0&&0===a&&0!==this[t+s+1]&&(a=1),this[t+s]=(e/o>>0)-a&255;return t+r},l.prototype.writeInt8=function(e,t,r){return e=+e,t|=0,r||k(this,e,t,1,127,-128),l.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},l.prototype.writeInt16LE=function(e,t,r){return e=+e,t|=0,r||k(this,e,t,2,32767,-32768),l.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):D(this,e,t,!0),t+2},l.prototype.writeInt16BE=function(e,t,r){return e=+e,t|=0,r||k(this,e,t,2,32767,-32768),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):D(this,e,t,!1),t+2},l.prototype.writeInt32LE=function(e,t,r){return e=+e,t|=0,r||k(this,e,t,4,2147483647,-2147483648),l.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):T(this,e,t,!0),t+4},l.prototype.writeInt32BE=function(e,t,r){return e=+e,t|=0,r||k(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),l.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):T(this,e,t,!1),t+4},l.prototype.writeFloatLE=function(e,t,r){return I(this,e,t,!0,r)},l.prototype.writeFloatBE=function(e,t,r){return I(this,e,t,!1,r)},l.prototype.writeDoubleLE=function(e,t,r){return A(this,e,t,!0,r)},l.prototype.writeDoubleBE=function(e,t,r){return A(this,e,t,!1,r)},l.prototype.copy=function(e,t,r,n){if(r||(r=0),n||0===n||(n=this.length),t>=e.length&&(t=e.length),t||(t=0),0=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(s=t;s>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;s.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;s.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return s}function R(e){return n.toByteArray(function(e){var t;if((e=(t=e,t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")).replace(O,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function P(e,t,r,n){for(var i=0;i=t.length||i>=e.length);++i)t[i+r]=e[i];return i}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"base64-js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/base64-js/index.js",ieee754:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ieee754/index.js",isarray:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/isarray/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/string_decoder/index.js":[function(e,t,r){var n=e("buffer").Buffer,i=n.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};var s=r.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),function(e){if(e&&!i(e))throw new Error("Unknown encoding: "+e)}(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=a;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=f;break;default:return void(this.write=o)}this.charBuffer=new n(6),this.charReceived=0,this.charLength=0};function o(e){return e.toString(this.encoding)}function a(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function f(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}s.prototype.write=function(e){for(var t="";this.charLength;){var r=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,r),this.charReceived+=r,this.charReceived>5==6){this.charLength=2;break}if(t<=2&&r>>4==14){this.charLength=3;break}if(t<=3&&r>>3==30){this.charLength=4;break}}this.charReceived=t},s.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var r=this.charReceived,n=this.charBuffer,i=this.encoding;t+=n.slice(0,r).toString(i)}return t}},{buffer:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browserify/node_modules/buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bs58/index.js":[function(e,t,r){var n=e("base-x");t.exports=n("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")},{"base-x":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/base-x/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/bytebuffer/dist/bytebuffer.js":[function(t,e,r){var n,i;n=this,i=function(f){"use strict";var p=function(e,t,r){if(void 0===e&&(e=p.DEFAULT_CAPACITY),void 0===t&&(t=p.DEFAULT_ENDIAN),void 0===r&&(r=p.DEFAULT_NOASSERT),!r){if((e|=0)<0)throw RangeError("Illegal capacity");t=!!t,r=!!r}this.buffer=0===e?s:new ArrayBuffer(e),this.view=0===e?null:new Uint8Array(this.buffer),this.offset=0,this.markedOffset=-1,this.limit=e,this.littleEndian=t,this.noAssert=r};p.VERSION="5.0.1",p.LITTLE_ENDIAN=!0,p.BIG_ENDIAN=!1,p.DEFAULT_CAPACITY=16,p.DEFAULT_ENDIAN=p.BIG_ENDIAN,p.DEFAULT_NOASSERT=!1,p.Long=f||null;var o=p.prototype;o.__isByteBuffer__,Object.defineProperty(o,"__isByteBuffer__",{value:!0,enumerable:!1,configurable:!1});var s=new ArrayBuffer(0),r=String.fromCharCode;function a(e){var t=0;return function(){return t>1,c=-7,l=r?i-1:0,h=r?-1:1,d=e[t+l];for(l+=h,s=d&(1<<-c)-1,d>>=-c,c+=a;0>=-c,c+=n;0>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=n?0:s-1,p=n?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-o))<1&&(o--,f*=2),2<=(t+=1<=o+l?h/f:h*Math.pow(2,1-l))*f&&(o++,f/=2),c<=o+l?(a=0,o=c):1<=o+l?(a=(t*f-1)*Math.pow(2,i),o+=l):(a=t*Math.pow(2,l-1)*Math.pow(2,i),o=0));8<=i;e[r+d]=255&a,d+=p,a/=256,i-=8);for(o=o<>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i=t,s=e.length,o=s>>3,a=0;for(t+=this.writeVarint32(s,t);o--;)n=1&!!e[a++]|(1&!!e[a++])<<1|(1&!!e[a++])<<2|(1&!!e[a++])<<3|(1&!!e[a++])<<4|(1&!!e[a++])<<5|(1&!!e[a++])<<6|(1&!!e[a++])<<7,this.writeByte(n,t++);if(a>3,o=0,a=[];for(e+=n.length;s--;)r=this.readByte(e++),a[o++]=!!(1&r),a[o++]=!!(2&r),a[o++]=!!(4&r),a[o++]=!!(8&r),a[o++]=!!(16&r),a[o++]=!!(32&r),a[o++]=!!(64&r),a[o++]=!!(128&r);if(o>f++&1)}return t&&(this.offset=e),a},o.readBytes=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+e>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+"+e+") <= "+this.buffer.byteLength)}var n=this.slice(t,t+e);return r&&(this.offset+=e),n},o.writeBytes=o.append,o.writeInt8=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var n=this.buffer.byteLength;return nt?n:t),t-=1,this.view[t]=e,r&&(this.offset+=1),this},o.writeByte=o.writeInt8,o.readInt8=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=this.view[e];return 128==(128&r)&&(r=-(255-r+1)),t&&(this.offset+=1),r},o.readByte=o.readInt8,o.writeUint8=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var n=this.buffer.byteLength;return nt?n:t),t-=1,this.view[t]=e,r&&(this.offset+=1),this},o.writeUInt8=o.writeUint8,o.readUint8=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=this.view[e];return t&&(this.offset+=1),r},o.readUInt8=o.readUint8,o.writeInt16=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var n=this.buffer.byteLength;return nt?n:t),t-=2,this.littleEndian?(this.view[t+1]=(65280&e)>>>8,this.view[t]=255&e):(this.view[t]=(65280&e)>>>8,this.view[t+1]=255&e),r&&(this.offset+=2),this},o.writeShort=o.writeInt16,o.readInt16=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e],r|=this.view[e+1]<<8):(r=this.view[e]<<8,r|=this.view[e+1]),32768==(32768&r)&&(r=-(65535-r+1)),t&&(this.offset+=2),r},o.readShort=o.readInt16,o.writeUint16=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var n=this.buffer.byteLength;return nt?n:t),t-=2,this.littleEndian?(this.view[t+1]=(65280&e)>>>8,this.view[t]=255&e):(this.view[t]=(65280&e)>>>8,this.view[t+1]=255&e),r&&(this.offset+=2),this},o.writeUInt16=o.writeUint16,o.readUint16=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e],r|=this.view[e+1]<<8):(r=this.view[e]<<8,r|=this.view[e+1]),t&&(this.offset+=2),r},o.readUInt16=o.readUint16,o.writeInt32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var n=this.buffer.byteLength;return nt?n:t),t-=4,this.littleEndian?(this.view[t+3]=e>>>24&255,this.view[t+2]=e>>>16&255,this.view[t+1]=e>>>8&255,this.view[t]=255&e):(this.view[t]=e>>>24&255,this.view[t+1]=e>>>16&255,this.view[t+2]=e>>>8&255,this.view[t+3]=255&e),r&&(this.offset+=4),this},o.writeInt=o.writeInt32,o.readInt32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0):(r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0),r|=0,t&&(this.offset+=4),r},o.readInt=o.readInt32,o.writeUint32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var n=this.buffer.byteLength;return nt?n:t),t-=4,this.littleEndian?(this.view[t+3]=e>>>24&255,this.view[t+2]=e>>>16&255,this.view[t+1]=e>>>8&255,this.view[t]=255&e):(this.view[t]=e>>>24&255,this.view[t+1]=e>>>16&255,this.view[t+2]=e>>>8&255,this.view[t+3]=255&e),r&&(this.offset+=4),this},o.writeUInt32=o.writeUint32,o.readUint32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0):(r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0),t&&(this.offset+=4),r},o.readUInt32=o.readUint32,f&&(o.writeInt64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e)),t+=8;var n=this.buffer.byteLength;nt?n:t),t-=8;var i=e.low,s=e.high;return this.littleEndian?(this.view[t+3]=i>>>24&255,this.view[t+2]=i>>>16&255,this.view[t+1]=i>>>8&255,this.view[t]=255&i,t+=4,this.view[t+3]=s>>>24&255,this.view[t+2]=s>>>16&255,this.view[t+1]=s>>>8&255,this.view[t]=255&s):(this.view[t]=s>>>24&255,this.view[t+1]=s>>>16&255,this.view[t+2]=s>>>8&255,this.view[t+3]=255&s,t+=4,this.view[t]=i>>>24&255,this.view[t+1]=i>>>16&255,this.view[t+2]=i>>>8&255,this.view[t+3]=255&i),r&&(this.offset+=8),this},o.writeLong=o.writeInt64,o.readInt64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=0,n=0;this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0,e+=4,n=this.view[e+2]<<16,n|=this.view[e+1]<<8,n|=this.view[e],n+=this.view[e+3]<<24>>>0):(n=this.view[e+1]<<16,n|=this.view[e+2]<<8,n|=this.view[e+3],n+=this.view[e]<<24>>>0,e+=4,r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0);var i=new f(r,n,!1);return t&&(this.offset+=8),i},o.readLong=o.readInt64,o.writeUint64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e)),t+=8;var n=this.buffer.byteLength;nt?n:t),t-=8;var i=e.low,s=e.high;return this.littleEndian?(this.view[t+3]=i>>>24&255,this.view[t+2]=i>>>16&255,this.view[t+1]=i>>>8&255,this.view[t]=255&i,t+=4,this.view[t+3]=s>>>24&255,this.view[t+2]=s>>>16&255,this.view[t+1]=s>>>8&255,this.view[t]=255&s):(this.view[t]=s>>>24&255,this.view[t+1]=s>>>16&255,this.view[t+2]=s>>>8&255,this.view[t+3]=255&s,t+=4,this.view[t]=i>>>24&255,this.view[t+1]=i>>>16&255,this.view[t+2]=i>>>8&255,this.view[t+3]=255&i),r&&(this.offset+=8),this},o.writeUInt64=o.writeUint64,o.readUint64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=0,n=0;this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0,e+=4,n=this.view[e+2]<<16,n|=this.view[e+1]<<8,n|=this.view[e],n+=this.view[e+3]<<24>>>0):(n=this.view[e+1]<<16,n|=this.view[e+2]<<8,n|=this.view[e+3],n+=this.view[e]<<24>>>0,e+=4,r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0);var i=new f(r,n,!0);return t&&(this.offset+=8),i},o.readUInt64=o.readUint64),o.writeFloat32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var n=this.buffer.byteLength;return nt?n:t),t-=4,i(this.view,e,t,this.littleEndian,23,4),r&&(this.offset+=4),this},o.writeFloat=o.writeFloat32,o.readFloat32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=n(this.view,e,this.littleEndian,23,4);return t&&(this.offset+=4),r},o.readFloat=o.readFloat32,o.writeFloat64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=8;var n=this.buffer.byteLength;return nt?n:t),t-=8,i(this.view,e,t,this.littleEndian,52,8),r&&(this.offset+=8),this},o.writeDouble=o.writeFloat64,o.readFloat64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=n(this.view,e,this.littleEndian,52,8);return t&&(this.offset+=8),r},o.readDouble=o.readFloat64,p.MAX_VARINT32_BYTES=5,p.calculateVarint32=function(e){return(e>>>=0)<128?1:e<16384?2:e<1<<21?3:e<1<<28?4:5},p.zigZagEncode32=function(e){return((e|=0)<<1^e>>31)>>>0},p.zigZagDecode32=function(e){return e>>>1^-(1&e)|0},o.writeVarint32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i=p.calculateVarint32(e);t+=i;var s=this.buffer.byteLength;for(st?s:t),t-=i,e>>>=0;128<=e;)n=127&e|128,this.view[t++]=n,e>>>=7;return this.view[t++]=e,r?(this.offset=t,this):i},o.writeVarint32ZigZag=function(e,t){return this.writeVarint32(p.zigZagEncode32(e),t)},o.readVarint32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,n=0,i=0;do{if(!this.noAssert&&e>this.limit){var s=Error("Truncated");throw s.truncated=!0,s}r=this.view[e++],n<5&&(i|=(127&r)<<7*n),++n}while(0!=(128&r));return i|=0,t?(this.offset=e,i):{value:i,length:n}},o.readVarint32ZigZag=function(e){var t=this.readVarint32(e);return"object"==typeof t?t.value=p.zigZagDecode32(t.value):t=p.zigZagDecode32(t),t},f&&(p.MAX_VARINT64_BYTES=10,p.calculateVarint64=function(e){"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e));var t=e.toInt()>>>0,r=e.shiftRightUnsigned(28).toInt()>>>0,n=e.shiftRightUnsigned(56).toInt()>>>0;return 0==n?0==r?t<16384?t<128?1:2:t<1<<21?3:4:r<16384?r<128?5:6:r<1<<21?7:8:n<128?9:10},p.zigZagEncode64=function(e){return"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftLeft(1).xor(e.shiftRight(63)).toUnsigned()},p.zigZagDecode64=function(e){return"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftRightUnsigned(1).xor(e.and(f.ONE).toSigned().negate()).toSigned()},o.writeVarint64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned());var n=p.calculateVarint64(e),i=e.toInt()>>>0,s=e.shiftRightUnsigned(28).toInt()>>>0,o=e.shiftRightUnsigned(56).toInt()>>>0;t+=n;var a=this.buffer.byteLength;switch(at?a:t),t-=n,n){case 10:this.view[t+9]=o>>>7&1;case 9:this.view[t+8]=9!==n?128|o:127&o;case 8:this.view[t+7]=8!==n?s>>>21|128:s>>>21&127;case 7:this.view[t+6]=7!==n?s>>>14|128:s>>>14&127;case 6:this.view[t+5]=6!==n?s>>>7|128:s>>>7&127;case 5:this.view[t+4]=5!==n?128|s:127&s;case 4:this.view[t+3]=4!==n?i>>>21|128:i>>>21&127;case 3:this.view[t+2]=3!==n?i>>>14|128:i>>>14&127;case 2:this.view[t+1]=2!==n?i>>>7|128:i>>>7&127;case 1:this.view[t]=1!==n?128|i:127&i}return r?(this.offset+=n,this):n},o.writeVarint64ZigZag=function(e,t){return this.writeVarint64(p.zigZagEncode64(e),t)},o.readVarint64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=e,n=0,i=0,s=0,o=0;if(n=127&(o=this.view[e++]),128&o&&(n|=(127&(o=this.view[e++]))<<7,(128&o||this.noAssert&&void 0===o)&&(n|=(127&(o=this.view[e++]))<<14,(128&o||this.noAssert&&void 0===o)&&(n|=(127&(o=this.view[e++]))<<21,(128&o||this.noAssert&&void 0===o)&&(i=127&(o=this.view[e++]),(128&o||this.noAssert&&void 0===o)&&(i|=(127&(o=this.view[e++]))<<7,(128&o||this.noAssert&&void 0===o)&&(i|=(127&(o=this.view[e++]))<<14,(128&o||this.noAssert&&void 0===o)&&(i|=(127&(o=this.view[e++]))<<21,(128&o||this.noAssert&&void 0===o)&&(s=127&(o=this.view[e++]),(128&o||this.noAssert&&void 0===o)&&(s|=(127&(o=this.view[e++]))<<7,128&o||this.noAssert&&void 0===o))))))))))throw Error("Buffer overrun");var a=f.fromBits(n|i<<28,i>>>4|s<<24,!1);return t?(this.offset=e,a):{value:a,length:e-r}},o.readVarint64ZigZag=function(e){var t=this.readVarint64(e);return t&&t.value instanceof f?t.value=p.zigZagDecode64(t.value):t=p.zigZagDecode64(t),t}),o.writeCString=function(e,t){var r=void 0===t;r&&(t=this.offset);var n,i=e.length;if(!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");for(n=0;n>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}i=h.calculateUTF16asUTF8(a(e))[1],t+=i+1;var s=this.buffer.byteLength;return st?s:t),t-=i+1,h.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),this.view[t++]=0,r?(this.offset=t,this):i},o.readCString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,n=e,i=-1;return h.decodeUTF8toUTF16(function(){if(0===i)return null;if(e>=this.limit)throw RangeError("Illegal range: Truncated data, "+e+" < "+this.limit);return 0===(i=this.view[e++])?null:i}.bind(this),r=u(),!0),t?(this.offset=e,r()):{string:r(),length:e-n}},o.writeIString=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i=t;n=h.calculateUTF16asUTF8(a(e),this.noAssert)[1],t+=4+n;var s=this.buffer.byteLength;if(st?s:t),t-=4+n,this.littleEndian?(this.view[t+3]=n>>>24&255,this.view[t+2]=n>>>16&255,this.view[t+1]=n>>>8&255,this.view[t]=255&n):(this.view[t]=n>>>24&255,this.view[t+1]=n>>>16&255,this.view[t+2]=n>>>8&255,this.view[t+3]=255&n),t+=4,h.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),t!==i+4+n)throw RangeError("Illegal range: Truncated data, "+t+" == "+(t+4+n));return r?(this.offset=t,this):t-i},o.readIString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=e,n=this.readUint32(e),i=this.readUTF8String(n,p.METRICS_BYTES,e+=4);return e+=i.length,t?(this.offset=e,i.string):{string:i.string,length:e-r}},p.METRICS_CHARS="c",p.METRICS_BYTES="b",o.writeUTF8String=function(e,t){var r,n=void 0===t;if(n&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var i=t;r=h.calculateUTF16asUTF8(a(e))[1],t+=r;var s=this.buffer.byteLength;return st?s:t),t-=r,h.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),n?(this.offset=t,this):t-i},o.writeString=o.writeUTF8String,p.calculateUTF8Chars=function(e){return h.calculateUTF16asUTF8(a(e))[0]},p.calculateUTF8Bytes=function(e){return h.calculateUTF16asUTF8(a(e))[1]},p.calculateString=p.calculateUTF8Bytes,o.readUTF8String=function(e,t,r){"number"==typeof t&&(r=t,t=void 0);var n=void 0===r;if(n&&(r=this.offset),void 0===t&&(t=p.METRICS_CHARS),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal length: "+e+" (not an integer)");if(e|=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}var i,s=0,o=r;if(t===p.METRICS_CHARS){if(i=u(),h.decodeUTF8(function(){return s>>=0)<0||r+e>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+"+e+") <= "+this.buffer.byteLength)}var a=r+e;if(h.decodeUTF8toUTF16(function(){return r>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var n,i,s=t;n=h.calculateUTF16asUTF8(a(e),this.noAssert)[1],i=p.calculateVarint32(n),t+=i+n;var o=this.buffer.byteLength;if(ot?o:t),t-=i+n,t+=this.writeVarint32(n,t),h.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),t!==s+n+i)throw RangeError("Illegal range: Truncated data, "+t+" == "+(t+n+i));return r?(this.offset=t,this):t-s},o.readVString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=e,n=this.readVarint32(e),i=this.readUTF8String(n.value,p.METRICS_BYTES,e+=n.length);return e+=i.length,t?(this.offset=e,i.string):{string:i.string,length:e-r}},o.append=function(e,t,r){"number"!=typeof t&&"string"==typeof t||(r=t,t=void 0);var n=void 0===r;if(n&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}e instanceof p||(e=p.wrap(e,t));var i=e.limit-e.offset;if(i<=0)return this;r+=i;var s=this.buffer.byteLength;return sr?s:r),r-=i,this.view.set(e.view.subarray(e.offset,e.limit),r),e.offset+=i,n&&(this.offset+=i),this},o.appendTo=function(e,t){return e.append(this,t),this},o.assert=function(e){return this.noAssert=!e,this},o.capacity=function(){return this.buffer.byteLength},o.clear=function(){return this.offset=0,this.limit=this.buffer.byteLength,this.markedOffset=-1,this},o.clone=function(e){var t=new p(0,this.littleEndian,this.noAssert);return t.view=e?(t.buffer=new ArrayBuffer(this.buffer.byteLength),new Uint8Array(t.buffer)):(t.buffer=this.buffer,this.view),t.offset=this.offset,t.markedOffset=this.markedOffset,t.limit=this.limit,t},o.compact=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(0===e&&t===this.buffer.byteLength)return this;var r=t-e;if(0===r)return this.buffer=s,this.view=null,0<=this.markedOffset&&(this.markedOffset-=e),this.offset=0,this.limit=0,this;var n=new ArrayBuffer(r),i=new Uint8Array(n);return i.set(this.view.subarray(e,t)),this.buffer=n,this.view=i,0<=this.markedOffset&&(this.markedOffset-=e),this.offset=0,this.limit=r,this},o.copy=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(e===t)return new p(0,this.littleEndian,this.noAssert);var r=t-e,n=new p(r,this.littleEndian,this.noAssert);return n.offset=0,n.limit=r,0<=n.markedOffset&&(n.markedOffset-=e),this.copyTo(n,0,e,t),n},o.copyTo=function(e,t,r,n){var i,s;if(!this.noAssert&&!p.isByteBuffer(e))throw TypeError("Illegal target: Not a ByteBuffer");if(t=(s=void 0===t)?e.offset:0|t,r=(i=void 0===r)?this.offset:0|r,n=void 0===n?this.limit:0|n,t<0||t>e.buffer.byteLength)throw RangeError("Illegal target range: 0 <= "+t+" <= "+e.buffer.byteLength);if(r<0||n>this.buffer.byteLength)throw RangeError("Illegal source range: 0 <= "+r+" <= "+this.buffer.byteLength);var o=n-r;return 0===o?e:(e.ensureCapacity(t+o),e.view.set(this.view.subarray(r,n),t),i&&(this.offset+=o),s&&(e.offset+=o),this)},o.ensureCapacity=function(e){var t=this.buffer.byteLength;return te?t:e):this},o.fill=function(e,t,r){var n=void 0===t;if(n&&(t=this.offset),"string"==typeof e&&0>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal end: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}if(r<=t)return this;for(;t>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}return this.markedOffset=e,this},o.order=function(e){if(!this.noAssert&&"boolean"!=typeof e)throw TypeError("Illegal littleEndian: Not a boolean");return this.littleEndian=!!e,this},o.LE=function(e){return this.littleEndian=void 0===e||!!e,this},o.BE=function(e){return this.littleEndian=void 0!==e&&!e,this},o.prepend=function(e,t,r){"number"!=typeof t&&"string"==typeof t||(r=t,t=void 0);var n=void 0===r;if(n&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}e instanceof p||(e=p.wrap(e,t));var i=e.limit-e.offset;if(i<=0)return this;var s=i-r;if(0>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}return e===t||Array.prototype.reverse.call(this.view.subarray(e,t)),this},o.skip=function(e){if(!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal length: "+e+" (not an integer)");e|=0}var t=this.offset+e;if(!this.noAssert&&(t<0||t>this.buffer.byteLength))throw RangeError("Illegal length: 0 <= "+this.offset+" + "+e+" <= "+this.buffer.byteLength);return this.offset=t,this},o.slice=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}var r=this.clone();return r.offset=e,r.limit=t,r},o.toBuffer=function(e){var t=this.offset,r=this.limit;if(!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: Not an integer");if(t>>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal limit: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}if(!e&&0===t&&r===this.buffer.byteLength)return this.buffer;if(t===r)return s;var n=new ArrayBuffer(r-t);return new Uint8Array(n).set(new Uint8Array(this.buffer).subarray(t,r),0),n},o.toArrayBuffer=o.toBuffer,o.toString=function(e,t,r){if(void 0===e)return"ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";switch("number"==typeof e&&(r=t=e="utf8"),e){case"utf8":return this.toUTF8(t,r);case"base64":return this.toBase64(t,r);case"hex":return this.toHex(t,r);case"binary":return this.toBinary(t,r);case"debug":return this.toDebug();case"columns":return this.toColumns();default:throw Error("Unsupported encoding: "+e)}};var c=function(){for(var e={},i=[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47],o=[],t=0,r=i.length;t>2&63]),n=(3&r)<<4,null!==(r=e())?(t(i[63&((n|=r>>4&15)|r>>4&15)]),n=(15&r)<<2,null!==(r=e())?(t(i[63&(n|r>>6&3)]),t(i[63&r])):(t(i[63&n]),t(61))):(t(i[63&n]),t(61),t(61))},e.decode=function(e,t){var r,n,i;function s(e){throw Error("Illegal character code: "+e)}for(;null!==(r=e());)if(void 0===(n=o[r])&&s(r),null!==(r=e())&&(void 0===(i=o[r])&&s(r),t(n<<2>>>0|(48&i)>>4),null!==(r=e()))){if(void 0===(n=o[r])){if(61===r)break;s(r)}if(t((15&i)<<4>>>0|(60&n)>>2),null!==(r=e())){if(void 0===(i=o[r])){if(61===r)break;s(r)}t((3&n)<<6>>>0|i)}}},e.test=function(e){return/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e)},e}();o.toBase64=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),t|=0,(e|=0)<0||t>this.capacity||tthis.capacity()||t":i+=r===this.markedOffset?"'":e||0!==r&&r!==n?" ":""}if(e&&" "!==i){for(;i.length<51;)i+=" ";o+=i+s+"\n"}return e?o:i},p.fromDebug=function(e,t,r){for(var n,i,s=e.length,o=new p((s+1)/3|0,t,r),a=0,f=0,u=!1,c=!1,l=!1,h=!1,d=!1;a":if(!r){if(h){d=!0;break}h=!0}o.limit=f,u=!1;break;case"'":if(!r){if(l){d=!0;break}l=!0}o.markedOffset=f,u=!1;break;case" ":u=!1;break;default:if(!r&&u){d=!0;break}if(i=parseInt(n+e.charAt(a++),16),!r&&(isNaN(i)||i<0||255>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}for(var r,n=new Array(t-e);e>6&31|192):(r<65536?t(r>>12&15|224):(t(r>>18&7|240),t(r>>12&63|128)),t(r>>6&63|128)),t(63&r|128)),r=null},decodeUTF8:function(e,t){for(var r,n,i,s,o=function(e){e=e.slice(0,e.indexOf(null));var t=Error(e.toString());throw t.name="TruncatedError",t.bytes=e,t};null!==(r=e());)if(0==(128&r))t(r);else if(192==(224&r))null===(n=e())&&o([r,n]),t((31&r)<<6|63&n);else if(224==(240&r))(null===(n=e())||null===(i=e()))&&o([r,n,i]),t((15&r)<<12|(63&n)<<6|63&i);else{if(240!=(248&r))throw RangeError("Illegal starting byte: "+r);(null===(n=e())||null===(i=e())||null===(s=e()))&&o([r,n,i,s]),t((7&r)<<18|(63&n)<<12|(63&i)<<6|63&s)}},UTF16toUTF8:function(e,t){for(var r,n=null;null!==(r=null!==n?n:e());)55296<=r&&r<=57343&&null!==(n=e())&&56320<=n&&n<=57343?(t(1024*(r-55296)+n-56320+65536),n=null):t(r);null!==n&&t(n)},UTF8toUTF16:function(e,t){var r=null;for("number"==typeof e&&(r=e,e=function(){return null});null!==r||null!==(r=e());)r<=65535?t(r):(t(55296+((r-=65536)>>10)),t(r%1024+56320)),r=null},encodeUTF16toUTF8:function(e,t){l.UTF16toUTF8(e,function(e){l.encodeUTF8(e,t)})},decodeUTF8toUTF16:function(e,t){l.decodeUTF8(e,function(e){l.UTF8toUTF16(e,t)})},calculateCodePoint:function(e){return e<128?1:e<2048?2:e<65536?3:4},calculateUTF8:function(e){for(var t,r=0;null!==(t=e());)r+=t<128?1:t<2048?2:t<65536?3:4;return r},calculateUTF16asUTF8:function(e){var t=0,r=0;return l.UTF16toUTF8(e,function(e){++t,r+=e<128?1:e<2048?2:e<65536?3:4}),[t,r]}};return o.toUTF8=function(t,r){if(void 0===t&&(t=this.offset),void 0===r&&(r=this.limit),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal begin: Not an integer");if(t>>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal end: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}var e;try{h.decodeUTF8toUTF16(function(){return tr)?t=("rmd160"===e?new f:u(e)).update(t).digest():t.length>>8^255&i^99,u[r]=i;var s=e[c[i]=r],o=e[s],a=e[o],f=257*e[i]^16843008*i;l[r]=f<<24|f>>>8,h[r]=f<<16|f>>>16,d[r]=f<<8|f>>>24,p[r]=f;f=16843009*a^65537*o^257*s^16843008*r;m[i]=f<<24|f>>>8,y[i]=f<<16|f>>>16,b[i]=f<<8|f>>>24,_[i]=f,r?(r=s^e[e[e[a^s]]],n^=e[e[n]]):r=n=1}}();var g=[0,1,2,4,8,16,32,64,128,27,54],n=r.AES=t.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var e=this._keyPriorReset=this._key,t=e.words,r=e.sigBytes/4,n=4*((this._nRounds=r+6)+1),i=this._keySchedule=[],s=0;s>>24]<<24|u[o>>>16&255]<<16|u[o>>>8&255]<<8|u[255&o]):(o=u[(o=o<<8|o>>>24)>>>24]<<24|u[o>>>16&255]<<16|u[o>>>8&255]<<8|u[255&o],o^=g[s/r|0]<<24),i[s]=i[s-r]^o}for(var a=this._invKeySchedule=[],f=0;f>>24]]^y[u[o>>>16&255]]^b[u[o>>>8&255]]^_[u[255&o]]}}},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,l,h,d,p,u)},decryptBlock:function(e,t){var r=e[t+1];e[t+1]=e[t+3],e[t+3]=r,this._doCryptBlock(e,t,this._invKeySchedule,m,y,b,_,c);r=e[t+1];e[t+1]=e[t+3],e[t+3]=r},_doCryptBlock:function(e,t,r,n,i,s,o,a){for(var f=this._nRounds,u=e[t]^r[0],c=e[t+1]^r[1],l=e[t+2]^r[2],h=e[t+3]^r[3],d=4,p=1;p>>24]^i[c>>>16&255]^s[l>>>8&255]^o[255&h]^r[d++],y=n[c>>>24]^i[l>>>16&255]^s[h>>>8&255]^o[255&u]^r[d++],b=n[l>>>24]^i[h>>>16&255]^s[u>>>8&255]^o[255&c]^r[d++],_=n[h>>>24]^i[u>>>16&255]^s[c>>>8&255]^o[255&l]^r[d++];u=m,c=y,l=b,h=_}m=(a[u>>>24]<<24|a[c>>>16&255]<<16|a[l>>>8&255]<<8|a[255&h])^r[d++],y=(a[c>>>24]<<24|a[l>>>16&255]<<16|a[h>>>8&255]<<8|a[255&u])^r[d++],b=(a[l>>>24]<<24|a[h>>>16&255]<<16|a[u>>>8&255]<<8|a[255&c])^r[d++],_=(a[h>>>24]<<24|a[u>>>16&255]<<16|a[c>>>8&255]<<8|a[255&l])^r[d++];e[t]=m,e[t+1]=y,e[t+2]=b,e[t+3]=_},keySize:8});e.AES=t._createHelper(n)}(),i.AES},"object"==typeof r?t.exports=r=i(e("./core"),e("./enc-base64"),e("./md5"),e("./evpkdf"),e("./cipher-core")):i(n.CryptoJS)},{"./cipher-core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/cipher-core.js","./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js","./enc-base64":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/enc-base64.js","./evpkdf":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/evpkdf.js","./md5":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/md5.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/cipher-core.js":[function(e,t,r){var n,i;n=this,i=function(e){var t,r,n,f,i,s,o,a,u,c,l,h,d,p,m,y,b,_;e.lib.Cipher||(r=(t=e).lib,n=r.Base,f=r.WordArray,i=r.BufferedBlockAlgorithm,(s=t.enc).Utf8,o=s.Base64,a=t.algo.EvpKDF,u=r.Cipher=i.extend({cfg:n.extend(),createEncryptor:function(e,t){return this.create(this._ENC_XFORM_MODE,e,t)},createDecryptor:function(e,t){return this.create(this._DEC_XFORM_MODE,e,t)},init:function(e,t,r){this.cfg=this.cfg.extend(r),this._xformMode=e,this._key=t,this.reset()},reset:function(){i.reset.call(this),this._doReset()},process:function(e){return this._append(e),this._process()},finalize:function(e){return e&&this._append(e),this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(){function i(e){return"string"==typeof e?_:y}return function(n){return{encrypt:function(e,t,r){return i(t).encrypt(n,e,t,r)},decrypt:function(e,t,r){return i(t).decrypt(n,e,t,r)}}}}()}),r.StreamCipher=u.extend({_doFinalize:function(){return this._process(!0)},blockSize:1}),c=t.mode={},l=r.BlockCipherMode=n.extend({createEncryptor:function(e,t){return this.Encryptor.create(e,t)},createDecryptor:function(e,t){return this.Decryptor.create(e,t)},init:function(e,t){this._cipher=e,this._iv=t}}),h=c.CBC=function(){var e=l.extend();function s(e,t,r){var n=this._iv;if(n){var i=n;this._iv=void 0}else i=this._prevBlock;for(var s=0;s>>2];e.sigBytes-=t}},r.BlockCipher=u.extend({cfg:u.cfg.extend({mode:h,padding:d}),reset:function(){u.reset.call(this);var e=this.cfg,t=e.iv,r=e.mode;if(this._xformMode==this._ENC_XFORM_MODE)var n=r.createEncryptor;else{n=r.createDecryptor;this._minBufferSize=1}this._mode=n.call(r,this,t&&t.words)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else{t=this._process(!0);e.unpad(t)}return t},blockSize:4}),p=r.CipherParams=n.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),m=(t.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext,r=e.salt;if(r)var n=f.create([1398893684,1701076831]).concat(r).concat(t);else n=t;return n.toString(o)},parse:function(e){var t=o.parse(e),r=t.words;if(1398893684==r[0]&&1701076831==r[1]){var n=f.create(r.slice(2,4));r.splice(0,4),t.sigBytes-=16}return p.create({ciphertext:t,salt:n})}},y=r.SerializableCipher=n.extend({cfg:n.extend({format:m}),encrypt:function(e,t,r,n){n=this.cfg.extend(n);var i=e.createEncryptor(r,n),s=i.finalize(t),o=i.cfg;return p.create({ciphertext:s,key:r,iv:o.iv,algorithm:e,mode:o.mode,padding:o.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,r,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(r,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}}),b=(t.kdf={}).OpenSSL={execute:function(e,t,r,n){n||(n=f.random(8));var i=a.create({keySize:t+r}).compute(e,n),s=f.create(i.words.slice(t),4*r);return i.sigBytes=4*t,p.create({key:i,iv:s,salt:n})}},_=r.PasswordBasedCipher=y.extend({cfg:y.cfg.extend({kdf:b}),encrypt:function(e,t,r,n){var i=(n=this.cfg.extend(n)).kdf.execute(r,e.keySize,e.ivSize);n.iv=i.iv;var s=y.encrypt.call(this,e,t,i.key,n);return s.mixIn(i),s},decrypt:function(e,t,r,n){n=this.cfg.extend(n),t=this._parse(t,n.format);var i=n.kdf.execute(r,e.keySize,e.ivSize,t.salt);return n.iv=i.iv,y.decrypt.call(this,e,t,i.key,n)}}))},"object"==typeof r?t.exports=r=i(e("./core")):i(n.CryptoJS)},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js":[function(e,t,r){var n,i;n=this,i=function(){var c,r,e,t,n,l,i,s,o,a,f,u,h=h||(c=Math,r=Object.create||function(){function r(){}return function(e){var t;return r.prototype=e,t=new r,r.prototype=null,t}}(),t=(e={}).lib={},n=t.Base={extend:function(e){var t=r(this);return e&&t.mixIn(e),t.hasOwnProperty("init")&&this.init!==t.init||(t.init=function(){t.$super.init.apply(this,arguments)}),(t.init.prototype=t).$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},l=t.WordArray=n.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||s).stringify(this)},concat:function(e){var t=this.words,r=e.words,n=this.sigBytes,i=e.sigBytes;if(this.clamp(),n%4)for(var s=0;s>>2]>>>24-s%4*8&255;t[n+s>>>2]|=o<<24-(n+s)%4*8}else for(s=0;s>>2]=r[s>>>2];return this.sigBytes+=i,this},clamp:function(){var e=this.words,t=this.sigBytes;e[t>>>2]&=4294967295<<32-t%4*8,e.length=c.ceil(t/4)},clone:function(){var e=n.clone.call(this);return e.words=this.words.slice(0),e},random:function(e){for(var t,r=[],n=function(t){t=t;var r=987654321,n=4294967295;return function(){var e=((r=36969*(65535&r)+(r>>16)&n)<<16)+(t=18e3*(65535&t)+(t>>16)&n)&n;return e/=4294967296,(e+=.5)*(.5>>2]>>>24-i%4*8&255;n.push((s>>>4).toString(16)),n.push((15&s).toString(16))}return n.join("")},parse:function(e){for(var t=e.length,r=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new l.init(r,t/2)}},o=i.Latin1={stringify:function(e){for(var t=e.words,r=e.sigBytes,n=[],i=0;i>>2]>>>24-i%4*8&255;n.push(String.fromCharCode(s))}return n.join("")},parse:function(e){for(var t=e.length,r=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new l.init(r,t)}},a=i.Utf8={stringify:function(e){try{return decodeURIComponent(escape(o.stringify(e)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(e){return o.parse(unescape(encodeURIComponent(e)))}},f=t.BufferedBlockAlgorithm=n.extend({reset:function(){this._data=new l.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=a.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(e){var t=this._data,r=t.words,n=t.sigBytes,i=this.blockSize,s=n/(4*i),o=(s=e?c.ceil(s):c.max((0|s)-this._minBufferSize,0))*i,a=c.min(4*o,n);if(o){for(var f=0;f>>2]>>>24-s%4*8&255)<<16|(t[s+1>>>2]>>>24-(s+1)%4*8&255)<<8|t[s+2>>>2]>>>24-(s+2)%4*8&255,a=0;a<4&&s+.75*a>>6*(3-a)&63));var f=n.charAt(64);if(f)for(;i.length%4;)i.push(f);return i.join("")},parse:function(e){var t=e.length,r=this._map,n=this._reverseMap;if(!n){n=this._reverseMap=[];for(var i=0;i>>6-s%4*2;n[i>>>2]|=(o|a)<<24-i%4*8,i++}return f.create(n,i)}(e,t,n)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},e.enc.Base64},"object"==typeof r?t.exports=r=i(e("./core")):i(n.CryptoJS)},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/enc-hex.js":[function(e,t,r){var n,i;n=this,i=function(e){return e.enc.Hex},"object"==typeof r?t.exports=r=i(e("./core")):i(n.CryptoJS)},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/evpkdf.js":[function(e,t,r){var n,i;n=this,i=function(e){var t,r,n,c,i,s,o;return r=(t=e).lib,n=r.Base,c=r.WordArray,i=t.algo,s=i.MD5,o=i.EvpKDF=n.extend({cfg:n.extend({keySize:4,hasher:s,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var r=this.cfg,n=r.hasher.create(),i=c.create(),s=i.words,o=r.keySize,a=r.iterations;s.lengthn&&(t=e.finalize(t)),t.clamp();for(var i=this._oKey=t.clone(),s=this._iKey=t.clone(),o=i.words,a=s.words,f=0;f>>24)|4278255360&(i<<24|i>>>8)}var s=this._hash.words,o=e[t+0],a=e[t+1],f=e[t+2],u=e[t+3],c=e[t+4],l=e[t+5],h=e[t+6],d=e[t+7],p=e[t+8],m=e[t+9],y=e[t+10],b=e[t+11],_=e[t+12],g=e[t+13],w=e[t+14],v=e[t+15],j=s[0],E=s[1],B=s[2],x=s[3];E=S(E=S(E=S(E=S(E=T(E=T(E=T(E=T(E=D(E=D(E=D(E=D(E=k(E=k(E=k(E=k(E,B=k(B,x=k(x,j=k(j,E,B,x,o,7,U[0]),E,B,a,12,U[1]),j,E,f,17,U[2]),x,j,u,22,U[3]),B=k(B,x=k(x,j=k(j,E,B,x,c,7,U[4]),E,B,l,12,U[5]),j,E,h,17,U[6]),x,j,d,22,U[7]),B=k(B,x=k(x,j=k(j,E,B,x,p,7,U[8]),E,B,m,12,U[9]),j,E,y,17,U[10]),x,j,b,22,U[11]),B=k(B,x=k(x,j=k(j,E,B,x,_,7,U[12]),E,B,g,12,U[13]),j,E,w,17,U[14]),x,j,v,22,U[15]),B=D(B,x=D(x,j=D(j,E,B,x,a,5,U[16]),E,B,h,9,U[17]),j,E,b,14,U[18]),x,j,o,20,U[19]),B=D(B,x=D(x,j=D(j,E,B,x,l,5,U[20]),E,B,y,9,U[21]),j,E,v,14,U[22]),x,j,c,20,U[23]),B=D(B,x=D(x,j=D(j,E,B,x,m,5,U[24]),E,B,w,9,U[25]),j,E,u,14,U[26]),x,j,p,20,U[27]),B=D(B,x=D(x,j=D(j,E,B,x,g,5,U[28]),E,B,f,9,U[29]),j,E,d,14,U[30]),x,j,_,20,U[31]),B=T(B,x=T(x,j=T(j,E,B,x,l,4,U[32]),E,B,p,11,U[33]),j,E,b,16,U[34]),x,j,w,23,U[35]),B=T(B,x=T(x,j=T(j,E,B,x,a,4,U[36]),E,B,c,11,U[37]),j,E,d,16,U[38]),x,j,y,23,U[39]),B=T(B,x=T(x,j=T(j,E,B,x,g,4,U[40]),E,B,o,11,U[41]),j,E,u,16,U[42]),x,j,h,23,U[43]),B=T(B,x=T(x,j=T(j,E,B,x,m,4,U[44]),E,B,_,11,U[45]),j,E,v,16,U[46]),x,j,f,23,U[47]),B=S(B,x=S(x,j=S(j,E,B,x,o,6,U[48]),E,B,d,10,U[49]),j,E,w,15,U[50]),x,j,l,21,U[51]),B=S(B,x=S(x,j=S(j,E,B,x,_,6,U[52]),E,B,u,10,U[53]),j,E,y,15,U[54]),x,j,a,21,U[55]),B=S(B,x=S(x,j=S(j,E,B,x,p,6,U[56]),E,B,v,10,U[57]),j,E,h,15,U[58]),x,j,g,21,U[59]),B=S(B,x=S(x,j=S(j,E,B,x,c,6,U[60]),E,B,b,10,U[61]),j,E,f,15,U[62]),x,j,m,21,U[63]),s[0]=s[0]+j|0,s[1]=s[1]+E|0,s[2]=s[2]+B|0,s[3]=s[3]+x|0},_doFinalize:function(){var e=this._data,t=e.words,r=8*this._nDataBytes,n=8*e.sigBytes;t[n>>>5]|=128<<24-n%32;var i=c.floor(r/4294967296),s=r;t[15+(n+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),t[14+(n+64>>>9<<4)]=16711935&(s<<8|s>>>24)|4278255360&(s<<24|s>>>8),e.sigBytes=4*(t.length+1),this._process();for(var o=this._hash,a=o.words,f=0;f<4;f++){var u=a[f];a[f]=16711935&(u<<8|u>>>24)|4278255360&(u<<24|u>>>8)}return o},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});function k(e,t,r,n,i,s,o){var a=e+(t&r|~t&n)+i+o;return(a<>>32-s)+t}function D(e,t,r,n,i,s,o){var a=e+(t&n|r&~n)+i+o;return(a<>>32-s)+t}function T(e,t,r,n,i,s,o){var a=e+(t^r^n)+i+o;return(a<>>32-s)+t}function S(e,t,r,n,i,s,o){var a=e+(r^(t|~n))+i+o;return(a<>>32-s)+t}e.MD5=n._createHelper(s),e.HmacMD5=n._createHmacHelper(s)}(Math),o.MD5},"object"==typeof r?t.exports=r=i(e("./core")):i(n.CryptoJS)},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/sha1.js":[function(e,t,r){var n,i;n=this,i=function(e){var t,r,n,i,s,l,o;return r=(t=e).lib,n=r.WordArray,i=r.Hasher,s=t.algo,l=[],o=s.SHA1=i.extend({_doReset:function(){this._hash=new n.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(e,t){for(var r=this._hash.words,n=r[0],i=r[1],s=r[2],o=r[3],a=r[4],f=0;f<80;f++){if(f<16)l[f]=0|e[t+f];else{var u=l[f-3]^l[f-8]^l[f-14]^l[f-16];l[f]=u<<1|u>>>31}var c=(n<<5|n>>>27)+a+l[f];c+=f<20?1518500249+(i&s|~i&o):f<40?1859775393+(i^s^o):f<60?(i&s|i&o|s&o)-1894007588:(i^s^o)-899497514,a=o,o=s,s=i<<30|i>>>2,i=n,n=c}r[0]=r[0]+n|0,r[1]=r[1]+i|0,r[2]=r[2]+s|0,r[3]=r[3]+o|0,r[4]=r[4]+a|0},_doFinalize:function(){var e=this._data,t=e.words,r=8*this._nDataBytes,n=8*e.sigBytes;return t[n>>>5]|=128<<24-n%32,t[14+(n+64>>>9<<4)]=Math.floor(r/4294967296),t[15+(n+64>>>9<<4)]=r,e.sigBytes=4*t.length,this._process(),this._hash},clone:function(){var e=i.clone.call(this);return e._hash=this._hash.clone(),e}}),t.SHA1=i._createHelper(o),t.HmacSHA1=i._createHmacHelper(o),e.SHA1},"object"==typeof r?t.exports=r=i(e("./core")):i(n.CryptoJS)},{"./core":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/crypto-js/core.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/deep-equal/index.js":[function(e,t,r){var a=Array.prototype.slice,f=e("./lib/keys.js"),u=e("./lib/is_arguments.js"),c=t.exports=function(e,t,r){return r||(r={}),e===t||(e instanceof Date&&t instanceof Date?e.getTime()===t.getTime():!e||!t||"object"!=typeof e&&"object"!=typeof t?r.strict?e===t:e==t:function(e,t,r){var n,i;if(l(e)||l(t))return!1;if(e.prototype!==t.prototype)return!1;if(u(e))return!!u(t)&&(e=a.call(e),t=a.call(t),c(e,t,r));if(h(e)){if(!h(t))return!1;if(e.length!==t.length)return!1;for(n=0;nr&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},n.prototype.once=function(e,t){if(!f(t))throw TypeError("listener must be a function");var r=!1;function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}return n.listener=t,this.on(e,n),this},n.prototype.removeListener=function(e,t){var r,n,i,s;if(!f(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(i=(r=this._events[e]).length,n=-1,r===t||f(r.listener)&&r.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(u(r)){for(s=i;0=this._blockSize;){for(var i=this._blockOffset;i>1,c=-7,l=r?i-1:0,h=r?-1:1,d=e[t+l];for(l+=h,s=d&(1<<-c)-1,d>>=-c,c+=a;0>=-c,c+=n;0>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,d=n?0:s-1,p=n?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-o))<1&&(o--,f*=2),2<=(t+=1<=o+l?h/f:h*Math.pow(2,1-l))*f&&(o++,f/=2),c<=o+l?(a=0,o=c):1<=o+l?(a=(t*f-1)*Math.pow(2,i),o+=l):(a=t*Math.pow(2,l-1)*Math.pow(2,i),o=0));8<=i;e[r+d]=255&a,d+=p,a/=256,i-=8);for(o=o<>>=0)&&e<256)&&(n=o[e])?n:(r=m(e,(0|e)<0?-1:0,!0),i&&(o[e]=r),r):(i=-128<=(e|=0)&&e<128)&&(n=s[e])?n:(r=m(e,e<0?-1:0,!1),i&&(s[e]=r),r)}function p(e,t){if(isNaN(e)||!isFinite(e))return t?f:_;if(t){if(e<0)return f;if(i<=e)return v}else{if(e<=-a)return j;if(a<=e+1)return w}return e<0?p(-e,t).neg():m(e%r|0,e/r|0,t)}function m(e,t,r){return new n(e,t,r)}n.fromInt=e,n.fromNumber=p,n.fromBits=m;var c=Math.pow;function l(e,t,r){if(0===e.length)throw Error("empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return _;if(t="number"==typeof t?(r=t,!1):!!t,(r=r||10)<2||36>>0:this.low},t.toNumber=function(){return this.unsigned?(this.high>>>0)*r+(this.low>>>0):this.high*r+(this.low>>>0)},t.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((s=a).isZero())return f+o;for(;f.length<6;)f="0"+f;o=""+f+o}},t.getHighBits=function(){return this.high},t.getHighBitsUnsigned=function(){return this.high>>>0},t.getLowBits=function(){return this.low},t.getLowBitsUnsigned=function(){return this.low>>>0},t.getNumBitsAbs=function(){if(this.isNegative())return this.eq(j)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;0>>31!=1||e.high>>>31!=1)&&(this.high===e.high&&this.low===e.low)},t.eq=t.equals,t.notEquals=function(e){return!this.eq(e)},t.neq=t.notEquals,t.lessThan=function(e){return this.comp(e)<0},t.lt=t.lessThan,t.lessThanOrEqual=function(e){return this.comp(e)<=0},t.lte=t.lessThanOrEqual,t.greaterThan=function(e){return 0>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},t.comp=t.compare,t.negate=function(){return!this.unsigned&&this.eq(j)?j:this.not().add(u)},t.neg=t.negate,t.add=function(e){d(e)||(e=y(e));var t=this.high>>>16,r=65535&this.high,n=this.low>>>16,i=65535&this.low,s=e.high>>>16,o=65535&e.high,a=e.low>>>16,f=0,u=0,c=0,l=0;return c+=(l+=i+(65535&e.low))>>>16,u+=(c+=n+a)>>>16,f+=(u+=r+o)>>>16,f+=t+s,m((c&=65535)<<16|(l&=65535),(f&=65535)<<16|(u&=65535),this.unsigned)},t.subtract=function(e){return d(e)||(e=y(e)),this.add(e.neg())},t.sub=t.subtract,t.multiply=function(e){if(this.isZero())return _;if(d(e)||(e=y(e)),e.isZero())return _;if(this.eq(j))return e.isOdd()?j:_;if(e.eq(j))return this.isOdd()?j:_;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(b)&&e.lt(b))return p(this.toNumber()*e.toNumber(),this.unsigned);var t=this.high>>>16,r=65535&this.high,n=this.low>>>16,i=65535&this.low,s=e.high>>>16,o=65535&e.high,a=e.low>>>16,f=65535&e.low,u=0,c=0,l=0,h=0;return l+=(h+=i*f)>>>16,c+=(l+=n*f)>>>16,l&=65535,c+=(l+=i*a)>>>16,u+=(c+=r*f)>>>16,c&=65535,u+=(c+=n*a)>>>16,c&=65535,u+=(c+=i*o)>>>16,u+=t*f+r*a+n*o+i*s,m((l&=65535)<<16|(h&=65535),(u&=65535)<<16|(c&=65535),this.unsigned)},t.mul=t.multiply,t.divide=function(e){if(d(e)||(e=y(e)),e.isZero())throw Error("division by zero");if(this.isZero())return this.unsigned?f:_;var t,r,n;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return f;if(e.gt(this.shru(1)))return h;n=f}else{if(this.eq(j))return e.eq(u)||e.eq(g)?j:e.eq(j)?u:(t=this.shr(1).div(e).shl(1)).eq(_)?e.isNegative()?u:g:(r=this.sub(e.mul(t)),n=t.add(r.div(e)));else if(e.eq(j))return this.unsigned?f:_;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();n=_}for(r=this;r.gte(e);){t=Math.max(1,Math.floor(r.toNumber()/e.toNumber()));for(var i=Math.ceil(Math.log(t)/Math.LN2),s=i<=48?1:c(2,i-48),o=p(t),a=o.mul(e);a.isNegative()||a.gt(r);)a=(o=p(t-=s,this.unsigned)).mul(e);o.isZero()&&(o=u),n=n.add(o),r=r.sub(a)}return n},t.div=t.divide,t.modulo=function(e){return d(e)||(e=y(e)),this.sub(this.div(e).mul(e))},t.mod=t.modulo,t.not=function(){return m(~this.low,~this.high,this.unsigned)},t.and=function(e){return d(e)||(e=y(e)),m(this.low&e.low,this.high&e.high,this.unsigned)},t.or=function(e){return d(e)||(e=y(e)),m(this.low|e.low,this.high|e.high,this.unsigned)},t.xor=function(e){return d(e)||(e=y(e)),m(this.low^e.low,this.high^e.high,this.unsigned)},t.shiftLeft=function(e){return d(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?m(this.low<>>32-e,this.unsigned):m(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):m(this.high>>e-32,0<=this.high?0:-1,this.unsigned)},t.shr=t.shiftRight,t.shiftRightUnsigned=function(e){if(d(e)&&(e=e.toInt()),0===(e&=63))return this;var t=this.high;return e<32?m(this.low>>>e|t<<32-e,t>>>e,this.unsigned):m(32===e?t:t>>>e-32,0,this.unsigned)},t.shru=t.shiftRightUnsigned,t.toSigned=function(){return this.unsigned?m(this.low,this.high,!1):this},t.toUnsigned=function(){return this.unsigned?this:m(this.low,this.high,!0)},t.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},t.toBytesLE=function(){var e=this.high,t=this.low;return[255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255]},t.toBytesBE=function(){var e=this.high,t=this.low;return[e>>>24&255,e>>>16&255,e>>>8&255,255&e,t>>>24&255,t>>>16&255,t>>>8&255,255&t]},n},"function"==typeof e&&"object"==typeof t&&t&&t.exports?t.exports=i():(n.dcodeIO=n.dcodeIO||{}).Long=i()},{}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/md5.js/index.js":[function(i,s,e){(function(t){"use strict";var e=i("inherits"),r=i("hash-base"),o=new Array(16);function n(){r.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878}function a(e,t){return e<>>32-t}function f(e,t,r,n,i,s,o){return a(e+(t&r|~t&n)+i+s|0,o)+t|0}function u(e,t,r,n,i,s,o){return a(e+(t&n|r&~n)+i+s|0,o)+t|0}function c(e,t,r,n,i,s,o){return a(e+(t^r^n)+i+s|0,o)+t|0}function l(e,t,r,n,i,s,o){return a(e+(r^(t|~n))+i+s|0,o)+t|0}e(n,r),n.prototype._update=function(){for(var e=o,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);var r=this._a,n=this._b,i=this._c,s=this._d;n=l(n=l(n=l(n=l(n=c(n=c(n=c(n=c(n=u(n=u(n=u(n=u(n=f(n=f(n=f(n=f(n,i=f(i,s=f(s,r=f(r,n,i,s,e[0],3614090360,7),n,i,e[1],3905402710,12),r,n,e[2],606105819,17),s,r,e[3],3250441966,22),i=f(i,s=f(s,r=f(r,n,i,s,e[4],4118548399,7),n,i,e[5],1200080426,12),r,n,e[6],2821735955,17),s,r,e[7],4249261313,22),i=f(i,s=f(s,r=f(r,n,i,s,e[8],1770035416,7),n,i,e[9],2336552879,12),r,n,e[10],4294925233,17),s,r,e[11],2304563134,22),i=f(i,s=f(s,r=f(r,n,i,s,e[12],1804603682,7),n,i,e[13],4254626195,12),r,n,e[14],2792965006,17),s,r,e[15],1236535329,22),i=u(i,s=u(s,r=u(r,n,i,s,e[1],4129170786,5),n,i,e[6],3225465664,9),r,n,e[11],643717713,14),s,r,e[0],3921069994,20),i=u(i,s=u(s,r=u(r,n,i,s,e[5],3593408605,5),n,i,e[10],38016083,9),r,n,e[15],3634488961,14),s,r,e[4],3889429448,20),i=u(i,s=u(s,r=u(r,n,i,s,e[9],568446438,5),n,i,e[14],3275163606,9),r,n,e[3],4107603335,14),s,r,e[8],1163531501,20),i=u(i,s=u(s,r=u(r,n,i,s,e[13],2850285829,5),n,i,e[2],4243563512,9),r,n,e[7],1735328473,14),s,r,e[12],2368359562,20),i=c(i,s=c(s,r=c(r,n,i,s,e[5],4294588738,4),n,i,e[8],2272392833,11),r,n,e[11],1839030562,16),s,r,e[14],4259657740,23),i=c(i,s=c(s,r=c(r,n,i,s,e[1],2763975236,4),n,i,e[4],1272893353,11),r,n,e[7],4139469664,16),s,r,e[10],3200236656,23),i=c(i,s=c(s,r=c(r,n,i,s,e[13],681279174,4),n,i,e[0],3936430074,11),r,n,e[3],3572445317,16),s,r,e[6],76029189,23),i=c(i,s=c(s,r=c(r,n,i,s,e[9],3654602809,4),n,i,e[12],3873151461,11),r,n,e[15],530742520,16),s,r,e[2],3299628645,23),i=l(i,s=l(s,r=l(r,n,i,s,e[0],4096336452,6),n,i,e[7],1126891415,10),r,n,e[14],2878612391,15),s,r,e[5],4237533241,21),i=l(i,s=l(s,r=l(r,n,i,s,e[12],1700485571,6),n,i,e[3],2399980690,10),r,n,e[10],4293915773,15),s,r,e[1],2240044497,21),i=l(i,s=l(s,r=l(r,n,i,s,e[8],1873313359,6),n,i,e[15],4264355552,10),r,n,e[6],2734768916,15),s,r,e[13],1309151649,21),i=l(i,s=l(s,r=l(r,n,i,s,e[4],4149444226,6),n,i,e[11],3174756917,10),r,n,e[2],718787259,15),s,r,e[9],3951481745,21),this._a=this._a+r|0,this._b=this._b+n|0,this._c=this._c+i|0,this._d=this._d+s|0},n.prototype._digest=function(){this._block[this._blockOffset++]=128,56this.urls.length-1)return t(new Error("Tried "+(i+1)+" connections, none of which worked: "+JSON.stringify(this.urls.concat(this.url))));var o=function(e,t){return s.logFailure(n),s.connectWithFallback(r,s.urls[i],i+1,e,t)};return e&&t?this.connect(r,n).then(e).catch(function(){o(e,t)}):new Promise(function(e,t){s.connect(r).then(e).catch(function(){o(e,t)})})},n.prototype.checkConnections=function(){var i=0t.highWaterMark&&(t.highWaterMark=(m<=(r=e)?r=m:(r--,r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r++),r)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0));var r}function j(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(w("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?b.nextTick(E,e):E(e))}function E(e){w("emit readable"),e.emit("readable"),D(e)}function B(e,t){t.readingMore||(t.readingMore=!0,b.nextTick(x,e,t))}function x(e,t){for(var r=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):r=function(e,t,r){var n;es.length?s.length:e;if(o===s.length?i+=s:i+=s.slice(0,e),0===(e-=o)){o===s.length?(++n,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r).data=s.slice(o);break}++n}return t.length-=n,i}(e,t):function(e,t){var r=u.allocUnsafe(e),n=t.head,i=1;n.data.copy(r),e-=n.data.length;for(;n=n.next;){var s=n.data,o=e>s.length?s.length:e;if(s.copy(r,r.length-e,0,o),0===(e-=o)){o===s.length?(++i,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n).data=s.slice(o);break}++i}return t.length-=i,r}(e,t);return n}(e,t.buffer,t.decoder),r);var r}function S(e){var t=e._readableState;if(0=t.highWaterMark||t.ended))return w("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?S(this):j(this),null;if(0===(e=v(e,t))&&t.ended)return 0===t.length&&S(this),null;var n,i=t.needReadable;return w("need readable",i),(0===t.length||t.length-e>>0),s=this.head,o=0;s;)t=s.data,r=i,n=o,t.copy(r,n),o+=s.data.length,s=s.next;return i},e}(),n&&n.inspect&&n.inspect.custom&&(t.exports.prototype[n.inspect.custom]=function(){var e=n.inspect({length:this.length});return this.constructor.name+" "+e})},{"safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js",util:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/browser-resolve/empty.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/destroy.js":[function(e,t,r){"use strict";var s=e("process-nextick-args");function o(e,t){e.emit("error",t)}t.exports={destroy:function(e,t){var r=this,n=this._readableState&&this._readableState.destroyed,i=this._writableState&&this._writableState.destroyed;return n||i?t?t(e):!e||this._writableState&&this._writableState.errorEmitted||s.nextTick(o,this,e):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(s.nextTick(o,r,e),r._writableState&&(r._writableState.errorEmitted=!0)):t&&t(e)})),this},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},{"process-nextick-args":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/process-nextick-args/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/internal/streams/stream-browser.js":[function(e,t,r){t.exports=e("events").EventEmitter},{events:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/events/events.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/passthrough.js":[function(e,t,r){t.exports=e("./readable").PassThrough},{"./readable":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/readable-browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/readable-browser.js":[function(e,t,r){(((r=t.exports=e("./lib/_stream_readable.js")).Stream=r).Readable=r).Writable=e("./lib/_stream_writable.js"),r.Duplex=e("./lib/_stream_duplex.js"),r.Transform=e("./lib/_stream_transform.js"),r.PassThrough=e("./lib/_stream_passthrough.js")},{"./lib/_stream_duplex.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_duplex.js","./lib/_stream_passthrough.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_passthrough.js","./lib/_stream_readable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_readable.js","./lib/_stream_transform.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_transform.js","./lib/_stream_writable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_writable.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/transform.js":[function(e,t,r){t.exports=e("./readable").Transform},{"./readable":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/readable-browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/writable-browser.js":[function(e,t,r){t.exports=e("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/lib/_stream_writable.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/ripemd160/index.js":[function(e,t,r){"use strict";var n=e("buffer").Buffer,i=e("inherits"),s=e("hash-base"),y=new Array(16),b=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],_=[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11],g=[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],w=[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11],v=[0,1518500249,1859775393,2400959708,2840853838],j=[1352829926,1548603684,1836072691,2053994217,0];function o(){s.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520}function E(e,t){return e<>>32-t}function B(e,t,r,n,i,s,o,a){return E(e+(t^r^n)+s+o|0,a)+i|0}function x(e,t,r,n,i,s,o,a){return E(e+(t&r|~t&n)+s+o|0,a)+i|0}function U(e,t,r,n,i,s,o,a){return E(e+((t|~r)^n)+s+o|0,a)+i|0}function k(e,t,r,n,i,s,o,a){return E(e+(t&n|r&~n)+s+o|0,a)+i|0}function D(e,t,r,n,i,s,o,a){return E(e+(t^(r|~n))+s+o|0,a)+i|0}i(o,s),o.prototype._update=function(){for(var e=y,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);for(var r=0|this._a,n=0|this._b,i=0|this._c,s=0|this._d,o=0|this._e,a=0|this._a,f=0|this._b,u=0|this._c,c=0|this._d,l=0|this._e,h=0;h<80;h+=1){var d,p;p=h<16?(d=B(r,n,i,s,o,e[b[h]],v[0],g[h]),D(a,f,u,c,l,e[_[h]],j[0],w[h])):h<32?(d=x(r,n,i,s,o,e[b[h]],v[1],g[h]),k(a,f,u,c,l,e[_[h]],j[1],w[h])):h<48?(d=U(r,n,i,s,o,e[b[h]],v[2],g[h]),U(a,f,u,c,l,e[_[h]],j[2],w[h])):h<64?(d=k(r,n,i,s,o,e[b[h]],v[3],g[h]),x(a,f,u,c,l,e[_[h]],j[3],w[h])):(d=D(r,n,i,s,o,e[b[h]],v[4],g[h]),B(a,f,u,c,l,e[_[h]],j[4],w[h])),r=o,o=s,s=E(i,10),i=n,n=d,a=l,l=c,c=E(u,10),u=f,f=p}var m=this._b+i+c|0;this._b=this._c+s+l|0,this._c=this._d+o+a|0,this._d=this._e+r+f|0,this._e=this._a+n+u|0,this._a=m},o.prototype._digest=function(){this._block[this._blockOffset++]=128,56=this._finalSize&&(this._update(this._block),this._block.fill(0));var r=8*this._len;if(r<=4294967295)this._block.writeUInt32BE(r,this._blockSize-4);else{var n=(4294967295&r)>>>0,i=(r-n)/4294967296;this._block.writeUInt32BE(i,this._blockSize-8),this._block.writeUInt32BE(n,this._blockSize-4)}this._update(this._block);var s=this._hash();return e?s.toString(e):s},n.prototype._update=function(){throw new Error("_update must be implemented by subclass")},t.exports=n},{"safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/index.js":[function(e,t,r){(r=t.exports=function(e){e=e.toLowerCase();var t=r[e];if(!t)throw new Error(e+" is not supported (we accept pull requests)");return new t}).sha=e("./sha"),r.sha1=e("./sha1"),r.sha224=e("./sha224"),r.sha256=e("./sha256"),r.sha384=e("./sha384"),r.sha512=e("./sha512")},{"./sha":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha.js","./sha1":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha1.js","./sha224":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha224.js","./sha256":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha256.js","./sha384":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha384.js","./sha512":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha512.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha.js":[function(e,t,r){var n=e("inherits"),i=e("./hash"),s=e("safe-buffer").Buffer,b=[1518500249,1859775393,-1894007588,-899497514],o=new Array(80);function a(){this.init(),this._w=o,i.call(this,64,56)}n(a,i),a.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},a.prototype._update=function(e){for(var t,r,n,i,s,o,a=this._w,f=0|this._a,u=0|this._b,c=0|this._c,l=0|this._d,h=0|this._e,d=0;d<16;++d)a[d]=e.readInt32BE(4*d);for(;d<80;++d)a[d]=a[d-3]^a[d-8]^a[d-14]^a[d-16];for(var p=0;p<80;++p){var m=~~(p/20),y=0|((o=f)<<5|o>>>27)+(n=u,i=c,s=l,0===(r=m)?n&i|~n&s:2===r?n&i|n&s|i&s:n^i^s)+h+a[p]+b[m];h=l,l=c,c=(t=u)<<30|t>>>2,u=f,f=y}this._a=f+this._a|0,this._b=u+this._b|0,this._c=c+this._c|0,this._d=l+this._d|0,this._e=h+this._e|0},a.prototype._hash=function(){var e=s.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},t.exports=a},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js",inherits:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha1.js":[function(e,t,r){var n=e("inherits"),i=e("./hash"),s=e("safe-buffer").Buffer,_=[1518500249,1859775393,-1894007588,-899497514],o=new Array(80);function a(){this.init(),this._w=o,i.call(this,64,56)}n(a,i),a.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},a.prototype._update=function(e){for(var t,r,n,i,s,o,a,f=this._w,u=0|this._a,c=0|this._b,l=0|this._c,h=0|this._d,d=0|this._e,p=0;p<16;++p)f[p]=e.readInt32BE(4*p);for(;p<80;++p)f[p]=(t=f[p-3]^f[p-8]^f[p-14]^f[p-16])<<1|t>>>31;for(var m=0;m<80;++m){var y=~~(m/20),b=0|((a=u)<<5|a>>>27)+(i=c,s=l,o=h,0===(n=y)?i&s|~i&o:2===n?i&s|i&o|s&o:i^s^o)+d+f[m]+_[y];d=h,h=l,l=(r=c)<<30|r>>>2,c=u,u=b}this._a=u+this._a|0,this._b=c+this._b|0,this._c=l+this._c|0,this._d=h+this._d|0,this._e=d+this._e|0},a.prototype._hash=function(){var e=s.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},t.exports=a},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js",inherits:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha224.js":[function(e,t,r){var n=e("inherits"),i=e("./sha256"),s=e("./hash"),o=e("safe-buffer").Buffer,a=new Array(64);function f(){this.init(),this._w=a,s.call(this,64,56)}n(f,i),f.prototype.init=function(){return this._a=3238371032,this._b=914150663,this._c=812702999,this._d=4144912697,this._e=4290775857,this._f=1750603025,this._g=1694076839,this._h=3204075428,this},f.prototype._hash=function(){var e=o.allocUnsafe(28);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e},t.exports=f},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js","./sha256":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha256.js",inherits:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha256.js":[function(e,t,r){var n=e("inherits"),i=e("./hash"),s=e("safe-buffer").Buffer,v=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],o=new Array(64);function a(){this.init(),this._w=o,i.call(this,64,56)}n(a,i),a.prototype.init=function(){return this._a=1779033703,this._b=3144134277,this._c=1013904242,this._d=2773480762,this._e=1359893119,this._f=2600822924,this._g=528734635,this._h=1541459225,this},a.prototype._update=function(e){for(var t,r,n,i,s,o,a,f=this._w,u=0|this._a,c=0|this._b,l=0|this._c,h=0|this._d,d=0|this._e,p=0|this._f,m=0|this._g,y=0|this._h,b=0;b<16;++b)f[b]=e.readInt32BE(4*b);for(;b<64;++b)f[b]=0|(((r=f[b-2])>>>17|r<<15)^(r>>>19|r<<13)^r>>>10)+f[b-7]+(((t=f[b-15])>>>7|t<<25)^(t>>>18|t<<14)^t>>>3)+f[b-16];for(var _=0;_<64;++_){var g=y+(((a=d)>>>6|a<<26)^(a>>>11|a<<21)^(a>>>25|a<<7))+((o=m)^d&(p^o))+v[_]+f[_]|0,w=0|(((s=u)>>>2|s<<30)^(s>>>13|s<<19)^(s>>>22|s<<10))+((n=u)&(i=c)|l&(n|i));y=m,m=p,p=d,d=h+g|0,h=l,l=c,c=u,u=g+w|0}this._a=u+this._a|0,this._b=c+this._b|0,this._c=l+this._c|0,this._d=h+this._d|0,this._e=d+this._e|0,this._f=p+this._f|0,this._g=m+this._g|0,this._h=y+this._h|0},a.prototype._hash=function(){var e=s.allocUnsafe(32);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e.writeInt32BE(this._h,28),e},t.exports=a},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js",inherits:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha384.js":[function(e,t,r){var n=e("inherits"),i=e("./sha512"),s=e("./hash"),o=e("safe-buffer").Buffer,a=new Array(160);function f(){this.init(),this._w=a,s.call(this,128,112)}n(f,i),f.prototype.init=function(){return this._ah=3418070365,this._bh=1654270250,this._ch=2438529370,this._dh=355462360,this._eh=1731405415,this._fh=2394180231,this._gh=3675008525,this._hh=1203062813,this._al=3238371032,this._bl=914150663,this._cl=812702999,this._dl=4144912697,this._el=4290775857,this._fl=1750603025,this._gl=1694076839,this._hl=3204075428,this},f.prototype._hash=function(){var n=o.allocUnsafe(48);function e(e,t,r){n.writeInt32BE(e,r),n.writeInt32BE(t,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),n},t.exports=f},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js","./sha512":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha512.js",inherits:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/sha512.js":[function(e,t,r){var n=e("inherits"),i=e("./hash"),s=e("safe-buffer").Buffer,ee=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591],o=new Array(160);function a(){this.init(),this._w=o,i.call(this,128,112)}function te(e,t,r){return r^e&(t^r)}function re(e,t,r){return e&t|r&(e|t)}function ne(e,t){return(e>>>28|t<<4)^(t>>>2|e<<30)^(t>>>7|e<<25)}function ie(e,t){return(e>>>14|t<<18)^(e>>>18|t<<14)^(t>>>9|e<<23)}function se(e,t){return e>>>0>>0?1:0}n(a,i),a.prototype.init=function(){return this._ah=1779033703,this._bh=3144134277,this._ch=1013904242,this._dh=2773480762,this._eh=1359893119,this._fh=2600822924,this._gh=528734635,this._hh=1541459225,this._al=4089235720,this._bl=2227873595,this._cl=4271175723,this._dl=1595750129,this._el=2917565137,this._fl=725511199,this._gl=4215389547,this._hl=327033209,this},a.prototype._update=function(e){for(var t,r,n,i,s,o,a,f,u=this._w,c=0|this._ah,l=0|this._bh,h=0|this._ch,d=0|this._dh,p=0|this._eh,m=0|this._fh,y=0|this._gh,b=0|this._hh,_=0|this._al,g=0|this._bl,w=0|this._cl,v=0|this._dl,j=0|this._el,E=0|this._fl,B=0|this._gl,x=0|this._hl,U=0;U<32;U+=2)u[U]=e.readInt32BE(4*U),u[U+1]=e.readInt32BE(4*U+4);for(;U<160;U+=2){var k=u[U-30],D=u[U-30+1],T=((a=k)>>>1|(f=D)<<31)^(a>>>8|f<<24)^a>>>7,S=((s=D)>>>1|(o=k)<<31)^(s>>>8|o<<24)^(s>>>7|o<<25);k=u[U-4],D=u[U-4+1];var I=((n=k)>>>19|(i=D)<<13)^(i>>>29|n<<3)^n>>>6,A=((t=D)>>>19|(r=k)<<13)^(r>>>29|t<<3)^(t>>>6|r<<26),O=u[U-14],L=u[U-14+1],C=u[U-32],R=u[U-32+1],P=S+L|0,q=T+O+se(P,S)|0;q=(q=q+I+se(P=P+A|0,A)|0)+C+se(P=P+R|0,R)|0,u[U]=q,u[U+1]=P}for(var M=0;M<160;M+=2){q=u[M],P=u[M+1];var z=re(c,l,h),N=re(_,g,w),F=ne(c,_),K=ne(_,c),H=ie(p,j),V=ie(j,p),Y=ee[M],W=ee[M+1],Z=te(p,m,y),G=te(j,E,B),J=x+V|0,X=b+H+se(J,x)|0;X=(X=(X=X+Z+se(J=J+G|0,G)|0)+Y+se(J=J+W|0,W)|0)+q+se(J=J+P|0,P)|0;var $=K+N|0,Q=F+z+se($,K)|0;b=y,x=B,y=m,B=E,m=p,E=j,p=d+X+se(j=v+J|0,v)|0,d=h,v=w,h=l,w=g,l=c,g=_,c=X+Q+se(_=J+$|0,J)|0}this._al=this._al+_|0,this._bl=this._bl+g|0,this._cl=this._cl+w|0,this._dl=this._dl+v|0,this._el=this._el+j|0,this._fl=this._fl+E|0,this._gl=this._gl+B|0,this._hl=this._hl+x|0,this._ah=this._ah+c+se(this._al,_)|0,this._bh=this._bh+l+se(this._bl,g)|0,this._ch=this._ch+h+se(this._cl,w)|0,this._dh=this._dh+d+se(this._dl,v)|0,this._eh=this._eh+p+se(this._el,j)|0,this._fh=this._fh+m+se(this._fl,E)|0,this._gh=this._gh+y+se(this._gl,B)|0,this._hh=this._hh+b+se(this._hl,x)|0},a.prototype._hash=function(){var n=s.allocUnsafe(64);function e(e,t,r){n.writeInt32BE(e,r),n.writeInt32BE(t,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),e(this._gh,this._gl,48),e(this._hh,this._hl,56),n},t.exports=a},{"./hash":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/sha.js/hash.js",inherits:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","safe-buffer":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/safe-buffer/index.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/stream-browserify/index.js":[function(e,t,r){t.exports=n;var c=e("events").EventEmitter;function n(){c.call(this)}e("inherits")(n,c),n.Readable=e("readable-stream/readable.js"),n.Writable=e("readable-stream/writable.js"),n.Duplex=e("readable-stream/duplex.js"),n.Transform=e("readable-stream/transform.js"),n.PassThrough=e("readable-stream/passthrough.js"),(n.Stream=n).prototype.pipe=function(t,e){var r=this;function n(e){t.writable&&!1===t.write(e)&&r.pause&&r.pause()}function i(){r.readable&&r.resume&&r.resume()}r.on("data",n),t.on("drain",i),t._isStdio||e&&!1===e.end||(r.on("end",o),r.on("close",a));var s=!1;function o(){s||(s=!0,t.end())}function a(){s||(s=!0,"function"==typeof t.destroy&&t.destroy())}function f(e){if(u(),0===c.listenerCount(this,"error"))throw e}function u(){r.removeListener("data",n),t.removeListener("drain",i),r.removeListener("end",o),r.removeListener("close",a),r.removeListener("error",f),t.removeListener("error",f),r.removeListener("end",u),r.removeListener("close",u),t.removeListener("close",u)}return r.on("error",f),t.on("error",f),r.on("end",u),r.on("close",u),t.on("close",u),t.emit("pipe",r),t}},{events:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/events/events.js",inherits:"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/inherits/inherits_browser.js","readable-stream/duplex.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/duplex-browser.js","readable-stream/passthrough.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/passthrough.js","readable-stream/readable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/readable-browser.js","readable-stream/transform.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/transform.js","readable-stream/writable.js":"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/readable-stream/writable-browser.js"}],"/Users/mseaward/Documents/code/peerplaysjs-lib/node_modules/string_decoder/lib/string_decoder.js":[function(e,t,r){"use strict";var n=e("safe-buffer").Buffer,i=n.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function s(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(n.isEncoding===i||!i(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=f,this.end=u,t=4;break;case"utf8":this.fillLast=a,t=4;break;case"base64":this.text=c,this.end=l,t=3;break;default:return this.write=h,void(this.end=d)}this.lastNeed=0,this.lastTotal=0,this.lastChar=n.allocUnsafe(t)}function o(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function a(e){var t=this.lastTotal-this.lastNeed,r=function(e,t,r){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(1=1.1.13-1 <1.2.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, - "combine-source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.6.1.tgz", - "integrity": "sha1-m0oJwxYDPXaODxHgKfonMOB5rZY=", - "dev": true, - "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.5.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.4.2" - } - }, - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", - "dev": true - }, - "inline-source-map": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.5.0.tgz", - "integrity": "sha1-Skxd2OT7Xps82mDIIt+tyu5m4K8=", - "dev": true, - "requires": { - "source-map": "~0.4.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, "bytebuffer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", @@ -1570,21 +1168,6 @@ "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", "dev": true }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -1605,12 +1188,6 @@ "supports-color": "^2.0.0" } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, "cheerio": { "version": "1.0.0-rc.2", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", @@ -1652,41 +1229,12 @@ "safe-buffer": "^5.0.1" } }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { - "color-name": "1.1.3" - } + "optional": true }, "color-logger": { "version": "0.0.6", @@ -1694,12 +1242,6 @@ "integrity": "sha1-5WJF7ymCJlcRDHy3WpzXhstp7Rs=", "dev": true }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, "combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", @@ -1795,12 +1337,6 @@ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", "dev": true }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, "convert-source-map": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", @@ -1854,17 +1390,6 @@ "sha.js": "^2.4.8" } }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -1885,9 +1410,9 @@ } }, "crypto-js": { - "version": "3.1.9-1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", - "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", + "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=" }, "css-select": { "version": "1.2.0", @@ -1931,12 +1456,6 @@ "es5-ext": "^0.10.9" } }, - "damerau-levenshtein": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz", - "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=", - "dev": true - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -1971,16 +1490,8 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, - "requires": { - "object-keys": "^1.0.12" - } + "optional": true }, "defined": { "version": "1.0.0", @@ -2036,9 +1547,9 @@ } }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", "dev": true }, "diffie-hellman": { @@ -2052,15 +1563,6 @@ "randombytes": "^2.0.0" } }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, "dom-serializer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", @@ -2153,52 +1655,12 @@ "minimalistic-crypto-utils": "^1.0.0" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "entities": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", "dev": true }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "es5-ext": { "version": "0.10.45", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", @@ -2290,314 +1752,6 @@ } } }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "globals": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", - "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", - "dev": true - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "eslint-config-airbnb": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz", - "integrity": "sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw==", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^13.1.0", - "object.assign": "^4.1.0", - "object.entries": "^1.0.4" - } - }, - "eslint-config-airbnb-base": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz", - "integrity": "sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==", - "dev": true, - "requires": { - "eslint-restricted-globals": "^0.1.1", - "object.assign": "^4.1.0", - "object.entries": "^1.0.4" - } - }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" - } - }, - "eslint-module-utils": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz", - "integrity": "sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==", - "dev": true, - "requires": { - "debug": "^2.6.8", - "pkg-dir": "^2.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz", - "integrity": "sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==", - "dev": true, - "requires": { - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.3.0", - "has": "^1.0.3", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "read-pkg-up": "^2.0.0", - "resolve": "^1.9.0" - }, - "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } - }, - "eslint-plugin-jsx-a11y": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.0.tgz", - "integrity": "sha512-KpibpIdKT0nbDG7G/ILWoZoN5G9cj3h1IHARxzvHk5Nt2LQ7oPUutbO9QbT1FKNHLPZB6BaoA1ASSLOiJZVEUQ==", - "dev": true, - "requires": { - "aria-query": "^3.0.0", - "array-includes": "^3.0.3", - "ast-types-flow": "^0.0.7", - "axobject-query": "^2.0.2", - "damerau-levenshtein": "^1.0.4", - "emoji-regex": "^7.0.2", - "has": "^1.0.3", - "jsx-ast-utils": "^2.0.1" - } - }, - "eslint-plugin-prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz", - "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==", - "dev": true, - "requires": { - "fast-diff": "^1.1.1", - "jest-docblock": "^21.0.0" - } - }, - "eslint-plugin-react": { - "version": "7.12.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz", - "integrity": "sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==", - "dev": true, - "requires": { - "array-includes": "^3.0.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.0.1", - "object.fromentries": "^2.0.0", - "prop-types": "^15.6.2", - "resolve": "^1.9.0" - }, - "dependencies": { - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } - }, - "eslint-restricted-globals": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", - "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", - "dev": true - }, - "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", @@ -2605,29 +1759,12 @@ "dev": true, "optional": true }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true + "dev": true, + "optional": true }, "esutils": { "version": "2.0.2", @@ -2687,17 +1824,6 @@ "dev": true, "optional": true }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, "extglob": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", @@ -2714,68 +1840,26 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, - "falafel": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.1.0.tgz", - "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=", - "dev": true, - "requires": { - "acorn": "^5.0.0", - "foreach": "^2.0.5", - "isarray": "0.0.1", - "object-keys": "^1.0.6" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, "fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true + "dev": true, + "optional": true }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true + "dev": true, + "optional": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" - } + "optional": true }, "filename-regex": { "version": "2.0.1", @@ -2798,27 +1882,6 @@ "repeat-string": "^1.5.2" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", - "dev": true, - "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" - } - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -2836,12 +1899,6 @@ "for-in": "^1.0.1" } }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -3419,12 +2476,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "get-assigned-identifiers": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", @@ -3488,9 +2539,9 @@ "dev": true }, "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", "dev": true }, "har-schema": { @@ -3529,18 +2580,6 @@ "ansi-regex": "^2.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, "hash-base": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", @@ -3560,12 +2599,6 @@ "minimalistic-assert": "^1.0.1" } }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -3587,12 +2620,6 @@ "os-tmpdir": "^1.0.1" } }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true - }, "htmlescape": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", @@ -3717,24 +2744,10 @@ } } }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, "ieee754": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" - }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", "dev": true }, "immutable": { @@ -3742,12 +2755,6 @@ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=" }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -3778,74 +2785,6 @@ "source-map": "~0.5.3" } }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "insert-module-globals": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", @@ -3887,12 +2826,6 @@ "loose-envify": "^1.0.0" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, "is-binary-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", @@ -3909,27 +2842,6 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -3969,12 +2881,6 @@ "number-is-nan": "^1.0.0" } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", @@ -4008,36 +2914,6 @@ "dev": true, "optional": true }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -4051,12 +2927,6 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, "isobject": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", @@ -4074,36 +2944,36 @@ "dev": true, "optional": true }, - "jest-docblock": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", - "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "jade": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "commander": "0.6.1", + "mkdirp": "0.3.0" }, "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", + "dev": true + }, + "mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", "dev": true } } }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -4168,7 +3038,8 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true + "dev": true, + "optional": true }, "json-stable-stringify": { "version": "0.0.1", @@ -4179,12 +3050,6 @@ "jsonify": "~0.0.0" } }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -4232,15 +3097,6 @@ "verror": "1.10.0" } }, - "jsx-ast-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", - "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", - "dev": true, - "requires": { - "array-includes": "^3.0.3" - } - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -4274,45 +3130,36 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, + "optional": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", "dev": true }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", "dev": true }, + "lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=", + "dev": true + }, "long": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", @@ -4327,16 +3174,6 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "marked": { "version": "0.3.19", "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", @@ -4406,12 +3243,6 @@ "mime-db": "~1.33.0" } }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -4449,47 +3280,81 @@ } }, "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", + "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", + "dev": true, + "requires": { + "commander": "2.3.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.2", + "glob": "3.2.11", + "growl": "1.9.2", + "jade": "0.26.3", "mkdirp": "0.5.1", - "supports-color": "5.4.0" + "supports-color": "1.2.0", + "to-iso-string": "0.0.2" }, "dependencies": { "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", + "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", "dev": true }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "0.7.1" } }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "escape-string-regexp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", + "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", + "dev": true + }, + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true, + "requires": { + "inherits": "2", + "minimatch": "0.3" + } + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", "dev": true, "requires": { - "has-flag": "^3.0.0" + "lru-cache": "2", + "sigmund": "~1.0.0" } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "supports-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", + "dev": true } } }, @@ -4522,12 +3387,6 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", @@ -4535,28 +3394,10 @@ "dev": true, "optional": true }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, "next-tick": { "version": "1.0.0", "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "normalize-package-data": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.2.tgz", - "integrity": "sha512-YcMnjqeoUckXTPKZSAsPjUPLxH85XotbpqK3w4RyCwdFQSU5FxxBys8buehkSfg0j9fKvV1hn7O0+8reEgkAiw==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "normalize-path": { "version": "2.1.1", @@ -4602,48 +3443,6 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.entries": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", - "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "object.fromentries": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", - "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.11.0", - "function-bind": "^1.1.1", - "has": "^1.0.1" - } - }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -4664,20 +3463,12 @@ "wrappy": "1" } }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, + "optional": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -4716,30 +3507,6 @@ "object-assign": "^4.1.0" } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", @@ -4781,15 +3548,6 @@ "is-glob": "^2.0.0" } }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, "parse5": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", @@ -4805,24 +3563,12 @@ "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -4835,15 +3581,6 @@ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", "dev": true }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, "pbkdf2": { "version": "3.0.16", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", @@ -4858,8 +3595,8 @@ } }, "peerplaysjs-ws": { - "version": "git+ssh://git@github.com/PBSA/peerplaysjs-ws.git#a92c3d94297d79e41c75c0c9f63898e59a888a2a", - "from": "git+ssh://git@github.com/PBSA/peerplaysjs-ws.git", + "version": "0.1.11", + "resolved": "git+ssh://git@github.com/PBSA/peerplaysjs-ws.git#a92c3d94297d79e41c75c0c9f63898e59a888a2a", "requires": { "ws": "2.3.1" } @@ -4871,27 +3608,6 @@ "dev": true, "optional": true }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -4905,12 +3621,6 @@ "dev": true, "optional": true }, - "prettier": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.3.tgz", - "integrity": "sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==", - "dev": true - }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -4929,28 +3639,6 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "prop-types": { - "version": "15.6.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", - "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", - "dev": true, - "requires": { - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "psl": { "version": "1.1.28", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.28.tgz", @@ -5052,27 +3740,6 @@ "readable-stream": "^2.0.2" } }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -5134,12 +3801,6 @@ "is-equal-shallow": "^0.1.3" } }, - "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", - "dev": true - }, "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", @@ -5243,16 +3904,6 @@ } } }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - } - }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -5262,47 +3913,6 @@ "path-parse": "^1.0.5" } }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -5312,30 +3922,6 @@ "inherits": "^2.0.1" } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "*" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -5345,7 +3931,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "optional": true }, "sax": { "version": "1.2.4", @@ -5359,12 +3946,6 @@ "resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.1.tgz", "integrity": "sha1-CIDy2MUYX0vLRoQFjINrTdsHFFo=" }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true - }, "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", @@ -5391,21 +3972,6 @@ "sha.js": "~2.4.4" } }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, "shell-quote": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", @@ -5418,10 +3984,10 @@ "jsonify": "~0.0.0" } }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, "simple-concat": { @@ -5436,15 +4002,6 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -5460,44 +4017,6 @@ "source-map": "^0.5.6" } }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", - "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, "sshpk": { "version": "1.14.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", @@ -5559,33 +4078,6 @@ "readable-stream": "^2.0.2" } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -5604,18 +4096,6 @@ "ansi-regex": "^2.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -5655,63 +4135,12 @@ "acorn-node": "^1.2.0" } }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "taffydb": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.7.3.tgz", "integrity": "sha1-KtNxaWKUmPylvIQkMJbTzeDsOjQ=", "dev": true }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -5737,15 +4166,6 @@ "process": "~0.11.0" } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -5758,6 +4178,12 @@ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", "dev": true }, + "to-iso-string": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", + "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", + "dev": true + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -5820,29 +4246,11 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, - "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", - "dev": true, - "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } + "uglifyjs": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/uglifyjs/-/uglifyjs-2.4.11.tgz", + "integrity": "sha1-NEDWTgRXWViVJEGOtkHGi7kNET4=", + "dev": true }, "ultron": { "version": "1.1.1", @@ -5901,6 +4309,7 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, "requires": { "inherits": "2.0.1" }, @@ -5908,7 +4317,8 @@ "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true } } }, @@ -5934,16 +4344,6 @@ "user-home": "^1.1.1" } }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -5982,20 +4382,12 @@ "tr46": "~0.0.1" } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "dev": true, + "optional": true }, "wrappy": { "version": "1.0.2", @@ -6003,15 +4395,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "ws": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/ws/-/ws-2.3.1.tgz", @@ -6040,12 +4423,6 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true } } } diff --git a/package.json b/package.json index cccf9d9..9b521be 100644 --- a/package.json +++ b/package.json @@ -1,84 +1,71 @@ { - "name": "peerplaysjs-lib", - "version": "0.4.24", - "description": "Pure JavaScript Peerplaysjs library for node.js and browsers.", - "browser": { - "ws": false, - "crypto": false - }, - "scripts": { - "test": "BABEL_ENV=test mocha --compilers js:babel-register --recursive", - "test:chain": "BABEL_ENV=test mocha --compilers js:babel-register ./test/chain --recursive", - "test:ecc": "BABEL_ENV=test mocha --compilers js:babel-register ./test/ecc --recursive", - "test:serializer": "BABEL_ENV=test mocha --compilers js:babel-register ./test/serializer --recursive", - "test:watch": "npm test -- --watch", - "clean": "rm -rf ./dist/* & rm -rf ./build/*", - "prebuild": "npm run clean", - "build": "babel lib -d dist", - "postbuild": "npm run browserify", - "build:watch": "babel lib -d dist --watch", - "prebrowserify": "rm -rf ./build/*", - "browserify": "browserify -t [browserify-package-json --global=true] -p [bundle-collapser/plugin] dist/browser.js --full-path=false --standalone peerplays_js -o build/peerplaysjs-lib.js -d", - "postbrowserify": "uglifyjs --compress --mangle --sequences --drop_console --output build/peerplaysjs-lib.min.js -- build/peerplaysjs-lib.js", - "doc": "esdoc -c esdoc.json", - "example:transfer": "babel-node examples/transfer", - "example:chainStore": "babel-node examples/chainStore", - "example:privKey": "babel-node examples/privKey" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/PBSA/peerplaysjs-lib" - }, - "author": "Sigve Kvalsvik (https://github.com/svk31)", - "contributors": [ - "James Calfee (https://github.com/jcalfee/)", - "Daniel Larimer (https://github.com/bytemaster/)", - "Valentine Zavgorodnev (https://github.com/valzav/)" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/PBSA/peerplaysjs-lib/issues" - }, - "engines": { - "node": ">= 6.0.0" - }, - "main": "dist/index.js", - "jsnext:main": "lib/index.js", - "dependencies": { - "assert": "^1.3.0", - "bigi": "^1.4.1", - "bs58": "^3.0.0", - "buffer": "^5.1.0", - "bytebuffer": "^5.0.0", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "crypto-js": "^3.1.9-1", - "deep-equal": "^1.0.1", - "ecurve": "^1.0.2", - "event-emitter": "^0.3.4", - "immutable": "^3.7.6", - "peerplaysjs-ws": "git+ssh://git@github.com:PBSA/peerplaysjs-ws.git", - "secure-random": "^1.1.1" - }, - "devDependencies": { - "babel-cli": "^6.18.0", - "babel-core": "^6.21.0", - "babel-eslint": "^7.1.1", - "babel-plugin-add-module-exports": "^0.2.1", - "babel-preset-es2015": "^6.18.0", - "babel-preset-stage-1": "^6.16.0", - "browserify": "^13.1.0", - "browserify-package-json": "^1.0.1", - "bundle-collapser": "^1.3.0", - "esdoc": "^1.1.0", - "eslint": "^4.19.1", - "eslint-config-airbnb": "^17.0.0", - "eslint-plugin-import": "^2.13.0", - "eslint-plugin-jsx-a11y": "^6.1.1", - "eslint-plugin-prettier": "^2.6.2", - "eslint-plugin-react": "^7.10.0", - "mocha": "^5.2.0", - "prettier": "^1.13.7", - "uglify-js": "^3.4.9" - } + "name": "peerplaysjs-lib", + "version": "0.4.20", + "description": "Pure JavaScript Peerplays/Graphene library for node.js and browsers.", + "browser": { + "ws": false, + "crypto": false + }, + "scripts": { + "test": "mocha --compilers js:babel-core/register --recursive", + "test:chain": "mocha --compilers js:babel-core/register ./test/chain --recursive", + "test:ecc": "mocha --compilers js:babel-core/register ./test/ecc --recursive", + "test:serializer": "mocha --compilers js:babel-core/register ./test/serializer --recursive", + "test:watch": "npm test -- --watch", + "clean": "rm -rf ./dist/* & rm -rf ./build/*", + "prebuild": "npm run clean", + "build": "babel lib --presets es2015-generators-async --plugins transform-async-to-generator --out-dir dist", + "build:watch": "babel lib --presets es2015-generators-async --out-dir dist --watch", + "prebrowserify": "rm -rf ./build/*", + "browserify": "browserify --full-paths dist/browser.js --standalone steemJS -o build/peerplaysjs-lib.js -d", + "postbrowserify": "uglifyjs --compress --mangle --sequences --drop_console --output build/peerplaysjs-lib.min.js -- build/peerplaysjs-lib.js", + "prepublish": "npm run build", + "doc": "esdoc -c esdoc.json" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/PBSA/peerplaysjs-lib.git" + }, + "author": "Sigve Kvalsvik (https://github.com/svk31)", + "contributors": [ + "James Calfee (https://github.com/jcalfee/)", + "Daniel Larimer (https://github.com/bytemaster/)", + "Valentine Zavgorodnev (https://github.com/valzav/)" + ], + "license": "BSD-2-Clause-FreeBSD", + "bugs": { + "url": "https://github.com/PBSA/peerplaysjs-lib/issues" + }, + "engines": { + "node": ">= 6.0.0" + }, + "main": "./dist/index.js", + "dependencies": { + "bigi": "^1.4.1", + "bluebird": "^3.5.0", + "bs58": "^3.0.0", + "bytebuffer": "^5.0.0", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "crypto-js": "^3.1.5", + "deep-equal": "^1.0.1", + "ecurve": "^1.0.2", + "event-emitter": "^0.3.4", + "immutable": "^3.7.6", + "peerplaysjs-ws": "^0.1.11", + "secure-random": "^1.1.1" + }, + "devDependencies": { + "assert": "^1.3.0", + "babel-cli": "^6.9.0", + "babel-core": "^6.10.4", + "babel-eslint": "^6.0.4", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-preset-es2015": "^6.24.1", + "babel-preset-es2015-generators-async": "^6.3.13", + "browserify": "^13.1.0", + "esdoc": "^1.1.0", + "mocha": "^2.5.3", + "uglifyjs": "^2.4.10" + } } From fd68ba19485a2b133531aaa0a76028c74cea2ed3 Mon Sep 17 00:00:00 2001 From: mseaward Date: Fri, 1 Feb 2019 15:34:58 -0400 Subject: [PATCH 09/15] include dist --- .gitignore | 3 +- dist/browser.js | 11 + dist/chain/index.js | 23 + dist/chain/src/AccountLogin.js | 132 ++ dist/chain/src/ChainStore.js | 1711 +++++++++++++++++++ dist/chain/src/ChainTypes.js | 116 ++ dist/chain/src/ChainValidation.js | 144 ++ dist/chain/src/EmitterInstance.js | 14 + dist/chain/src/GameMoves.js | 113 ++ dist/chain/src/NumberUtils.js | 44 + dist/chain/src/ObjectId.js | 71 + dist/chain/src/TransactionBuilder.js | 591 +++++++ dist/chain/src/TransactionHelper.js | 104 ++ dist/chain/src/state.js | 19 + dist/ecc/index.js | 12 + dist/ecc/src/BrainKey.js | 9 + dist/ecc/src/KeyUtils.js | 202 +++ dist/ecc/src/PrivateKey.js | 213 +++ dist/ecc/src/PublicKey.js | 236 +++ dist/ecc/src/address.js | 95 + dist/ecc/src/aes.js | 308 ++++ dist/ecc/src/ecdsa.js | 219 +++ dist/ecc/src/ecsignature.js | 128 ++ dist/ecc/src/enforce_types.js | 49 + dist/ecc/src/hash.js | 60 + dist/ecc/src/signature.js | 187 ++ dist/index.js | 3 + dist/serializer/index.js | 22 + dist/serializer/src/FastParser.js | 90 + dist/serializer/src/SerializerValidation.js | 363 ++++ dist/serializer/src/convert.js | 37 + dist/serializer/src/error_with_cause.js | 42 + dist/serializer/src/operations.js | 709 ++++++++ dist/serializer/src/precision.js | 95 + dist/serializer/src/serializer.js | 207 +++ dist/serializer/src/template.js | 17 + dist/serializer/src/types.js | 1024 +++++++++++ 37 files changed, 7421 insertions(+), 2 deletions(-) create mode 100644 dist/browser.js create mode 100644 dist/chain/index.js create mode 100644 dist/chain/src/AccountLogin.js create mode 100644 dist/chain/src/ChainStore.js create mode 100644 dist/chain/src/ChainTypes.js create mode 100644 dist/chain/src/ChainValidation.js create mode 100644 dist/chain/src/EmitterInstance.js create mode 100644 dist/chain/src/GameMoves.js create mode 100644 dist/chain/src/NumberUtils.js create mode 100644 dist/chain/src/ObjectId.js create mode 100644 dist/chain/src/TransactionBuilder.js create mode 100644 dist/chain/src/TransactionHelper.js create mode 100644 dist/chain/src/state.js create mode 100644 dist/ecc/index.js create mode 100644 dist/ecc/src/BrainKey.js create mode 100644 dist/ecc/src/KeyUtils.js create mode 100644 dist/ecc/src/PrivateKey.js create mode 100644 dist/ecc/src/PublicKey.js create mode 100644 dist/ecc/src/address.js create mode 100644 dist/ecc/src/aes.js create mode 100644 dist/ecc/src/ecdsa.js create mode 100644 dist/ecc/src/ecsignature.js create mode 100644 dist/ecc/src/enforce_types.js create mode 100644 dist/ecc/src/hash.js create mode 100644 dist/ecc/src/signature.js create mode 100644 dist/index.js create mode 100644 dist/serializer/index.js create mode 100644 dist/serializer/src/FastParser.js create mode 100644 dist/serializer/src/SerializerValidation.js create mode 100644 dist/serializer/src/convert.js create mode 100644 dist/serializer/src/error_with_cause.js create mode 100644 dist/serializer/src/operations.js create mode 100644 dist/serializer/src/precision.js create mode 100644 dist/serializer/src/serializer.js create mode 100644 dist/serializer/src/template.js create mode 100644 dist/serializer/src/types.js diff --git a/.gitignore b/.gitignore index 3d658a9..0b79b02 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .npmrc npm-debug.log node_modules -.babelrc -dist +.babelrc \ No newline at end of file diff --git a/dist/browser.js b/dist/browser.js new file mode 100644 index 0000000..dc2b3d3 --- /dev/null +++ b/dist/browser.js @@ -0,0 +1,11 @@ +"use strict"; + +module.exports = { + PrivateKey: require("./ecc/src/PrivateKey"), + PublicKey: require("./ecc/src/PublicKey"), + Signature: require("./ecc/src/signature"), + key: require("./ecc/src/KeyUtils"), + TransactionBuilder: require("./chain/src/TransactionBuilder"), + Login: require("./chain/src/AccountLogin"), + grapheneWS: require("peerplaysjs-ws") +}; \ No newline at end of file diff --git a/dist/chain/index.js b/dist/chain/index.js new file mode 100644 index 0000000..9b10496 --- /dev/null +++ b/dist/chain/index.js @@ -0,0 +1,23 @@ +"use strict"; + +var ChainStore = require("./src/ChainStore"); +var TransactionBuilder = require("./src/TransactionBuilder"); + +module.exports = { + ChainStore: ChainStore, + TransactionBuilder: TransactionBuilder, + FetchChainObjects: ChainStore.FetchChainObjects, + + ChainTypes: require("./src/ChainTypes"), + ObjectId: require("./src/ObjectId"), + NumberUtils: require("./src/NumberUtils"), + TransactionHelper: require("./src/TransactionHelper"), + ChainValidation: require("./src/ChainValidation"), + EmitterInstance: require("./src/EmitterInstance"), + Login: require("./src/AccountLogin"), + GameMoves: require("./src/GameMoves"), + + /** Helper function for FetchChainObjects */ + FetchChain: ChainStore.FetchChain + +}; \ No newline at end of file diff --git a/dist/chain/src/AccountLogin.js b/dist/chain/src/AccountLogin.js new file mode 100644 index 0000000..b082e45 --- /dev/null +++ b/dist/chain/src/AccountLogin.js @@ -0,0 +1,132 @@ +"use strict"; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PrivateKey = require("../../ecc/src/PrivateKey"); +var key = require("../../ecc/src/KeyUtils"); + +var _require = require("./state"), + get = _require.get, + set = _require.set; + +var _keyCachePriv = {}; +var _keyCachePub = {}; + +var AccountLogin = function () { + function AccountLogin() { + _classCallCheck(this, AccountLogin); + + var state = { loggedIn: false, roles: ["active", "owner", "memo"] }; + this.get = get(state); + this.set = set(state); + + this.subs = {}; + } + + _createClass(AccountLogin, [{ + key: "addSubscription", + value: function addSubscription(cb) { + this.subs[cb] = cb; + } + }, { + key: "setRoles", + value: function setRoles(roles) { + this.set("roles", roles); + } + }, { + key: "generateKeys", + value: function generateKeys(accountName, password, roles, prefix) { + var start = new Date().getTime(); + if (!accountName || !password) { + throw new Error("Account name or password required"); + } + if (password.length < 12) { + throw new Error("Password must have at least 12 characters"); + } + + var privKeys = {}; + var pubKeys = {}; + + (roles || this.get("roles")).forEach(function (role) { + var seed = accountName + role + password; + var pkey = _keyCachePriv[seed] ? _keyCachePriv[seed] : PrivateKey.fromSeed(key.normalize_brainKey(seed)); + _keyCachePriv[seed] = pkey; + + privKeys[role] = pkey; + pubKeys[role] = _keyCachePub[seed] ? _keyCachePub[seed] : pkey.toPublicKey().toString(prefix); + + _keyCachePub[seed] = pubKeys[role]; + }); + + return { privKeys: privKeys, pubKeys: pubKeys }; + } + }, { + key: "checkKeys", + value: function checkKeys(_ref) { + var _this = this; + + var accountName = _ref.accountName, + password = _ref.password, + auths = _ref.auths; + + if (!accountName || !password || !auths) { + throw new Error("checkKeys: Missing inputs"); + } + var hasKey = false; + + var _loop = function _loop(role) { + var _generateKeys = _this.generateKeys(accountName, password, [role]), + privKeys = _generateKeys.privKeys, + pubKeys = _generateKeys.pubKeys; + + auths[role].forEach(function (key) { + if (key[0] === pubKeys[role]) { + hasKey = true; + _this.set(role, { priv: privKeys[role], pub: pubKeys[role] }); + } + }); + }; + + for (var role in auths) { + _loop(role); + }; + + if (hasKey) { + this.set("name", accountName); + } + + this.set("loggedIn", hasKey); + + return hasKey; + } + }, { + key: "signTransaction", + value: function signTransaction(tr) { + var _this2 = this; + + var myKeys = {}; + var hasKey = false; + + this.get("roles").forEach(function (role) { + var myKey = _this2.get(role); + if (myKey) { + hasKey = true; + console.log("adding signer:", myKey.pub); + tr.add_signer(myKey.priv, myKey.pub); + } + }); + + if (!hasKey) { + throw new Error("You do not have any private keys to sign this transaction"); + } + } + }]); + + return AccountLogin; +}(); + +var accountLogin = new AccountLogin(); + +module.exports = accountLogin; \ No newline at end of file diff --git a/dist/chain/src/ChainStore.js b/dist/chain/src/ChainStore.js new file mode 100644 index 0000000..a00b15e --- /dev/null +++ b/dist/chain/src/ChainStore.js @@ -0,0 +1,1711 @@ +"use strict"; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var Immutable = require("immutable"); + +var _require = require("peerplaysjs-ws"), + Apis = _require.Apis; + +var _require2 = require("./ChainTypes"), + object_type = _require2.object_type, + impl_object_type = _require2.impl_object_type; + +var ChainValidation = require("./ChainValidation"); +var BigInteger = require("bigi"); +var ee = require("./EmitterInstance"); + +var emitter = ee.emitter(); + +var op_history = parseInt(object_type.operation_history, 10); +var limit_order = parseInt(object_type.limit_order, 10); +var call_order = parseInt(object_type.call_order, 10); +var proposal = parseInt(object_type.proposal, 10); +var balance_type = parseInt(object_type.balance, 10); +var vesting_balance_type = parseInt(object_type.vesting_balance, 10); +var witness_object_type = parseInt(object_type.witness, 10); +var worker_object_type = parseInt(object_type.worker, 10); +var committee_member_object_type = parseInt(object_type.committee_member, 10); +var account_object_type = parseInt(object_type.account, 10); +var asset_object_type = parseInt(object_type.asset, 10); +var tournament_object_type = parseInt(object_type.tournament, 10); +var tournament_details_object_type = parseInt(object_type.tournament_details, 10); + +var order_prefix = "1." + limit_order + "."; +var call_order_prefix = "1." + call_order + "."; +var proposal_prefix = "1." + proposal + "."; +var balance_prefix = "2." + parseInt(impl_object_type.account_balance, 10) + "."; +var account_stats_prefix = "2." + parseInt(impl_object_type.account_statistics, 10) + "."; +var asset_dynamic_data_prefix = "2." + parseInt(impl_object_type.asset_dynamic_data, 10) + "."; +var bitasset_data_prefix = "2." + parseInt(impl_object_type.asset_bitasset_data, 10) + "."; +var vesting_balance_prefix = "1." + vesting_balance_type + "."; +var witness_prefix = "1." + witness_object_type + "."; +var worker_prefix = "1." + worker_object_type + "."; +var committee_prefix = "1." + committee_member_object_type + "."; +var asset_prefix = "1." + asset_object_type + "."; +var account_prefix = "1." + account_object_type + "."; +var tournament_prefix = "1." + tournament_object_type + "."; +var tournament_details_prefix = "1." + tournament_details_object_type + "."; + +// count last operations should be stored in memory +var operations_stack_size = 100; +// count last blocks should be stored in memory +var block_stack_size = 20; + +var DEBUG = JSON.parse(process.env.npm_config__graphene_chain_chain_debug || false); + +/** + * @brief maintains a local cache of blockchain state + * + * The ChainStore maintains a local cache of blockchain state and exposes + * an API that makes it easy to query objects and receive updates when + * objects are available. + */ + +var ChainStore = function () { + function ChainStore() { + _classCallCheck(this, ChainStore); + + /** tracks everyone who wants to receive updates when the cache changes */ + this.subscribers = new Set(); + this.subscribed = false; + this.clearCache(); + this.progress = 0; + // this.chain_time_offset is used to estimate the blockchain time + this.chain_time_offset = []; + this.dispatchFrequency = 40; + } + + /** + * Clears all cached state. This should be called any time the network connection is + * reset. + */ + + + _createClass(ChainStore, [{ + key: "clearCache", + value: function clearCache() { + this.objects_by_id = Immutable.Map(); + this.accounts_by_name = Immutable.Map(); + this.assets_by_symbol = Immutable.Map(); + this.account_ids_by_key = Immutable.Map(); + this.balance_objects_by_address = Immutable.Map(); + this.get_account_refs_of_keys_calls = Immutable.Set(); + this.account_history_requests = new Map(); ///< tracks pending history requests + this.witness_by_account_id = new Map(); + this.account_by_witness_id = new Map(); + this.committee_by_account_id = new Map(); + this.objects_by_vote_id = new Map(); + this.fetching_get_full_accounts = new Map(); + this.recent_operations = Immutable.List(); + this.recent_blocks = Immutable.List(); + this.recent_blocks_by_id = Immutable.Map(); + this.last_processed_block = null; + this.simple_objects_by_id = Immutable.Map(); + + // tournament_ids_by_state is a + // Map(account => Map(state_string => Set of tournament ids)) + // it maintains a map of tournaments a given account is allowed to participate + // in (open-registration tournaments or tournaments they are whitelisted for). + // the null account maps to all tournaments + // accounts and states will not be tracked until their first access + this.tournament_ids_by_state = Immutable.Map().set(null, new Immutable.Map()); + + // registered_tournaments_details_by_player is a map of + // Map(registered_account_id => Set of tournament details objects) + // it only tracks tournaments which the account has registered to play in + this.registered_tournament_ids_by_player = Immutable.Map(); + + this.last_tournament_id = undefined; + + this.store_initialized = false; + } + }, { + key: "resetCache", + value: function resetCache() { + this.subscribed = false; + this.clearCache(); + this.head_block_time_string = null; + this.init().then(function (result) { + console.log("resetCache init success"); + }).catch(function (err) { + console.log("resetCache init error:", err); + }); + } + }, { + key: "setDispatchFrequency", + value: function setDispatchFrequency(freq) { + this.dispatchFrequency = freq; + } + }, { + key: "init", + value: function init() { + var _this = this; + + var reconnectCounter = 0; + var _init = function _init(resolve, reject) { + var db_api = Apis.instance().db_api(); + if (!db_api) { + return reject(new Error("Api not found, please initialize the api instance before calling the ChainStore")); + } + return db_api.exec("get_objects", [["2.1.0"]]).then(function (optional_objects) { + //if(DEBUG) console.log('... optional_objects',optional_objects ? optional_objects[0].id : null) + for (var i = 0; i < optional_objects.length; i++) { + var optional_object = optional_objects[i]; + if (optional_object) { + + _this._updateObject(optional_object, true); + + var head_time = new Date(optional_object.time + "+00:00").getTime(); + _this.head_block_time_string = optional_object.time; + _this.chain_time_offset.push(new Date().getTime() - _this.timeStringToDate(optional_object.time).getTime()); + var now = new Date().getTime(); + var delta = (now - head_time) / 1000; + var start = Date.parse('Sep 1, 2015'); + var progress_delta = head_time - start; + _this.progress = progress_delta / (now - start); + + if (delta < 60) { + Apis.instance().db_api().exec("set_subscribe_callback", [_this.onUpdate.bind(_this), true]).then(function (v) { + console.log("synced and subscribed, chainstore ready"); + _this.subscribed = true; + _this.fetchRecentOperations(); + resolve(); + }).catch(function (error) { + reject(error); + console.log("Error: ", error); + }); + } else { + console.log("not yet synced, retrying in 1s"); + reconnectCounter++; + if (reconnectCounter > 10) { + throw new Error("ChainStore sync error, please check your system clock"); + } + setTimeout(_init.bind(_this, resolve, reject), 1000); + } + } else { + setTimeout(_init.bind(_this, resolve, reject), 1000); + } + } + }).catch(function (error) { + // in the event of an error clear the pending state for id + console.log('!!! Chain API error', error); + _this.objects_by_id = _this.objects_by_id.delete("2.1.0"); + reject(error); + }); + }; + + return new Promise(function (resolve, reject) { + return _init(resolve, reject); + }); + } + }, { + key: "onUpdate", + value: function onUpdate(updated_objects) /// map from account id to objects + { + emitter.emit('heartbeat'); + // updated_objects is the parameter list, it should always be exactly + // one element long. + // The single parameter to this callback function is a vector of variants, where + // each entry indicates one changed object. + // If the entry is an object id, it means the object has been removed. If it + // is an full object, then the object is either newly-created or changed. + for (var a = 0; a < updated_objects.length; ++a) { + for (var i = 0; i < updated_objects[a].length; ++i) { + var obj = updated_objects[a][i]; + + if (ChainValidation.is_object_id(obj)) { + /// the object was removed + // Cancelled limit order, emit event for MarketStore to update it's state + if (obj.search(order_prefix) == 0) { + var old_obj = this.objects_by_id.get(obj); + if (!old_obj) { + return; + } + emitter.emit('cancel-order', old_obj.get("id")); + var account = this.objects_by_id.get(old_obj.get("seller")); + if (account && account.has("orders")) { + var limit_orders = account.get("orders"); + if (account.get("orders").has(obj)) { + account = account.set("orders", limit_orders.delete(obj)); + this.objects_by_id = this.objects_by_id.set(account.get("id"), account); + } + } + } + + // Update nested call_order inside account object + if (obj.search(call_order_prefix) == 0) { + + var _old_obj = this.objects_by_id.get(obj); + if (!_old_obj) { + return; + } + emitter.emit('close-call', _old_obj.get("id")); + var _account = this.objects_by_id.get(_old_obj.get("borrower")); + if (_account && _account.has("call_orders")) { + var call_orders = _account.get("call_orders"); + if (_account.get("call_orders").has(obj)) { + _account = _account.set("call_orders", call_orders.delete(obj)); + this.objects_by_id = this.objects_by_id.set(_account.get("id"), _account); + } + } + } + + // Remove the object + this.objects_by_id = this.objects_by_id.set(obj, null); + } else this._updateObject(obj, false); + } + } + this.notifySubscribers(); + } + }, { + key: "notifySubscribers", + value: function notifySubscribers() { + var _this2 = this; + + // Dispatch at most only once every x milliseconds + if (!this.dispatched) { + this.dispatched = true; + setTimeout(function () { + _this2.dispatched = false; + _this2.subscribers.forEach(function (callback) { + callback(); + }); + }, this.dispatchFrequency); + } + } + + /** + * Add a callback that will be called anytime any object in the cache is updated + */ + + }, { + key: "subscribe", + value: function subscribe(callback) { + if (this.subscribers.has(callback)) console.error("Subscribe callback already exists", callback); + this.subscribers.add(callback); + } + + /** + * Remove a callback that was previously added via subscribe + */ + + }, { + key: "unsubscribe", + value: function unsubscribe(callback) { + if (!this.subscribers.has(callback)) console.error("Unsubscribe callback does not exists", callback); + this.subscribers.delete(callback); + } + + /** Clear an object from the cache to force it to be fetched again. This may + * be useful if a query failed the first time and the wallet has reason to believe + * it may succeede the second time. + */ + + }, { + key: "clearObjectCache", + value: function clearObjectCache(id) { + this.objects_by_id = this.objects_by_id.delete(id); + } + + /** + * There are three states an object id could be in: + * + * 1. undefined - returned if a query is pending + * 3. defined - return an object + * 4. null - query return null + * + */ + + }, { + key: "getObject", + value: function getObject(id) { + var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!ChainValidation.is_object_id(id)) throw Error("argument is not an object id: " + JSON.stringify(id)); + + var result = this.objects_by_id.get(id); + if (result === undefined || force) return this.fetchObject(id, force); + if (result === true) return undefined; + + return result; + } + }, { + key: "getSimpleObjectById", + value: function getSimpleObjectById(id) { + var _this3 = this; + + return new Promise(function (success, fail) { + if (!ChainValidation.is_object_id(id)) fail("argument is not an object id: " + JSON.stringify(id)); + + var result = _this3.simple_objects_by_id.get(id); + + if (result) { + return success(result); + } + Apis.instance().db_api().exec("get_objects", [[id]]).then(function (objects) { + var object = objects[0]; + if (!object) return success(null); + _this3.simple_objects_by_id = _this3.simple_objects_by_id.set(id, object); + success(object); + }); + }); + } + + /** + * @return undefined if a query is pending + * @return null if id_or_symbol has been queired and does not exist + * @return object if the id_or_symbol exists + */ + + }, { + key: "getAsset", + value: function getAsset(id_or_symbol) { + var _this4 = this; + + if (!id_or_symbol) return null; + + if (ChainValidation.is_object_id(id_or_symbol)) { + var asset = this.getObject(id_or_symbol); + + if (asset && asset.get("bitasset") && !asset.getIn(["bitasset", "current_feed"])) { + return undefined; + } + return asset; + } + + /// TODO: verify id_or_symbol is a valid symbol name + + var asset_id = this.assets_by_symbol.get(id_or_symbol); + + if (ChainValidation.is_object_id(asset_id)) { + var _asset = this.getObject(asset_id); + + if (_asset && _asset.get("bitasset") && !_asset.getIn(["bitasset", "current_feed"])) { + return undefined; + } + return _asset; + } + + if (asset_id === null) return null; + + if (asset_id === true) return undefined; + + Apis.instance().db_api().exec("lookup_asset_symbols", [[id_or_symbol]]).then(function (asset_objects) { + // console.log( "lookup symbol ", id_or_symbol ) + if (asset_objects.length && asset_objects[0]) _this4._updateObject(asset_objects[0], true);else { + _this4.assets_by_symbol = _this4.assets_by_symbol.set(id_or_symbol, null); + _this4.notifySubscribers(); + } + }).catch(function (error) { + console.log("Error: ", error); + _this4.assets_by_symbol = _this4.assets_by_symbol.delete(id_or_symbol); + }); + + return undefined; + } + + /** + * @param the public key to find accounts that reference it + * + * @return Set of account ids that reference the given key + * @return a empty Set if no items are found + * @return undefined if the result is unknown + * + * If this method returns undefined, then it will send a request to + * the server for the current set of accounts after which the + * server will notify us of any accounts that reference these keys + */ + + }, { + key: "getAccountRefsOfKey", + value: function getAccountRefsOfKey(key) { + var _this5 = this; + + if (this.get_account_refs_of_keys_calls.has(key)) return this.account_ids_by_key.get(key);else { + this.get_account_refs_of_keys_calls = this.get_account_refs_of_keys_calls.add(key); + Apis.instance().db_api().exec("get_key_references", [[key]]).then(function (vec_account_id) { + var refs = Immutable.Set(); + vec_account_id = vec_account_id[0]; + refs = refs.withMutations(function (r) { + for (var i = 0; i < vec_account_id.length; ++i) { + r.add(vec_account_id[i]); + } + }); + _this5.account_ids_by_key = _this5.account_ids_by_key.set(key, refs); + _this5.notifySubscribers(); + }, function (error) { + _this5.account_ids_by_key = _this5.account_ids_by_key.delete(key); + _this5.get_account_refs_of_keys_calls = _this5.get_account_refs_of_keys_calls.delete(key); + }); + return undefined; + } + return undefined; + } + + /** + * @return a Set of balance ids that are claimable with the given address + * @return undefined if a query is pending and the set is not known at this time + * @return a empty Set if no items are found + * + * If this method returns undefined, then it will send a request to the server for + * the current state after which it will be subscribed to changes to this set. + */ + + }, { + key: "getBalanceObjects", + value: function getBalanceObjects(address) { + var _this6 = this; + + var current = this.balance_objects_by_address.get(address); + if (current === undefined) { + /** because balance objects are simply part of the genesis state, there is no need to worry about + * having to update them / merge them or index them in updateObject. + */ + this.balance_objects_by_address = this.balance_objects_by_address.set(address, Immutable.Set()); + Apis.instance().db_api().exec("get_balance_objects", [[address]]).then(function (balance_objects) { + var set = new Set(); + for (var i = 0; i < balance_objects.length; ++i) { + _this6._updateObject(balance_objects[i]); + set.add(balance_objects[i].id); + } + _this6.balance_objects_by_address = _this6.balance_objects_by_address.set(address, Immutable.Set(set)); + _this6.notifySubscribers(); + }, function (error) { + _this6.balance_objects_by_address = _this6.balance_objects_by_address.delete(address); + }); + } + return this.balance_objects_by_address.get(address); + } + + /** + * @return a list of tournament ids for upcoming tournaments + * @return an empty list if a query is pending and the set is not known at this time + * or if there are no upcoming touraments + * + * If we have not yet requested tournaments for this account, it will send a request to the server for + * the current list, after which it will be subscribed to changes to this set. + */ + + }, { + key: "getTournamentIdsInState", + value: function getTournamentIdsInState(accountId, stateString) { + var _this7 = this; + + var tournamentIdsForThisAccountAndState = undefined; + var tournamentIdsForThisAccount = this.tournament_ids_by_state.get(accountId); + if (tournamentIdsForThisAccount === undefined) { + tournamentIdsForThisAccountAndState = new Immutable.Set(); + tournamentIdsForThisAccount = new Immutable.Map().set(stateString, tournamentIdsForThisAccountAndState); + this.tournament_ids_by_state = this.tournament_ids_by_state.set(accountId, tournamentIdsForThisAccount); + } else { + tournamentIdsForThisAccountAndState = tournamentIdsForThisAccount.get(stateString); + if (tournamentIdsForThisAccountAndState !== undefined) return tournamentIdsForThisAccountAndState; + + tournamentIdsForThisAccountAndState = new Immutable.Set(); + tournamentIdsForThisAccount = tournamentIdsForThisAccount.set(stateString, tournamentIdsForThisAccountAndState); + this.tournament_ids_by_state = this.tournament_ids_by_state.set(accountId, tournamentIdsForThisAccount); + } + + Apis.instance().db_api().exec("get_tournaments_in_state", [stateString, 100]).then(function (tournaments) { + var originalTournamentIdsInState = _this7.tournament_ids_by_state.getIn([accountId, stateString]); + // call updateObject on each tournament, which will classify it + tournaments.forEach(function (tournament) { + /** + * Fix bug: we cant update tournament_ids_by_state if objects_by_id has a tournament + */ + if (!originalTournamentIdsInState.get(tournament.id)) { + _this7.clearObjectCache(tournament.id); + } + + _this7._updateObject(tournament, false); // false = don't notify on change + }); + if (_this7.tournament_ids_by_state.getIn([accountId, stateString]) != originalTournamentIdsInState) _this7.notifySubscribers(); + }); + return tournamentIdsForThisAccountAndState; + } + }, { + key: "getRegisteredTournamentIds", + value: function getRegisteredTournamentIds(accountId) { + var _this8 = this; + + var tournamentIds = this.registered_tournament_ids_by_player.get(accountId); + if (tournamentIds !== undefined) return tournamentIds; + tournamentIds = new Immutable.Set(); + this.registered_tournament_ids_by_player = this.registered_tournament_ids_by_player.set(accountId, tournamentIds); + + Apis.instance().db_api().exec("get_registered_tournaments", [accountId, 100]).then(function (tournamentIds) { + var originalTournamentIds = _this8.registered_tournament_ids_by_player.get(accountId); + var newTournamentIds = new Immutable.Set(tournamentIds); + if (!originalTournamentIds.equals(newTournamentIds)) { + _this8.registered_tournament_ids_by_player = _this8.registered_tournament_ids_by_player.set(accountId, newTournamentIds); + _this8.notifySubscribers(); + } + }); + + return tournamentIds; + } + + /** + * If there is not already a pending request to fetch this object, a new + * request will be made. + * + * @return null if the object does not exist, + * @return undefined if the object might exist but is not in cache + * @return the object if it does exist and is in our cache + */ + + }, { + key: "fetchObject", + value: function fetchObject(id) { + var _this9 = this; + + var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (typeof id !== 'string') { + var _result = []; + for (var i = 0; i < id.length; ++i) { + _result.push(this.fetchObject(id[i])); + }return _result; + } + + if (DEBUG) console.log("!!! fetchObject: ", id, this.subscribed, !this.subscribed && !force); + if (!this.subscribed && !force) return undefined; + + if (DEBUG) console.log("maybe fetch object: ", id); + if (!ChainValidation.is_object_id(id)) throw Error("argument is not an object id: " + id); + + if (id.substring(0, 4) == "1.2.") return this.fetchFullAccount(id); + + var result = this.objects_by_id.get(id); + if (result === undefined) { + // the fetch + if (DEBUG) console.log("fetching object: ", id); + this.objects_by_id = this.objects_by_id.set(id, true); + Apis.instance().db_api().exec("get_objects", [[id]]).then(function (optional_objects) { + if (DEBUG) console.log('... optional_objects', optional_objects ? optional_objects[0].id : null); + for (var _i = 0; _i < optional_objects.length; _i++) { + var optional_object = optional_objects[_i]; + if (optional_object) { + _this9._updateObject(optional_object, true); + _this9.simple_objects_by_id = _this9.simple_objects_by_id.set(id, optional_object); + } else { + _this9.objects_by_id = _this9.objects_by_id.set(id, null); + _this9.notifySubscribers(); + } + } + }).catch(function (error) { + // in the event of an error clear the pending state for id + console.log('!!! Chain API error', error); + _this9.objects_by_id = _this9.objects_by_id.delete(id); + }); + } else if (result === true) // then we are waiting a response + return undefined; + return result; // we have a response, return it + } + + /** + * @return null if no such account exists + * @return undefined if such an account may exist, and fetch the the full account if not already pending + * @return the account object if it does exist + */ + + }, { + key: "getAccount", + value: function getAccount(name_or_id) { + + if (!name_or_id) return null; + + if ((typeof name_or_id === "undefined" ? "undefined" : _typeof(name_or_id)) === 'object') { + if (name_or_id.id) return this.getAccount(name_or_id.id);else if (name_or_id.get) return this.getAccount(name_or_id.get('id'));else return undefined; + } + + if (ChainValidation.is_object_id(name_or_id)) { + var account = this.getObject(name_or_id); + if (account === null) { + return null; + } + if (account === undefined || account.get('name') === undefined) { + return this.fetchFullAccount(name_or_id); + } + return account; + } else if (ChainValidation.is_account_name(name_or_id, true)) { + var account_id = this.accounts_by_name.get(name_or_id); + if (account_id === null) return null; // already fetched and it wasn't found + if (account_id === undefined) // then no query, fetch it + return this.fetchFullAccount(name_or_id); + return this.getObject(account_id); // return it + } + //throw Error( `Argument is not an account name or id: ${name_or_id}` ) + } + + /** + * This method will attempt to lookup witness by account_id. + * If witness doesn't exist it will return null, if witness is found it will return witness object, + * if it's not fetched yet it will return undefined. + * @param account_id - account id + */ + + }, { + key: "getWitnessById", + value: function getWitnessById(account_id) { + var witness_id = this.witness_by_account_id.get(account_id); + if (witness_id === undefined) { + this.fetchWitnessByAccount(account_id); + return undefined; + } + return witness_id ? this.getObject(witness_id) : null; + } + + /** + * This method will attempt to lookup witness by account_id. + * If witness doesn't exist it will return null, if witness is found it will return witness object, + * if it's not fetched yet it will return undefined. + * @param witness_id - witness id + */ + + }, { + key: "getWitnessAccount", + value: function getWitnessAccount(witness_id) { + var _this10 = this; + + return new Promise(function (success, fail) { + var account = _this10.account_by_witness_id.get(witness_id); + + if (account) return success(account); + + _this10.getSimpleObjectById(witness_id).then(function (witness) { + _this10.getSimpleObjectById(witness.witness_account).then(function (account) { + _this10.account_by_witness_id = _this10.account_by_witness_id.set(witness_id, account); + success(account); + }); + }); + }); + } + + /** + * This method will attempt to lookup committee member by account_id. + * If committee member doesn't exist it will return null, if committee member is found it will return committee member object, + * if it's not fetched yet it will return undefined. + * @param account_id - account id + */ + + }, { + key: "getCommitteeMemberById", + value: function getCommitteeMemberById(account_id) { + var cm_id = this.committee_by_account_id.get(account_id); + if (cm_id === undefined) { + this.fetchCommitteeMemberByAccount(account_id); + return undefined; + } + return cm_id ? this.getObject(cm_id) : null; + } + + /** + * Obsolete! Please use getWitnessById + * This method will attempt to lookup the account, and then query to see whether or not there is + * a witness for this account. If the answer is known, it will return the witness_object, otherwise + * it will attempt to look it up and return null. Once the lookup has completed on_update will + * be called. + * + * @param id_or_account may either be an account_id, a witness_id, or an account_name + */ + + }, { + key: "getWitness", + value: function getWitness(id_or_account) { + var _this11 = this; + + var account = this.getAccount(id_or_account); + if (!account) return null; + var account_id = account.get('id'); + + var witness_id = this.witness_by_account_id.get(account_id); + if (witness_id === undefined) this.fetchWitnessByAccount(account_id); + return this.getObject(witness_id); + + if (ChainValidation.is_account_name(id_or_account, true) || id_or_account.substring(0, 4) == "1.2.") { + var _account2 = this.getAccount(id_or_account); + if (!_account2) { + this.lookupAccountByName(id_or_account).then(function (account) { + if (!account) return null; + + var account_id = account.get('id'); + var witness_id = _this11.witness_by_account_id.get(account_id); + if (ChainValidation.is_object_id(witness_id)) return _this11.getObject(witness_id, on_update); + + if (witness_id == undefined) _this11.fetchWitnessByAccount(account_id).then(function (witness) { + _this11.witness_by_account_id.set(account_id, witness ? witness.get('id') : null); + if (witness && on_update) on_update(); + }); + }, function (error) { + var witness_id = _this11.witness_by_account_id.set(id_or_account, null); + }); + } else { + var _account_id = _account2.get('id'); + var _witness_id = this.witness_by_account_id.get(_account_id); + if (ChainValidation.is_object_id(_witness_id)) return this.getObject(_witness_id, on_update); + + if (_witness_id == undefined) this.fetchWitnessByAccount(_account_id).then(function (witness) { + _this11.witness_by_account_id.set(_account_id, witness ? witness.get('id') : null); + if (witness && on_update) on_update(); + }); + } + return null; + } + return null; + } + + // Obsolete! Please use getCommitteeMemberById + + }, { + key: "getCommitteeMember", + value: function getCommitteeMember(id_or_account) { + var _this12 = this; + + var on_update = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + if (ChainValidation.is_account_name(id_or_account, true) || id_or_account.substring(0, 4) == "1.2.") { + var account = this.getAccount(id_or_account); + + if (!account) { + this.lookupAccountByName(id_or_account).then(function (account) { + var account_id = account.get('id'); + var committee_id = _this12.committee_by_account_id.get(account_id); + if (ChainValidation.is_object_id(committee_id)) return _this12.getObject(committee_id, on_update); + + if (committee_id == undefined) { + _this12.fetchCommitteeMemberByAccount(account_id).then(function (committee) { + _this12.committee_by_account_id.set(account_id, committee ? committee.get('id') : null); + if (on_update && committee) on_update(); + }); + } + }, function (error) { + var witness_id = _this12.committee_by_account_id.set(id_or_account, null); + }); + } else { + var account_id = account.get('id'); + var committee_id = this.committee_by_account_id.get(account_id); + if (ChainValidation.is_object_id(committee_id)) return this.getObject(committee_id, on_update); + + if (committee_id == undefined) { + this.fetchCommitteeMemberByAccount(account_id).then(function (committee) { + _this12.committee_by_account_id.set(account_id, committee ? committee.get('id') : null); + if (on_update && committee) on_update(); + }); + } + } + } + return null; + } + + /** + * + * @returns a promise with a list of all witness ids. Regardless of if they have been voted in or not. + * @memberof ChainStore + */ + + }, { + key: "fetchWitnessAccounts", + value: function fetchWitnessAccounts() { + var _this24 = this; + return new Promise(function (resolve, reject) { + Apis.instance().db_api().exec("lookup_witness_accounts", [0, 1000]).then(function (w) { + if (w) { + var witnessArr = []; + + for (var i = 0, length = w.length; i < length; i++) { + witnessArr.push(w[i][1]); // ids only + } + + _this24.witnesses = _this24.witnesses.merge(witnessArr); + _this24._updateObject(witnessArr, true); + resolve(_this24.witnesses); + } else { + resolve(null); + } + }); + }); + } + + /** + * + * @return a promise with the witness object + */ + + }, { + key: "fetchWitnessByAccount", + value: function fetchWitnessByAccount(account_id) { + var _this13 = this; + + return new Promise(function (resolve, reject) { + Apis.instance().db_api().exec("get_witness_by_account", [account_id]).then(function (optional_witness_object) { + if (optional_witness_object) { + _this13.witness_by_account_id = _this13.witness_by_account_id.set(optional_witness_object.witness_account, optional_witness_object.id); + var witness_object = _this13._updateObject(optional_witness_object, true); + resolve(witness_object); + } else { + _this13.witness_by_account_id = _this13.witness_by_account_id.set(account_id, null); + _this13.notifySubscribers(); + resolve(null); + } + }, reject); + }); + } + + /** + * + * @return a promise with the witness object + */ + + }, { + key: "fetchCommitteeMemberByAccount", + value: function fetchCommitteeMemberByAccount(account_id) { + var _this14 = this; + + return new Promise(function (resolve, reject) { + Apis.instance().db_api().exec("get_committee_member_by_account", [account_id]).then(function (optional_committee_object) { + if (optional_committee_object) { + _this14.committee_by_account_id = _this14.committee_by_account_id.set(optional_committee_object.committee_member_account, optional_committee_object.id); + var committee_object = _this14._updateObject(optional_committee_object, true); + resolve(committee_object); + } else { + _this14.committee_by_account_id = _this14.committee_by_account_id.set(account_id, null); + _this14.notifySubscribers(); + resolve(null); + } + }, reject); + }); + } + + /** + * Fetches an account and all of its associated data in a single query + * + * @param an account name or account id + * + * @return undefined if the account in question is in the process of being fetched + * @return the object if it has already been fetched + * @return null if the object has been queried and was not found + */ + + }, { + key: "fetchFullAccount", + value: function fetchFullAccount(name_or_id) { + var _this15 = this; + + if (DEBUG) console.log("Fetch full account: ", name_or_id); + + var fetch_account = false; + if (ChainValidation.is_object_id(name_or_id)) { + var current = this.objects_by_id.get(name_or_id); + fetch_account = current === undefined; + if (!fetch_account && fetch_account.get('name')) return current; + } else { + if (!ChainValidation.is_account_name(name_or_id, true)) throw Error("argument is not an account name: " + name_or_id); + + var account_id = this.accounts_by_name.get(name_or_id); + if (ChainValidation.is_object_id(account_id)) return this.getAccount(account_id); + } + + /// only fetch once every 5 seconds if it wasn't found + if (!this.fetching_get_full_accounts.has(name_or_id) || Date.now() - this.fetching_get_full_accounts.get(name_or_id) > 5000) { + this.fetching_get_full_accounts.set(name_or_id, Date.now()); + //console.log( "FETCHING FULL ACCOUNT: ", name_or_id ) + Apis.instance().db_api().exec("get_full_accounts", [[name_or_id], true]).then(function (results) { + if (results.length === 0) { + if (ChainValidation.is_object_id(name_or_id)) { + _this15.objects_by_id = _this15.objects_by_id.set(name_or_id, null); + _this15.notifySubscribers(); + } + return; + } + var full_account = results[0][1]; + if (DEBUG) console.log("full_account: ", full_account); + + var account = full_account.account, + vesting_balances = full_account.vesting_balances, + pending_dividend_payments = full_account.pending_dividend_payments, + statistics = full_account.statistics, + call_orders = full_account.call_orders, + limit_orders = full_account.limit_orders, + referrer_name = full_account.referrer_name, + registrar_name = full_account.registrar_name, + lifetime_referrer_name = full_account.lifetime_referrer_name, + votes = full_account.votes, + proposals = full_account.proposals; + + + _this15.accounts_by_name = _this15.accounts_by_name.set(account.name, account.id); + account.referrer_name = referrer_name; + account.lifetime_referrer_name = lifetime_referrer_name; + account.registrar_name = registrar_name; + account.balances = {}; + account.orders = new Immutable.Set(); + account.vesting_balances = new Immutable.Set(); + account.pending_dividend_payments = new Immutable.Set(); + account.balances = new Immutable.Map(); + account.call_orders = new Immutable.Set(); + account.proposals = new Immutable.Set(); + account.vesting_balances = account.vesting_balances.withMutations(function (set) { + vesting_balances.forEach(function (vb) { + _this15._updateObject(vb, false); + set.add(vb.id); + }); + }); + + votes.forEach(function (v) { + return _this15._updateObject(v, false); + }); + + account.balances = account.balances.withMutations(function (map) { + full_account.balances.forEach(function (b) { + _this15._updateObject(b, false); + map.set(b.asset_type, b.id); + }); + }); + + account.orders = account.orders.withMutations(function (set) { + limit_orders.forEach(function (order) { + _this15._updateObject(order, false); + set.add(order.id); + }); + }); + + account.pending_dividend_payments = account.pending_dividend_payments.withMutations(function (set) { + pending_dividend_payments.forEach(function (payments) { + _this15._updateObject(payments, false); + set.add(payments); + }); + }); + + account.call_orders = account.call_orders.withMutations(function (set) { + call_orders.forEach(function (co) { + _this15._updateObject(co, false); + set.add(co.id); + }); + }); + + account.proposals = account.proposals.withMutations(function (set) { + proposals.forEach(function (p) { + _this15._updateObject(p, false); + set.add(p.id); + }); + }); + + _this15._updateObject(statistics, false); + var updated_account = _this15._updateObject(account, false); + _this15.fetchRecentHistory(updated_account); + _this15.notifySubscribers(); + }, function (error) { + console.log("Error: ", error); + if (ChainValidation.is_object_id(name_or_id)) _this15.objects_by_id = _this15.objects_by_id.delete(name_or_id);else _this15.accounts_by_name = _this15.accounts_by_name.delete(name_or_id); + }); + } + return undefined; + } + }, { + key: "getAccountMemberStatus", + value: function getAccountMemberStatus(account) { + if (account === undefined) return undefined; + if (account === null) return "unknown"; + if (account.get('lifetime_referrer') == account.get('id')) return "lifetime"; + var exp = new Date(account.get('membership_expiration_date')).getTime(); + var now = new Date().getTime(); + if (exp < now) return "basic"; + return "annual"; + } + }, { + key: "getAccountBalance", + value: function getAccountBalance(account, asset_type) { + var balances = account.get('balances'); + if (!balances) return 0; + + var balance_obj_id = balances.get(asset_type); + if (balance_obj_id) { + var bal_obj = this.objects_by_id.get(balance_obj_id); + if (bal_obj) return bal_obj.get('balance'); + } + return 0; + } + + /** + * There are two ways to extend the account history, add new more + * recent history, and extend historic hstory. This method will fetch + * the most recent account history and prepend it to the list of + * historic operations. + * + * @param account immutable account object + * @return a promise with the account history + */ + + }, { + key: "fetchRecentHistory", + value: function fetchRecentHistory(account) { + var _this16 = this; + + var limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; + + // console.log( "get account history: ", account ) + /// TODO: make sure we do not submit a query if there is already one + /// in flight... + var account_id = account; + if (!ChainValidation.is_object_id(account_id) && account.toJS) account_id = account.get('id'); + + if (!ChainValidation.is_object_id(account_id)) return; + + account = this.objects_by_id.get(account_id); + if (!account) return; + + var pending_request = this.account_history_requests.get(account_id); + if (pending_request) { + pending_request.requests++; + return pending_request.promise; + } else pending_request = { requests: 0 }; + + var most_recent = "1." + op_history + ".0"; + var history = account.get('history'); + + if (history && history.size) most_recent = history.first().get('id'); + + /// starting at 0 means start at NOW, set this to something other than 0 + /// to skip recent transactions and fetch the tail + var start = "1." + op_history + ".0"; + + pending_request.promise = new Promise(function (resolve, reject) { + Apis.instance().history_api().exec("get_account_history", [account_id, most_recent, limit, start]).then(function (operations) { + var current_account = _this16.objects_by_id.get(account_id); + var current_history = current_account.get('history'); + if (!current_history) current_history = Immutable.List(); + var updated_history = Immutable.fromJS(operations); + updated_history = updated_history.withMutations(function (list) { + for (var i = 0; i < current_history.size; ++i) { + list.push(current_history.get(i)); + } + }); + var updated_account = current_account.set('history', updated_history); + _this16.objects_by_id = _this16.objects_by_id.set(account_id, updated_account); + + //if( current_history != updated_history ) + // this._notifyAccountSubscribers( account_id ) + + var pending_request = _this16.account_history_requests.get(account_id); + _this16.account_history_requests.delete(account_id); + if (pending_request.requests > 0) { + // it looks like some more history may have come in while we were + // waiting on the result, lets fetch anything new before we resolve + // this query. + _this16.fetchRecentHistory(updated_account, limit).then(resolve, reject); + } else resolve(updated_account); + }); // end then + }); + + this.account_history_requests.set(account_id, pending_request); + return pending_request.promise; + } + + //_notifyAccountSubscribers( account_id ) + //{ + // let sub = this.subscriptions_by_account.get( account_id ) + // let acnt = this.objects_by_id.get(account_id) + // if( !sub ) return + // for( let item of sub.subscriptions ) + // item( acnt ) + //} + + /** + * Callback that receives notification of objects that have been + * added, remove, or changed and are relevant to account_id + * + * This method updates or removes objects from the main index and + * then updates the account object with relevant meta-info depending + * upon the type of account + */ + // _updateAccount( account_id, payload ) + // { + // let updates = payload[0] + + // for( let i = 0; i < updates.length; ++i ) + // { + // let update = updates[i] + // if( typeof update == 'string' ) + // { + // let old_obj = this._removeObject( update ) + + // if( update.search( order_prefix ) == 0 ) + // { + // acnt = acnt.setIn( ['orders'], set => set.delete(update) ) + // } + // else if( update.search( vesting_balance_prefix ) == 0 ) + // { + // acnt = acnt.setIn( ['vesting_balances'], set => set.delete(update) ) + // } + // } + // else + // { + // let updated_obj = this._updateObject( update ) + // if( update.id.search( balance_prefix ) == 0 ) + // { + // if( update.owner == account_id ) + // acnt = acnt.setIn( ['balances'], map => map.set(update.asset_type,update.id) ) + // } + // else if( update.id.search( order_prefix ) == 0 ) + // { + // if( update.owner == account_id ) + // acnt = acnt.setIn( ['orders'], set => set.add(update.id) ) + // } + // else if( update.id.search( vesting_balance_prefix ) == 0 ) + // { + // if( update.owner == account_id ) + // acnt = acnt.setIn( ['vesting_balances'], set => set.add(update.id) ) + // } + + // this.objects_by_id = this.objects_by_id.set( acnt.id, acnt ) + // } + // } + // this.fetchRecentHistory( acnt ) + // } + + /** + * Updates the object in place by only merging the set + * properties of object. + * + * This method will create an immutable object with the given ID if + * it does not already exist. + * + * This is a "private" method called when data is received from the + * server and should not be used by others. + * + * @pre object.id must be a valid object ID + * @return an Immutable constructed from object and deep merged with the current state + */ + + }, { + key: "_updateObject", + value: function _updateObject(object, notify_subscribers) { + var emit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + + + if (!("id" in object)) { + console.log("object with no id:", object); + if ("balance" in object && "owner" in object && "settlement_date" in object) { + // Settle order object + emitter.emit("settle-order-update", object); + } + return; + } + // if (!(object.id.split(".")[0] == 2) && !(object.id.split(".")[1] == 6)) { + // console.log( "update: ", object ) + // } + + // DYNAMIC GLOBAL OBJECT + if (object.id == "2.1.0") { + object.participation = 100 * (BigInteger(object.recent_slots_filled).bitCount() / 128.0); + this.head_block_time_string = object.time; + this.chain_time_offset.push(Date.now() - this.timeStringToDate(object.time).getTime()); + if (this.chain_time_offset.length > 10) this.chain_time_offset.shift(); // remove first + this.fetchRecentOperations(object.head_block_number); + } + + var current = this.objects_by_id.get(object.id, undefined); + if (current === undefined || current === true) current = Immutable.Map(); + var prior = current; + if (current === undefined || current === true) this.objects_by_id = this.objects_by_id.set(object.id, current = Immutable.fromJS(object));else this.objects_by_id = this.objects_by_id.set(object.id, current = current.mergeDeep(Immutable.fromJS(object))); + + // BALANCE OBJECT + if (object.id.substring(0, balance_prefix.length) == balance_prefix) { + var owner = this.objects_by_id.get(object.owner); + if (owner === undefined || owner === null) { + return; + /* This prevents the full account from being looked up later + owner = {id:object.owner, balances:{ } } + owner.balances[object.asset_type] = object.id + owner = Immutable.fromJS( owner ) + */ + } else { + var balances = owner.get("balances"); + if (!balances) owner = owner.set("balances", Immutable.Map()); + owner = owner.setIn(['balances', object.asset_type], object.id); + } + this.objects_by_id = this.objects_by_id.set(object.owner, owner); + } + // ACCOUNT STATS OBJECT + else if (object.id.substring(0, account_stats_prefix.length) == account_stats_prefix) { + // console.log( "HISTORY CHANGED" ) + var prior_most_recent_op = prior ? prior.get('most_recent_op') : "2.9.0"; + + if (prior_most_recent_op != object.most_recent_op) { + this.fetchRecentHistory(object.owner); + } + } + // WITNESS OBJECT + else if (object.id.substring(0, witness_prefix.length) == witness_prefix) { + this.witness_by_account_id.set(object.witness_account, object.id); + this.objects_by_vote_id.set(object.vote_id, object.id); + } + // COMMITTEE MEMBER OBJECT + else if (object.id.substring(0, committee_prefix.length) == committee_prefix) { + this.committee_by_account_id.set(object.committee_member_account, object.id); + this.objects_by_vote_id.set(object.vote_id, object.id); + } + // ACCOUNT OBJECT + else if (object.id.substring(0, account_prefix.length) == account_prefix) { + current = current.set('active', Immutable.fromJS(object.active)); + current = current.set('owner', Immutable.fromJS(object.owner)); + current = current.set('options', Immutable.fromJS(object.options)); + current = current.set('pending_dividend_payments', Immutable.fromJS(object.pending_dividend_payments)); + current = current.set('whitelisting_accounts', Immutable.fromJS(object.whitelisting_accounts)); + current = current.set('blacklisting_accounts', Immutable.fromJS(object.blacklisting_accounts)); + current = current.set('whitelisted_accounts', Immutable.fromJS(object.whitelisted_accounts)); + current = current.set('blacklisted_accounts', Immutable.fromJS(object.blacklisted_accounts)); + this.objects_by_id = this.objects_by_id.set(object.id, current); + this.accounts_by_name = this.accounts_by_name.set(object.name, object.id); + } + // ASSET OBJECT + else if (object.id.substring(0, asset_prefix.length) == asset_prefix) { + this.assets_by_symbol = this.assets_by_symbol.set(object.symbol, object.id); + var dynamic = current.get('dynamic'); + if (!dynamic) { + var dad = this.getObject(object.dynamic_asset_data_id, true); + if (!dad) dad = Immutable.Map(); + if (!dad.get('asset_id')) { + dad = dad.set('asset_id', object.id); + } + this.objects_by_id = this.objects_by_id.set(object.dynamic_asset_data_id, dad); + + current = current.set('dynamic', dad); + this.objects_by_id = this.objects_by_id.set(object.id, current); + } + + var bitasset = current.get('bitasset'); + if (!bitasset && object.bitasset_data_id) { + var bad = this.getObject(object.bitasset_data_id, true); + if (!bad) bad = Immutable.Map(); + + if (!bad.get('asset_id')) { + bad = bad.set('asset_id', object.id); + } + this.objects_by_id = this.objects_by_id.set(object.bitasset_data_id, bad); + + current = current.set('bitasset', bad); + this.objects_by_id = this.objects_by_id.set(object.id, current); + } + } + // ASSET DYNAMIC DATA OBJECT + else if (object.id.substring(0, asset_dynamic_data_prefix.length) == asset_dynamic_data_prefix) { + // let asset_id = asset_prefix + object.id.substring( asset_dynamic_data_prefix.length ) + var asset_id = current.get("asset_id"); + if (asset_id) { + var asset_obj = this.getObject(asset_id); + if (asset_obj && asset_obj.set) { + asset_obj = asset_obj.set('dynamic', current); + this.objects_by_id = this.objects_by_id.set(asset_id, asset_obj); + } + } + } + // WORKER OBJECT + else if (object.id.substring(0, worker_prefix.length) == worker_prefix) { + this.objects_by_vote_id.set(object.vote_for, object.id); + this.objects_by_vote_id.set(object.vote_against, object.id); + } + // BITASSET DATA OBJECT + else if (object.id.substring(0, bitasset_data_prefix.length) == bitasset_data_prefix) { + var _asset_id = current.get("asset_id"); + if (_asset_id) { + var asset = this.getObject(_asset_id); + if (asset) { + asset = asset.set("bitasset", current); + emitter.emit('bitasset-update', asset); + this.objects_by_id = this.objects_by_id.set(_asset_id, asset); + } + } + } + // CALL ORDER OBJECT + else if (object.id.substring(0, call_order_prefix.length) == call_order_prefix) { + // Update nested call_orders inside account object + if (emit) { + emitter.emit("call-order-update", object); + } + + var account = this.objects_by_id.get(object.borrower); + if (account && account.has("call_orders")) { + var call_orders = account.get("call_orders"); + if (!call_orders.has(object.id)) { + account = account.set("call_orders", call_orders.add(object.id)); + this.objects_by_id = this.objects_by_id.set(account.get("id"), account); + } + } + } + // LIMIT ORDER OBJECT + else if (object.id.substring(0, order_prefix.length) == order_prefix) { + var _account3 = this.objects_by_id.get(object.seller); + if (_account3 && _account3.has("orders")) { + var limit_orders = _account3.get("orders"); + if (!limit_orders.has(object.id)) { + _account3 = _account3.set("orders", limit_orders.add(object.id)); + this.objects_by_id = this.objects_by_id.set(_account3.get("id"), _account3); + } + } + } + // PROPOSAL OBJECT + else if (object.id.substring(0, proposal_prefix.length) == proposal_prefix) { + this.addProposalData(object.required_active_approvals, object.id); + this.addProposalData(object.required_owner_approvals, object.id); + } + // TOURNAMENT OBJECT + else if (object.id.substring(0, tournament_prefix.length) == tournament_prefix) { + var priorState = prior.get("state"); + var newState = current.get("state"); + + if (priorState !== newState) { + this.tournament_ids_by_state = this.tournament_ids_by_state.map(function (stateMap, accountId) { + return stateMap.map(function (tournamentIdSet, stateString) { + if (stateString === priorState) return tournamentIdSet.remove(object.id);else if (stateString === newState && (accountId === null || current.getIn(["options", "whitelist"]).isEmpty() || current.getIn(["options", "whitelist"]).includes(accountId))) return tournamentIdSet.add(object.id);else return tournamentIdSet; + }); + }); + } + + if (this.last_tournament_id !== undefined) { + this.setLastTournamentId(current.get('id')); + } + } else if (object.id.substring(0, tournament_details_prefix.length) == tournament_details_prefix) { + var priorRegisteredPlayers = prior.get("registered_players"); + var newRegisteredPlayers = current.get("registered_players"); + if (priorRegisteredPlayers != newRegisteredPlayers) this.registered_tournament_ids_by_player = this.registered_tournament_ids_by_player.map(function (tournamentIdsSet, accountId) { + if (newRegisteredPlayers.includes(accountId)) return tournamentIdsSet.add(current.get("tournament_id"));else return tournamentIdsSet; + // currently, you can't un-register for a tournament, so we don't have + // to deal with removing from a list + }); + } + + if (notify_subscribers) this.notifySubscribers(); + + return current; + } + }, { + key: "setLastTournamentId", + value: function setLastTournamentId(current_tournament_id) { + if (current_tournament_id === null) { + if (!this.last_tournament_id) { + this.last_tournament_id = current_tournament_id; + } + } else { + var current_tournament_id_short = parseFloat(current_tournament_id.substring(tournament_prefix.length)), + last_tournament_id_short = this.last_tournament_id ? parseFloat(this.last_tournament_id.substring(tournament_prefix.length)) : -1; + + if (current_tournament_id_short > last_tournament_id_short) { + this.last_tournament_id = current_tournament_id; + } + } + } + }, { + key: "getTournaments", + value: function getTournaments(last_tournament_id) { + var _this17 = this; + + var limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5; + var start_tournament_id = arguments[2]; + + + return Apis.instance().db_api().exec("get_tournaments", [last_tournament_id, limit, start_tournament_id]).then(function (tournaments) { + var list = Immutable.List(); + + _this17.setLastTournamentId(null); + + if (tournaments && tournaments.length) { + list = list.withMutations(function (l) { + tournaments.forEach(function (tournament) { + + if (!_this17.objects_by_id.has(tournament.id)) { + _this17._updateObject(tournament, false); + } + + l.unshift(_this17.objects_by_id.get(tournament.id)); + }); + }); + } + + return list; + }); + } + }, { + key: "getLastTournamentId", + value: function getLastTournamentId() { + var _this18 = this; + + return new Promise(function (resolve, reject) { + if (_this18.last_tournament_id === undefined) { + + Apis.instance().db_api().exec("get_tournaments", [tournament_prefix + '0', 1, tournament_prefix + '0']).then(function (tournaments) { + + _this18.setLastTournamentId(null); + + if (tournaments && tournaments.length) { + + tournaments.forEach(function (tournament) { + _this18._updateObject(tournament, false); + }); + } + + resolve(_this18.last_tournament_id); + }); + } else { + + resolve(_this18.last_tournament_id); + } + }); + } + }, { + key: "getObjectsByVoteIds", + value: function getObjectsByVoteIds(vote_ids) { + var _this19 = this; + + var result = []; + var missing = []; + for (var i = 0; i < vote_ids.length; ++i) { + var obj = this.objects_by_vote_id.get(vote_ids[i]); + if (obj) result.push(this.getObject(obj));else { + result.push(null); + missing.push(vote_ids[i]); + } + } + + if (missing.length) { + // we may need to fetch some objects + Apis.instance().db_api().exec("lookup_vote_ids", [missing]).then(function (vote_obj_array) { + console.log("missing ===========> ", missing); + console.log("vote objects ===========> ", vote_obj_array); + for (var _i2 = 0; _i2 < vote_obj_array.length; ++_i2) { + if (vote_obj_array[_i2]) { + _this19._updateObject(vote_obj_array[_i2]); + } + } + }, function (error) { + return console.log("Error looking up vote ids: ", error); + }); + } + return result; + } + }, { + key: "getObjectByVoteID", + value: function getObjectByVoteID(vote_id) { + var obj_id = this.objects_by_vote_id.get(vote_id); + if (obj_id) return this.getObject(obj_id); + return undefined; + } + }, { + key: "getHeadBlockDate", + value: function getHeadBlockDate() { + return this.timeStringToDate(this.head_block_time_string); + } + }, { + key: "getEstimatedChainTimeOffset", + value: function getEstimatedChainTimeOffset() { + if (this.chain_time_offset.length === 0) return 0; + // Immutable is fast, sorts numbers correctly, and leaves the original unmodified + // This will fix itself if the user changes their clock + var median_offset = Immutable.List(this.chain_time_offset).sort().get(Math.floor((this.chain_time_offset.length - 1) / 2)); + // console.log("median_offset", median_offset) + return median_offset; + } + }, { + key: "addProposalData", + value: function addProposalData(approvals, objectId) { + var _this20 = this; + + approvals.forEach(function (id) { + var impactedAccount = _this20.objects_by_id.get(id); + if (impactedAccount) { + var proposals = impactedAccount.get("proposals"); + + if (!proposals.includes(objectId)) { + proposals = proposals.add(objectId); + impactedAccount = impactedAccount.set("proposals", proposals); + _this20._updateObject(impactedAccount.toJS(), false); + } + } + }); + } + }, { + key: "timeStringToDate", + value: function timeStringToDate(time_string) { + if (!time_string) return new Date("1970-01-01T00:00:00.000Z"); + if (!/Z$/.test(time_string)) //does not end in Z + // https://github.com/cryptonomex/graphene/issues/368 + time_string = time_string + "Z"; + return new Date(time_string); + } + }, { + key: "__getBlocksForScan", + value: function __getBlocksForScan(lastBlock) { + var _this21 = this; + + var db_api = Apis.instance().db_api(); + return new Promise(function (success, fail) { + + var scanToBlock = _this21.last_processed_block; + if (lastBlock) return success({ lastBlock: lastBlock, scanToBlock: scanToBlock }); + + db_api.exec("get_dynamic_global_properties", []).then(function (globalProperties) { + lastBlock = _this21.last_processed_block = globalProperties['head_block_number']; + scanToBlock = globalProperties['head_block_number'] - 2000; + scanToBlock = scanToBlock < 0 ? 1 : scanToBlock; + return success({ lastBlock: lastBlock, scanToBlock: scanToBlock }); + }); + }); + } + }, { + key: "__bindBlock", + value: function __bindBlock(lastBlock, scanToBlock, isInit) { + var _this22 = this; + + var db_api = Apis.instance().db_api(); + return new Promise(function (success, fail) { + db_api.exec("get_block", [lastBlock]).then(function (block) { + block.id = lastBlock; + if (typeof block.timestamp === "string") block.timestamp += "+00:00"; + block.timestamp = new Date(block.timestamp); + _this22.getWitnessAccount(block.witness).then(function (witness) { + block.witness_account_name = witness.name; + + if (!_this22.recent_blocks_by_id.get(lastBlock)) { + + _this22.recent_blocks_by_id = _this22.recent_blocks_by_id.set(lastBlock, block); + + if (_this22.last_processed_block < lastBlock) _this22.last_processed_block = lastBlock; + + if (!isInit) { + _this22.recent_blocks = _this22.recent_blocks.unshift(block); + if (_this22.recent_blocks.size > block_stack_size) { + _this22.recent_blocks = _this22.recent_blocks.pop(); + } + } else if (_this22.recent_blocks.size < block_stack_size) { + _this22.recent_blocks = _this22.recent_blocks.push(block); + } + + block.transactions.forEach(function (tx) { + return tx.operations.forEach(function (op) { + op[1].block_id = lastBlock; + op[1].created_at = block.timestamp; + if (!isInit) { + _this22.recent_operations = _this22.recent_operations.unshift(op); + } else { + if (_this22.recent_operations.size < operations_stack_size) { + _this22.recent_operations = _this22.recent_operations.push(op); + } + if (_this22.recent_operations.size >= operations_stack_size && _this22.recent_blocks.size >= block_stack_size) { + scanToBlock = lastBlock; + } + } + if (_this22.recent_operations.size > operations_stack_size) { + _this22.recent_operations = _this22.recent_operations.pop(); + } + }); + }); + } + lastBlock--; + if (lastBlock <= scanToBlock) { + return success(); + } + _this22.__bindBlock(lastBlock, scanToBlock, isInit).then(function () { + return success(); + }); + }); + }); + }); + } + }, { + key: "fetchRecentOperations", + value: function fetchRecentOperations() { + var _this23 = this; + + var lastBlock = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + if (lastBlock && !this.last_processed_block) return; + var isInit = !lastBlock; + + this.__getBlocksForScan(lastBlock).then(function (_ref) { + var lastBlock = _ref.lastBlock, + scanToBlock = _ref.scanToBlock; + + _this23.__bindBlock(lastBlock, scanToBlock, isInit).then(function () { + if (isInit) { + _this23.store_initialized = true; + } + }); + }); + } + }, { + key: "getRecentBlocks", + value: function getRecentBlocks() { + return this.recent_blocks; + } + }, { + key: "getRecentOperations", + value: function getRecentOperations() { + if (!this.store_initialized) return Immutable.List(); + return this.recent_operations; + } + }]); + + return ChainStore; +}(); + +var chain_store = new ChainStore(); + +function FetchChainObjects(method, object_ids, timeout) { + var get_object = method.bind(chain_store); + + return new Promise(function (resolve, reject) { + var timeout_handle = null; + + function onUpdate() { + var not_subscribed_yet = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + var res = object_ids.map(function (id) { + return get_object(id); + }); + if (res.findIndex(function (o) { + return o === undefined; + }) === -1) { + if (timeout_handle) clearTimeout(timeout_handle); + if (!not_subscribed_yet) chain_store.unsubscribe(onUpdate); + resolve(res); + return true; + } + return false; + } + + var resolved = onUpdate(true); + if (!resolved) chain_store.subscribe(onUpdate); + + if (timeout && !resolved) timeout_handle = setTimeout(function () { + chain_store.unsubscribe(onUpdate); + reject("timeout"); + }, timeout); + }); +} + +chain_store.FetchChainObjects = FetchChainObjects; + +function FetchChain(methodName, objectIds) { + var timeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1900; + + + var method = chain_store[methodName]; + if (!method) throw new Error("ChainStore does not have method " + methodName); + + var arrayIn = Array.isArray(objectIds); + if (!arrayIn) objectIds = [objectIds]; + + return chain_store.FetchChainObjects(method, Immutable.List(objectIds), timeout).then(function (res) { + return arrayIn ? res : res.get(0); + }); +} + +chain_store.FetchChain = FetchChain; + +module.exports = chain_store; \ No newline at end of file diff --git a/dist/chain/src/ChainTypes.js b/dist/chain/src/ChainTypes.js new file mode 100644 index 0000000..1a6ffa0 --- /dev/null +++ b/dist/chain/src/ChainTypes.js @@ -0,0 +1,116 @@ +"use strict"; + +var ChainTypes = {}; + +ChainTypes.reserved_spaces = { + relative_protocol_ids: 0, + protocol_ids: 1, + implementation_ids: 2 +}; + +ChainTypes.object_type = { + "null": 0, + base: 1, + account: 2, + asset: 3, + force_settlement: 4, + committee_member: 5, + witness: 6, + limit_order: 7, + call_order: 8, + custom: 9, + proposal: 10, + operation_history: 11, + withdraw_permission: 12, + vesting_balance: 13, + worker: 14, + balance: 15, + tournament: 16, + tournament_details: 17, + match_object_type: 18, + game: 19 +}; + +ChainTypes.impl_object_type = { + global_property: 0, + dynamic_global_property: 1, + index_meta: 2, + asset_dynamic_data: 3, + asset_bitasset_data: 4, + account_balance: 5, + account_statistics: 6, + transaction: 7, + block_summary: 8, + account_transaction_history: 9, + blinded_balance: 10, + chain_property: 11, + witness_schedule: 12, + budget_record: 13, + special_authority: 14, + buyback: 15, + fba_accumulator: 16, + asset_dividend_data: 17, + pending_dividend_payout_balance_for_holder: 18, + distributed_dividend_balance_data: 19 +}; + +ChainTypes.vote_type = { + committee: 0, + witness: 1, + worker: 2 +}; + +ChainTypes.operations = { + transfer: 0, + limit_order_create: 1, + limit_order_cancel: 2, + call_order_update: 3, + fill_order: 4, + account_create: 5, + account_update: 6, + account_whitelist: 7, + account_upgrade: 8, + account_transfer: 9, + asset_create: 10, + asset_update: 11, + asset_update_bitasset: 12, + asset_update_feed_producers: 13, + asset_issue: 14, + asset_reserve: 15, + asset_fund_fee_pool: 16, + asset_settle: 17, + asset_global_settle: 18, + asset_publish_feed: 19, + witness_create: 20, + witness_update: 21, + proposal_create: 22, + proposal_update: 23, + proposal_delete: 24, + withdraw_permission_create: 25, + withdraw_permission_update: 26, + withdraw_permission_claim: 27, + withdraw_permission_delete: 28, + committee_member_create: 29, + committee_member_update: 30, + committee_member_update_global_parameters: 31, + vesting_balance_create: 32, + vesting_balance_withdraw: 33, + worker_create: 34, + custom: 35, + assert: 36, + balance_claim: 37, + override_transfer: 38, + transfer_to_blind: 39, + blind_transfer: 40, + transfer_from_blind: 41, + asset_settle_cancel: 42, + asset_claim_fees: 43, + fba_distribute_operation: 44, + tournament_create: 45, + tournament_join: 46, + game_move: 47, + asset_update_dividend: 48, + asset_dividend_distribution: 49 +}; + +module.exports = ChainTypes; \ No newline at end of file diff --git a/dist/chain/src/ChainValidation.js b/dist/chain/src/ChainValidation.js new file mode 100644 index 0000000..eeb4d04 --- /dev/null +++ b/dist/chain/src/ChainValidation.js @@ -0,0 +1,144 @@ +'use strict'; + +/** + Account names may contain one or more names separated by a dot. + Each name needs to start with a letter and may contain + numbers, or well placed dashes. + @see is_valid_name graphene/libraries/chain/protocol/account.cpp +*/ +var id_regex = /\b\d+\.\d+\.(\d+)\b/; + +var chainValidation = { + is_account_name: function is_account_name(value) { + var allow_too_short = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var i, label, len, length, ref; + + if (this.is_empty(value)) { + return false; + } + + length = value.length; + + if (!allow_too_short && length < 3 || length > 63) { + return false; + } + + ref = value.split('.'); + + for (i = 0, len = ref.length; i < len; i++) { + + label = ref[i]; + + if (!(/^[a-z][a-z0-9-]*$/.test(label) && !/--/.test(label) && /[a-z0-9]$/.test(label))) { + return false; + } + } + return true; + }, + + is_object_id: function is_object_id(obj_id) { + if ('string' != typeof obj_id) return false; + + var match = id_regex.exec(obj_id); + return match !== null && obj_id.split(".").length === 3; + }, + + is_empty: function is_empty(value) { + return value == null || value.length === 0; + }, + + is_account_name_error: function is_account_name_error(value, allow_too_short) { + var i, label, len, length, ref, suffix; + if (allow_too_short == null) { + allow_too_short = false; + } + suffix = "Account name should "; + if (this.is_empty(value)) { + return suffix + "not be empty."; + } + length = value.length; + if (!allow_too_short && length < 3) { + return suffix + "be longer."; + } + if (length > 63) { + return suffix + "be shorter."; + } + if (/\./.test(value)) { + suffix = "Each account segment should "; + } + ref = value.split('.'); + for (i = 0, len = ref.length; i < len; i++) { + label = ref[i]; + if (!/^[~a-z]/.test(label)) { + return suffix + "start with a letter."; + } + if (!/^[~a-z0-9-]*$/.test(label)) { + return suffix + "have only letters, digits, or dashes."; + } + if (/--/.test(label)) { + return suffix + "have only one dash in a row."; + } + if (!/[a-z0-9]$/.test(label)) { + return suffix + "end with a letter or digit."; + } + if (!(label.length >= 3)) { + return suffix + "be longer"; + } + } + return null; + }, + + is_cheap_name: function is_cheap_name(account_name) { + return (/[0-9-]/.test(account_name) || !/[aeiouy]/.test(account_name) + ); + }, + + is_empty_user_input: function is_empty_user_input(value) { + if (this.is_empty(value)) { + return true; + } + if ((value + "").trim() === "") { + return true; + } + return false; + }, + + required: function required(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (this.is_empty(value)) { + throw new Error("value required for " + field_name + ": " + value); + } + return value; + }, + + /** @see is_valid_symbol graphene/libraries/chain/protocol/asset_ops.cpp */ + is_valid_symbol_error: function is_valid_symbol_error(value) { + var suffix = "Asset name should "; + if (this.is_empty(value)) { + return suffix + "not be empty."; + } + if (value.split('.').length > 2) { + return suffix + "have only one dot."; + } + if (value.length < 3) { + return suffix + "be longer."; + } + if (value.length > 16) { + return suffix + "be shorter."; + } + if (!/^[A-Z]/.test(value)) { + return suffix + "start with a letter"; + } + if (!/[A-Z]$/.test(value)) { + return suffix + "end with a letter"; + } + if (/^[A-Z0-9\.]$/.test(value)) { + return suffix + "contain only letters numbers and perhaps a dot."; + } + return null; + } +}; + +module.exports = chainValidation; \ No newline at end of file diff --git a/dist/chain/src/EmitterInstance.js b/dist/chain/src/EmitterInstance.js new file mode 100644 index 0000000..9b03216 --- /dev/null +++ b/dist/chain/src/EmitterInstance.js @@ -0,0 +1,14 @@ +"use strict"; + +var ee = require("event-emitter"); + +var _emitter; + +module.exports = { + emitter: function emitter() { + if (!_emitter) { + _emitter = ee({}); + } + return _emitter; + } +}; \ No newline at end of file diff --git a/dist/chain/src/GameMoves.js b/dist/chain/src/GameMoves.js new file mode 100644 index 0000000..4c5cd1c --- /dev/null +++ b/dist/chain/src/GameMoves.js @@ -0,0 +1,113 @@ +"use strict"; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var assert = require("assert"); + +var _require = require("../../ecc"), + Signature = _require.Signature, + PublicKey = _require.PublicKey, + hash = _require.hash; + +var _require2 = require("../../serializer"), + Serializer = _require2.Serializer, + types = _require2.types; + +var _require3 = require('peerplaysjs-ws'), + Apis = _require3.Apis, + ChainConfig = _require3.ChainConfig; + +var ChainTypes = require('./ChainTypes'); +var head_block_time_string = void 0; +var ByteBuffer = require('bytebuffer'); +var secureRandom = require("secure-random"); + +var uint8 = types.uint8, + uint16 = types.uint16, + uint32 = types.uint32, + int64 = types.int64, + uint64 = types.uint64, + string = types.string, + bytes = types.bytes, + bool = types.bool, + array = types.array, + fixed_array = types.fixed_array, + protocol_id_type = types.protocol_id_type, + object_id_type = types.object_id_type, + vote_id = types.vote_id, + future_extensions = types.future_extensions, + static_variant = types.static_variant, + map = types.map, + set = types.set, + public_key = types.public_key, + address = types.address, + time_point_sec = types.time_point_sec, + optional = types.optional, + variant = types.variant, + variant_object = types.variant_object, + enumeration = types.enumeration, + sha256 = types.sha256; + + +var rock_paper_scissors_gesture = enumeration(["rock", "paper", "scissors", "spock", "lizard"]); + +var rock_paper_scissors_throw = new Serializer("rock_paper_scissors_throw", { nonce1: uint64, + nonce2: uint64, + gesture: rock_paper_scissors_gesture }); + +var rock_paper_scissors_throw_commit = new Serializer("rock_paper_scissors_throw_commit", { nonce1: uint64, + throw_hash: sha256 }); + +var rock_paper_scissors_throw_reveal = new Serializer("rock_paper_scissors_throw_reveal", { nonce2: uint64, + gesture: rock_paper_scissors_gesture }); + +var GameMoves = function () { + function GameMoves() { + _classCallCheck(this, GameMoves); + } + + _createClass(GameMoves, [{ + key: "createCommitAndRevealMoveOperations", + value: function createCommitAndRevealMoveOperations(move_type) { + var nonce1 = ByteBuffer.wrap(secureRandom.randomArray(8)).readUint64(); + var nonce2 = ByteBuffer.wrap(secureRandom.randomArray(8)).readUint64(); + + var throw_object = rock_paper_scissors_throw.fromObject({ + nonce1: nonce1, + nonce2: nonce2, + gesture: move_type + }); + var throw_object_reconstructed = rock_paper_scissors_throw.toObject(throw_object); + //console.log("Nonce1: %o, Nonce2: %o", nonce1, nonce2); + //console.log("As object: %O, as JS: %O", throw_object, throw_object_reconstructed); + var throw_buffer = rock_paper_scissors_throw.toBuffer(throw_object); + //console.log("As hex: %O", rock_paper_scissors_throw.toHex(throw_object)); + var throw_hash = hash.sha256(throw_buffer); + //console.log("Hash is : %O", throw_hash); + + var commit_move_operation_object = rock_paper_scissors_throw_commit.fromObject({ + nonce1: nonce1, + throw_hash: throw_hash + }); + var reveal_move_operation_object = rock_paper_scissors_throw_reveal.fromObject({ + nonce2: nonce2, + gesture: move_type + }); + + //console.log("Commit hex is %O, reveal hex is %O", rock_paper_scissors_throw_commit.toHex(commit_move_operation_object), rock_paper_scissors_throw_reveal.toHex(reveal_move_operation_object)); + + var commit_move_operation = rock_paper_scissors_throw_commit.toObject(commit_move_operation_object); + var reveal_move_operation = rock_paper_scissors_throw_reveal.toObject(reveal_move_operation_object); + //console.log("As JS, they are %O, %O", commit_move_operation, reveal_move_operation); + + + return [commit_move_operation, reveal_move_operation]; + } + }]); + + return GameMoves; +}(); + +module.exports = GameMoves; \ No newline at end of file diff --git a/dist/chain/src/NumberUtils.js b/dist/chain/src/NumberUtils.js new file mode 100644 index 0000000..bd772ee --- /dev/null +++ b/dist/chain/src/NumberUtils.js @@ -0,0 +1,44 @@ +"use strict"; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; 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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var assert = require("assert"); + +/** + Convert 12.34 with a precision of 3 into 12340 + + @arg {number|string} number - Use strings for large numbers. This may contain one decimal but no sign + @arg {number} precision - number of implied decimal places (usually causes right zero padding) + @return {string} - +*/ +module.exports = { + toImpliedDecimal: function toImpliedDecimal(number, precision) { + + if (typeof number === "number") { + assert(number <= 9007199254740991, "overflow"); + number = "" + number; + } else if (number.toString) number = number.toString(); + + assert(typeof number === "string", "number should be an actual number or string: " + (typeof number === "undefined" ? "undefined" : _typeof(number))); + number = number.trim(); + assert(/^[0-9]*\.?[0-9]*$/.test(number), "Invalid decimal number " + number); + + var _number$split = number.split("."), + _number$split2 = _slicedToArray(_number$split, 2), + _number$split2$ = _number$split2[0], + whole = _number$split2$ === undefined ? "" : _number$split2$, + _number$split2$2 = _number$split2[1], + decimal = _number$split2$2 === undefined ? "" : _number$split2$2; + + var padding = precision - decimal.length; + assert(padding >= 0, "Too many decimal digits in " + number + " to create an implied decimal of " + precision); + + for (var i = 0; i < padding; i++) { + decimal += "0"; + }while (whole.charAt(0) === "0") { + whole = whole.substring(1); + }return whole + decimal; + } +}; \ No newline at end of file diff --git a/dist/chain/src/ObjectId.js b/dist/chain/src/ObjectId.js new file mode 100644 index 0000000..86ff3a2 --- /dev/null +++ b/dist/chain/src/ObjectId.js @@ -0,0 +1,71 @@ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var _require = require('bytebuffer'), + Long = _require.Long; + +var v = require('../../serializer/src/SerializerValidation'); + +var DB_MAX_INSTANCE_ID = Long.fromNumber(Math.pow(2, 48) - 1); + +var ObjectId = function () { + function ObjectId(space, type, instance) { + _classCallCheck(this, ObjectId); + + this.space = space; + this.type = type; + this.instance = instance; + var instance_string = this.instance.toString(); + var _ObjectId = this.space + '.' + this.type + '.' + instance_string; + if (!v.is_digits(instance_string)) { + throw new ('Invalid object id ' + _ObjectId)(); + } + } + + _createClass(ObjectId, [{ + key: 'toLong', + value: function toLong() { + return Long.fromNumber(this.space).shiftLeft(56).or(Long.fromNumber(this.type).shiftLeft(48).or(this.instance)); + } + }, { + key: 'appendByteBuffer', + value: function appendByteBuffer(b) { + return b.writeUint64(this.toLong()); + } + }, { + key: 'toString', + value: function toString() { + return this.space + '.' + this.type + '.' + this.instance.toString(); + } + }], [{ + key: 'fromString', + value: function fromString(value) { + if (value.space !== undefined && value.type !== undefined && value.instance !== undefined) { + return value; + } + + var params = v.require_match(/^([0-9]+)\.([0-9]+)\.([0-9]+)$/, v.required(value, "ObjectId"), "ObjectId"); + return new ObjectId(parseInt(params[1]), parseInt(params[2]), Long.fromString(params[3])); + } + }, { + key: 'fromLong', + value: function fromLong(long) { + var space = long.shiftRight(56).toInt(); + var type = long.shiftRight(48).toInt() & 0x00ff; + var instance = long.and(DB_MAX_INSTANCE_ID); + return new ObjectId(space, type, instance); + } + }, { + key: 'fromByteBuffer', + value: function fromByteBuffer(b) { + return ObjectId.fromLong(b.readUint64()); + } + }]); + + return ObjectId; +}(); + +module.exports = ObjectId; \ No newline at end of file diff --git a/dist/chain/src/TransactionBuilder.js b/dist/chain/src/TransactionBuilder.js new file mode 100644 index 0000000..8057fcc --- /dev/null +++ b/dist/chain/src/TransactionBuilder.js @@ -0,0 +1,591 @@ +"use strict"; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; 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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var assert = require("assert"); + +var _require = require("../../ecc"), + Signature = _require.Signature, + PublicKey = _require.PublicKey, + hash = _require.hash; + +var _require2 = require("../../serializer"), + ops = _require2.ops; + +var _require3 = require('peerplaysjs-ws'), + Apis = _require3.Apis, + ChainConfig = _require3.ChainConfig; + +var ChainTypes = require('./ChainTypes'); +var head_block_time_string; + +var TransactionBuilder = function () { + function TransactionBuilder() { + _classCallCheck(this, TransactionBuilder); + + this.ref_block_num = 0; + this.ref_block_prefix = 0; + this.expiration = 0; + this.operations = []; + this.signatures = []; + this.signer_private_keys = []; + + // semi-private method bindings + this._broadcast = _broadcast.bind(this); + } + + /** + @arg {string} name - like "transfer" + @arg {object} operation - JSON matchching the operation's format + */ + + + _createClass(TransactionBuilder, [{ + key: "add_type_operation", + value: function add_type_operation(name, operation) { + this.add_operation(this.get_type_operation(name, operation)); + return; + } + + /** + This does it all: set fees, finalize, sign, and broadcast (if wanted). + @arg {ConfidentialWallet} cwallet - must be unlocked, used to gather signing keys + @arg {array} [signer_pubkeys = null] - Optional ["GPHAbc9Def0...", ...]. These are additional signing keys. Some balance claims require propritary address formats, the witness node can't tell us which ones are needed so they must be passed in. If the witness node can figure out a signing key (mostly all other transactions), it should not be passed in here. + @arg {boolean} [broadcast = false] + */ + + }, { + key: "process_transaction", + value: function process_transaction(cwallet) { + var _this = this; + + var signer_pubkeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var broadcast = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + + var wallet_object = cwallet.wallet.wallet_object; + if (Apis.instance().chain_id !== wallet_object.get("chain_id")) return Promise.reject("Mismatched chain_id; expecting " + wallet_object.get("chain_id") + ", but got " + Apis.instance().chain_id); + + return this.set_required_fees().then(function () { + var signer_pubkeys_added = {}; + if (signer_pubkeys) { + + // Balance claims are by address, only the private + // key holder can know about these additional + // potential keys. + var pubkeys = cwallet.getPubkeys_having_PrivateKey(signer_pubkeys); + if (!pubkeys.length) throw new Error("Missing signing key"); + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = pubkeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var pubkey_string = _step.value; + + var private_key = cwallet.getPrivateKey(pubkey_string); + _this.add_signer(private_key, pubkey_string); + signer_pubkeys_added[pubkey_string] = true; + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + + return _this.get_potential_signatures().then(function (_ref) { + var pubkeys = _ref.pubkeys, + addys = _ref.addys; + + var my_pubkeys = cwallet.getPubkeys_having_PrivateKey(pubkeys, addys); + + //{//Testing only, don't send All public keys! + // var pubkeys_all = PrivateKeyStore.getPubkeys() // All public keys + // this.get_required_signatures(pubkeys_all).then( required_pubkey_strings => + // console.log('get_required_signatures all\t',required_pubkey_strings.sort(), pubkeys_all)) + // this.get_required_signatures(my_pubkeys).then( required_pubkey_strings => + // console.log('get_required_signatures normal\t',required_pubkey_strings.sort(), pubkeys)) + //} + + return _this.get_required_signatures(my_pubkeys).then(function (required_pubkeys) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = required_pubkeys[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var _pubkey_string = _step2.value; + + if (signer_pubkeys_added[_pubkey_string]) continue; + var private_key = cwallet.getPrivateKey(_pubkey_string); + if (!private_key) + // This should not happen, get_required_signatures will only + // returned keys from my_pubkeys + throw new Error("Missing signing key for " + _pubkey_string); + _this.add_signer(private_key, _pubkey_string); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + }); + }).then(function () { + return broadcast ? _this.broadcast() : _this.serialize(); + }); + }); + } + + /** Typically this is called automatically just prior to signing. Once finalized this transaction can not be changed. */ + + }, { + key: "finalize", + value: function finalize() { + var _this2 = this; + + return new Promise(function (resolve, reject) { + + if (_this2.tr_buffer) { + throw new Error("already finalized"); + } + + resolve(Apis.instance().db_api().exec("get_objects", [["2.1.0"]]).then(function (r) { + head_block_time_string = r[0].time; + if (_this2.expiration === 0) _this2.expiration = base_expiration_sec() + ChainConfig.expire_in_secs; + _this2.ref_block_num = r[0].head_block_number & 0xFFFF; + _this2.ref_block_prefix = new Buffer(r[0].head_block_id, 'hex').readUInt32LE(4); + //DEBUG console.log("ref_block",@ref_block_num,@ref_block_prefix,r) + + var iterable = _this2.operations; + for (var i = 0, op; i < iterable.length; i++) { + op = iterable[i]; + if (op[1]["finalize"]) { + op[1].finalize(); + } + + var _type = ops.operation.st_operations[op[0]]; + var hexBuffer = _type.toBuffer(op[1]).toString("hex"); + console.log("Operation %s: %O => %s (%d bytes)", _type.operation_name, op[1], hexBuffer, hexBuffer.length / 2); + } + _this2.tr_buffer = ops.transaction.toBuffer(_this2); + })); + }); + } + + /** @return {string} hex transaction ID */ + + }, { + key: "id", + value: function id() { + if (!this.tr_buffer) { + throw new Error("not finalized"); + } + return hash.sha256(this.tr_buffer).toString('hex').substring(0, 40); + } + + /** + Typically one will use {@link this.add_type_operation} instead. + @arg {array} operation - [operation_id, operation] + */ + + }, { + key: "add_operation", + value: function add_operation(operation) { + if (this.tr_buffer) { + throw new Error("already finalized"); + } + assert(operation, "operation"); + if (!Array.isArray(operation)) { + throw new Error("Expecting array [operation_id, operation]"); + } + this.operations.push(operation); + return; + } + }, { + key: "get_type_operation", + value: function get_type_operation(name, operation) { + if (this.tr_buffer) { + throw new Error("already finalized"); + } + assert(name, "name"); + assert(operation, "operation"); + var _type = ops[name]; + assert(_type, "Unknown operation " + name); + var operation_id = ChainTypes.operations[_type.operation_name]; + if (operation_id === undefined) { + throw new Error("unknown operation: " + _type.operation_name); + } + if (!operation.fee) { + operation.fee = { amount: 0, asset_id: 0 }; + } + if (name === 'proposal_create') { + operation.expiration_time || (operation.expiration_time = base_expiration_sec() + ChainConfig.expire_in_secs_proposal); + } + var operation_instance = _type.fromObject(operation); + return [operation_id, operation_instance]; + } + + /** optional: there is a deafult expiration */ + + }, { + key: "set_expire_seconds", + value: function set_expire_seconds(sec) { + if (this.tr_buffer) { + throw new Error("already finalized"); + } + return this.expiration = base_expiration_sec() + sec; + } + + /* Wraps this transaction in a proposal_create transaction */ + + }, { + key: "propose", + value: function propose(proposal_create_options) { + if (this.tr_buffer) { + throw new Error("already finalized"); + } + if (!this.operations.length) { + throw new Error("add operation first"); + } + + assert(proposal_create_options, "proposal_create_options"); + assert(proposal_create_options.fee_paying_account, "proposal_create_options.fee_paying_account"); + + var proposed_ops = this.operations.map(function (op) { + return { op: op }; + }); + + this.operations = []; + this.signatures = []; + this.signer_private_keys = []; + proposal_create_options.proposed_ops = proposed_ops; + this.add_type_operation("proposal_create", proposal_create_options); + return this; + } + }, { + key: "has_proposed_operation", + value: function has_proposed_operation() { + var hasProposed = false; + for (var i = 0; i < this.operations.length; i++) { + if ("proposed_ops" in this.operations[i][1]) { + hasProposed = true; + break; + } + } + + return hasProposed; + } + + /** optional: the fees can be obtained from the witness node */ + + }, { + key: "set_required_fees", + value: function set_required_fees(asset_id) { + var _this3 = this; + + var fee_pool; + if (this.tr_buffer) { + throw new Error("already finalized"); + } + if (!this.operations.length) { + throw new Error("add operations first"); + } + var operations = []; + for (var i = 0, op; i < this.operations.length; i++) { + op = this.operations[i]; + operations.push(ops.operation.toObject(op)); + } + + if (!asset_id) { + var op1_fee = operations[0][1].fee; + if (op1_fee && op1_fee.asset_id !== null) { + asset_id = op1_fee.asset_id; + } else { + asset_id = "1.3.0"; + } + } + + var promises = [Apis.instance().db_api().exec("get_required_fees", [operations, asset_id])]; + + var feeAssetPromise = null; + if (asset_id !== "1.3.0") { + // This handles the fallback to paying fees in BTS if the fee pool is empty. + promises.push(Apis.instance().db_api().exec("get_required_fees", [operations, "1.3.0"])); + promises.push(Apis.instance().db_api().exec("get_objects", [[asset_id]])); + } + + return Promise.all(promises).then(function (results) { + var _results = _slicedToArray(results, 3), + fees = _results[0], + coreFees = _results[1], + asset = _results[2]; + + asset = asset ? asset[0] : null; + + var dynamicPromise = asset_id !== "1.3.0" && asset ? Apis.instance().db_api().exec("get_objects", [[asset.dynamic_asset_data_id]]) : new Promise(function (resolve, reject) { + resolve(); + }); + + return dynamicPromise.then(function (dynamicObject) { + if (asset_id !== "1.3.0") { + fee_pool = dynamicObject ? dynamicObject[0].fee_pool : 0; + var totalFees = 0; + for (var j = 0, fee; j < coreFees.length; j++) { + fee = coreFees[j]; + totalFees += fee.amount; + } + + if (totalFees > parseInt(fee_pool, 10)) { + fees = coreFees; + asset_id = "1.3.0"; + } + } + + // Proposed transactions need to be flattened + var flat_assets = []; + var flatten = function flatten(obj) { + if (Array.isArray(obj)) { + for (var k = 0, item; k < obj.length; k++) { + item = obj[k]; + flatten(item); + } + } else { + flat_assets.push(obj); + } + return; + }; + flatten(fees); + + var asset_index = 0; + + var set_fee = function set_fee(operation) { + if (!operation.fee || operation.fee.amount === 0 || operation.fee.amount.toString && operation.fee.amount.toString() === "0" // Long + ) { + operation.fee = flat_assets[asset_index]; + // console.log("new operation.fee", operation.fee) + } else { + // console.log("old operation.fee", operation.fee) + } + asset_index++; + if (operation.proposed_ops) { + var result = []; + for (var y = 0; y < operation.proposed_ops.length; y++) { + result.push(set_fee(operation.proposed_ops[y].op[1])); + }return result; + } + }; + for (var _i = 0; _i < _this3.operations.length; _i++) { + set_fee(_this3.operations[_i][1]); + } + }); + //DEBUG console.log('... get_required_fees',operations,asset_id,flat_assets) + }); + } + }, { + key: "get_potential_signatures", + value: function get_potential_signatures() { + var tr_object = ops.signed_transaction.toObject(this); + return Promise.all([Apis.instance().db_api().exec("get_potential_signatures", [tr_object]), Apis.instance().db_api().exec("get_potential_address_signatures", [tr_object])]).then(function (results) { + return { pubkeys: results[0], addys: results[1] }; + }); + } + }, { + key: "get_required_signatures", + value: function get_required_signatures(available_keys) { + if (!available_keys.length) { + return Promise.resolve([]); + } + var tr_object = ops.signed_transaction.toObject(this); + //DEBUG console.log('... tr_object',tr_object) + return Apis.instance().db_api().exec("get_required_signatures", [tr_object, available_keys]).then(function (required_public_keys) { + //DEBUG console.log('... get_required_signatures',required_public_keys) + return required_public_keys; + }); + } + }, { + key: "add_signer", + value: function add_signer(private_key) { + var public_key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : private_key.toPublicKey(); + + + assert(private_key.d, "required PrivateKey object"); + + if (this.signed) { + throw new Error("already signed"); + } + if (!public_key.Q) { + public_key = PublicKey.fromPublicKeyString(public_key); + } + // prevent duplicates + var spHex = private_key.toHex(); + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.signer_private_keys[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var sp = _step3.value; + + if (sp[0].toHex() === spHex) return; + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + this.signer_private_keys.push([private_key, public_key]); + } + }, { + key: "sign", + value: function sign() { + var chain_id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Apis.instance().chain_id; + + if (!this.tr_buffer) { + throw new Error("not finalized"); + } + if (this.signed) { + throw new Error("already signed"); + } + if (!this.signer_private_keys.length) { + throw new Error("Transaction was not signed. Do you have a private key? [no_signers]"); + } + var end = this.signer_private_keys.length; + for (var i = 0; 0 < end ? i < end : i > end; 0 < end ? i++ : i++) { + var _signer_private_keys$ = _slicedToArray(this.signer_private_keys[i], 2), + private_key = _signer_private_keys$[0], + public_key = _signer_private_keys$[1]; + + var sig = Signature.signBuffer(Buffer.concat([new Buffer(chain_id, 'hex'), this.tr_buffer]), private_key, public_key); + this.signatures.push(sig.toBuffer()); + } + this.signer_private_keys = []; + this.signed = true; + return; + } + }, { + key: "serialize", + value: function serialize() { + return ops.signed_transaction.toObject(this); + } + }, { + key: "toObject", + value: function toObject() { + return ops.signed_transaction.toObject(this); + } + }, { + key: "broadcast", + value: function broadcast(was_broadcast_callback) { + var _this4 = this; + + if (this.tr_buffer) { + return this._broadcast(was_broadcast_callback); + } else { + return this.finalize().then(function () { + return _this4._broadcast(was_broadcast_callback); + }); + } + } + }]); + + return TransactionBuilder; +}(); + +var base_expiration_sec = function base_expiration_sec() { + var head_block_sec = Math.ceil(getHeadBlockDate().getTime() / 1000); + var now_sec = Math.ceil(Date.now() / 1000); + // The head block time should be updated every 3 seconds. If it isn't + // then help the transaction to expire (use head_block_sec) + if (now_sec - head_block_sec > 30) { + return head_block_sec; + } + // If the user's clock is very far behind, use the head block time. + return Math.max(now_sec, head_block_sec); +}; + +function _broadcast(was_broadcast_callback) { + var _this5 = this; + + return new Promise(function (resolve, reject) { + + if (!_this5.signed) { + _this5.sign(); + } + if (!_this5.tr_buffer) { + throw new Error("not finalized"); + } + if (!_this5.signatures.length) { + throw new Error("not signed"); + } + if (!_this5.operations.length) { + throw new Error("no operations"); + } + + var tr_object = ops.signed_transaction.toObject(_this5); + // console.log('... broadcast_transaction_with_callback !!!') + Apis.instance().network_api().exec("broadcast_transaction_with_callback", [function (res) { + return resolve(res); + }, tr_object]).then(function () { + //console.log('... broadcast success, waiting for callback') + if (was_broadcast_callback) was_broadcast_callback(); + return; + }).catch(function (error) { + // console.log may be redundant for network errors, other errors could occur + console.log(error); + var message = error.message; + if (!message) { + message = ""; + } + reject(new Error(message + "\n" + 'graphene-crypto ' + ' digest ' + hash.sha256(_this5.tr_buffer).toString('hex') + ' transaction ' + _this5.tr_buffer.toString('hex') + ' ' + JSON.stringify(tr_object))); + return; + }); + return; + }); +} + +function getHeadBlockDate() { + return timeStringToDate(head_block_time_string); +} + +function timeStringToDate(time_string) { + if (!time_string) return new Date("1970-01-01T00:00:00.000Z"); + if (!/Z$/.test(time_string)) //does not end in Z + // https://github.com/cryptonomex/graphene/issues/368 + time_string = time_string + "Z"; + return new Date(time_string); +} + +module.exports = TransactionBuilder; \ No newline at end of file diff --git a/dist/chain/src/TransactionHelper.js b/dist/chain/src/TransactionHelper.js new file mode 100644 index 0000000..238173f --- /dev/null +++ b/dist/chain/src/TransactionHelper.js @@ -0,0 +1,104 @@ +'use strict'; + +var helper; +module.exports = helper = {}; + +var secureRandom = require('secure-random'); + +//Promise = require '../common/Promise' + +var _require = require('bytebuffer'), + Long = _require.Long; + +var _require2 = require("../../ecc"), + Signature = _require2.Signature; + +var _require3 = require("../../serializer"), + ops = _require3.ops; + +var _require4 = require("peerplaysjs-ws"), + Apis = _require4.Apis; + +helper.unique_nonce_entropy = null; +helper.unique_nonce_uint64 = function () { + var entropy = helper.unique_nonce_entropy = function () { + + if (helper.unique_nonce_entropy === null) { + //console.log('... secureRandom.randomUint8Array(1)[0]',secureRandom.randomUint8Array(1)[0]) + return parseInt(secureRandom.randomUint8Array(1)[0]); + } else { + return ++helper.unique_nonce_entropy % 256; + } + }(); + var long = Long.fromNumber(Date.now()); + //console.log('unique_nonce_uint64 date\t',ByteBuffer.allocate(8).writeUint64(long).toHex(0)) + //console.log('unique_nonce_uint64 entropy\t',ByteBuffer.allocate(8).writeUint64(Long.fromNumber(entropy)).toHex(0)) + long = long.shiftLeft(8).or(Long.fromNumber(entropy)); + //console.log('unique_nonce_uint64 shift8\t',ByteBuffer.allocate(8).writeUint64(long).toHex(0)) + return long.toString(); +}; + +/* Todo, set fees */ +helper.to_json = function (tr) { + var broadcast = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + return function (tr, broadcast) { + var tr_object = ops.signed_transaction.toObject(tr); + if (broadcast) { + var net = Apis.instance().network_api(); + console.log('... tr_object', JSON.stringify(tr_object)); + return net.exec("broadcast_transaction", [tr_object]); + } else { + return tr_object; + } + }(tr, broadcast); +}; + +helper.signed_tr_json = function (tr, private_keys) { + var tr_buffer = ops.transaction.toBuffer(tr); + tr = ops.transaction.toObject(tr); + tr.signatures = function () { + var result = []; + for (var i = 0; 0 < private_keys.length ? i < private_keys.length : i > private_keys.length; 0 < private_keys.length ? i++ : i++) { + var private_key = private_keys[i]; + result.push(Signature.signBuffer(tr_buffer, private_key).toHex()); + } + return result; + }(); + return tr; +}; + +helper.expire_in_min = function (min) { + return Math.round(Date.now() / 1000) + min * 60; +}; + +helper.seconds_from_now = function (timeout_sec) { + return Math.round(Date.now() / 1000) + timeout_sec; +}; + +/** + Print to the console a JSON representation of any object in + @graphene/serializer { types } +*/ +helper.template = function (serializer_operation_type_name) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { use_default: true, annotate: true }; + + var so = type[serializer_operation_type_name]; + if (!so) { + throw new Error('unknown serializer_operation_type ' + serializer_operation_type_name); + } + return so.toObject(undefined, debug); +}; + +helper.new_operation = function (serializer_operation_type_name) { + var so = type[serializer_operation_type_name]; + if (!so) { + throw new Error('unknown serializer_operation_type ' + serializer_operation_type_name); + } + var object = so.toObject(undefined, { use_default: true, annotate: true }); + return so.fromObject(object); +}; + +helper.instance = function (ObjectId) { + return ObjectId.substring("0.0.".length); +}; \ No newline at end of file diff --git a/dist/chain/src/state.js b/dist/chain/src/state.js new file mode 100644 index 0000000..42971a3 --- /dev/null +++ b/dist/chain/src/state.js @@ -0,0 +1,19 @@ +"use strict"; + +function get(state) { + return function (key) { + return state[key] || ""; + }; +} + +function set(state) { + return function (key, value) { + state[key] = value; + return this; + }; +} + +module.exports = { + get: get, + set: set +}; \ No newline at end of file diff --git a/dist/ecc/index.js b/dist/ecc/index.js new file mode 100644 index 0000000..0444359 --- /dev/null +++ b/dist/ecc/index.js @@ -0,0 +1,12 @@ +"use strict"; + +module.exports = { + Address: require("./src/address"), + Aes: require("./src/aes"), + PrivateKey: require("./src/PrivateKey"), + PublicKey: require("./src/PublicKey"), + Signature: require("./src/signature"), + brainKey: require("./src/BrainKey"), + hash: require("./src/hash"), + key: require("./src/KeyUtils") +}; \ No newline at end of file diff --git a/dist/ecc/src/BrainKey.js b/dist/ecc/src/BrainKey.js new file mode 100644 index 0000000..998b065 --- /dev/null +++ b/dist/ecc/src/BrainKey.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function normalize(brainKey) { + if (typeof brainKey !== 'string') { + throw new Error("string required for brainKey"); + } + brainKey = brainKey.trim(); + return brainKey.split(/[\t\n\v\f\r ]+/).join(' '); +}; \ No newline at end of file diff --git a/dist/ecc/src/KeyUtils.js b/dist/ecc/src/KeyUtils.js new file mode 100644 index 0000000..f993222 --- /dev/null +++ b/dist/ecc/src/KeyUtils.js @@ -0,0 +1,202 @@ +'use strict'; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; 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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var key; +var PrivateKey = require('./PrivateKey'); +var PublicKey = require('./PublicKey'); +var Address = require('./address'); +var Aes = require('./aes'); + +var hash = require('./hash'); +// var dictionary = require('./dictionary_en'); +var secureRandom = require('secure-random'); + +var _require = require('peerplaysjs-ws'), + ChainConfig = _require.ChainConfig; + +// hash for .25 second + + +var HASH_POWER_MILLS = 250; + +module.exports = key = { + + /** Uses 1 second of hashing power to create a key/password checksum. An + implementation can re-call this method with the same password to re-match + the strength of the CPU (either after moving from a desktop to a mobile, + mobile to desktop, or N years from now when CPUs are presumably stronger). + A salt is used for all the normal reasons... + @return object { + aes_private: Aes, + checksum: "{hash_iteration_count},{salt},{checksum}" + } + */ + aes_checksum: function aes_checksum(password) { + if (!(typeof password === "string")) { + throw new "password string required"(); + } + var salt = secureRandom.randomBuffer(4).toString('hex'); + var iterations = 0; + var secret = salt + password; + // hash for .1 second + var start_t = Date.now(); + while (Date.now() - start_t < HASH_POWER_MILLS) { + secret = hash.sha256(secret); + iterations += 1; + } + + var checksum = hash.sha256(secret); + var checksum_string = [iterations, salt.toString('hex'), checksum.slice(0, 4).toString('hex')].join(','); + + return { aes_private: Aes.fromSeed(secret), + checksum: checksum_string + }; + }, + + + /** Provide a matching password and key_checksum. A "wrong password" + error is thrown if the password does not match. If this method takes + much more or less than 1 second to return, one should consider updating + all encyrpted fields using a new key.key_checksum. + */ + aes_private: function aes_private(password, key_checksum) { + var _key_checksum$split = key_checksum.split(','), + _key_checksum$split2 = _slicedToArray(_key_checksum$split, 3), + iterations = _key_checksum$split2[0], + salt = _key_checksum$split2[1], + checksum = _key_checksum$split2[2]; + + var secret = salt + password; + for (var i = 0; 0 < iterations ? i < iterations : i > iterations; 0 < iterations ? i++ : i++) { + secret = hash.sha256(secret); + } + var new_checksum = hash.sha256(secret); + if (!(new_checksum.slice(0, 4).toString('hex') === checksum)) { + throw new Error("wrong password"); + } + return Aes.fromSeed(secret); + }, + + + /** + A week random number generator can run out of entropy. This should ensure even the worst random number implementation will be reasonably safe. + @param1 string entropy of at least 32 bytes + */ + random32ByteBuffer: function random32ByteBuffer() { + var entropy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.browserEntropy(); + + + if (!(typeof entropy === 'string')) { + throw new Error("string required for entropy"); + } + + if (entropy.length < 32) { + throw new Error("expecting at least 32 bytes of entropy"); + } + + var start_t = Date.now(); + + while (Date.now() - start_t < HASH_POWER_MILLS) { + entropy = hash.sha256(entropy); + }var hash_array = []; + hash_array.push(entropy); + + // Hashing for 1 second may helps the computer is not low on entropy (this method may be called back-to-back). + hash_array.push(secureRandom.randomBuffer(32)); + + return hash.sha256(Buffer.concat(hash_array)); + }, + + + suggest_brain_key: function suggest_brain_key() { + var dictionary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ","; + var entropy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.browserEntropy(); + + + var randomBuffer = this.random32ByteBuffer(entropy); + + var word_count = 16; + var dictionary_lines = dictionary.split(','); + + if (!(dictionary_lines.length === 49744)) { + throw new Error('expecting ' + 49744 + ' but got ' + dictionary_lines.length + ' dictionary words'); + } + + var brainkey = []; + var end = word_count * 2; + + for (var i = 0; i < end; i += 2) { + + // randomBuffer has 256 bits / 16 bits per word == 16 words + var num = (randomBuffer[i] << 8) + randomBuffer[i + 1]; + + // convert into a number between 0 and 1 (inclusive) + var rndMultiplier = num / Math.pow(2, 16); + var wordIndex = Math.round(dictionary_lines.length * rndMultiplier); + + brainkey.push(dictionary_lines[wordIndex]); + } + return this.normalize_brainKey(brainkey.join(' ')); + }, + + get_random_key: function get_random_key(entropy) { + return PrivateKey.fromBuffer(this.random32ByteBuffer(entropy)); + }, + get_brainPrivateKey: function get_brainPrivateKey(brainKey) { + var sequence = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + + if (sequence < 0) { + throw new Error("invalid sequence"); + } + brainKey = key.normalize_brainKey(brainKey); + return PrivateKey.fromBuffer(hash.sha256(hash.sha512(brainKey + " " + sequence))); + }, + + + // Turn invisible space like characters into a single space + normalize_brainKey: function normalize_brainKey(brainKey) { + if (!(typeof brainKey === 'string')) { + throw new Error("string required for brainKey"); + } + + brainKey = brainKey.trim(); + return brainKey.split(/[\t\n\v\f\r ]+/).join(' '); + }, + browserEntropy: function browserEntropy() { + + var entropyStr = ""; + try { + entropyStr = new Date().toString() + " " + window.screen.height + " " + window.screen.width + " " + window.screen.colorDepth + " " + " " + window.screen.availHeight + " " + window.screen.availWidth + " " + window.screen.pixelDepth + navigator.language + " " + window.location + " " + window.history.length; + + for (var i = 0, mimeType; i < navigator.mimeTypes.length; i++) { + mimeType = navigator.mimeTypes[i]; + entropyStr += mimeType.description + " " + mimeType.type + " " + mimeType.suffixes + " "; + } + console.log("INFO\tbrowserEntropy gathered"); + } catch (error) { + //nodejs:ReferenceError: window is not defined + entropyStr = hash.sha256(new Date().toString()); + } + + var b = new Buffer(entropyStr); + entropyStr += b.toString('binary') + " " + new Date().toString(); + return entropyStr; + }, + + + // @return array of 5 legacy addresses for a pubkey string parameter. + addresses: function addresses(pubkey) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ChainConfig.address_prefix; + + var public_key = PublicKey.fromPublicKeyString(pubkey, address_prefix); + // S L O W + var address_string = [Address.fromPublic(public_key, false, 0).toString(address_prefix), // btc_uncompressed + Address.fromPublic(public_key, true, 0).toString(address_prefix), // btc_compressed + Address.fromPublic(public_key, false, 56).toString(address_prefix), // pts_uncompressed + Address.fromPublic(public_key, true, 56).toString(address_prefix), // pts_compressed + public_key.toAddressString(address_prefix) // bts_short, most recent format + ]; + return address_string; + } +}; \ No newline at end of file diff --git a/dist/ecc/src/PrivateKey.js b/dist/ecc/src/PrivateKey.js new file mode 100644 index 0000000..8f4bfdc --- /dev/null +++ b/dist/ecc/src/PrivateKey.js @@ -0,0 +1,213 @@ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var ecurve = require('ecurve'); + +var _require = require('ecurve'), + Point = _require.Point, + getCurveByName = _require.getCurveByName; + +var secp256k1 = getCurveByName('secp256k1'); +var BigInteger = require('bigi'); + +var _require2 = require('bs58'), + encode = _require2.encode, + decode = _require2.decode; + +var assert = require('assert'); +var hash = require('./hash'); +var PublicKey = require('./PublicKey'); +var deepEqual = require("deep-equal"); + +var G = secp256k1.G, + n = secp256k1.n; + +var PrivateKey = function () { + + /** + @private see static functions + @param {BigInteger} + */ + function PrivateKey(d) { + _classCallCheck(this, PrivateKey); + + this.d = d; + } + + _createClass(PrivateKey, [{ + key: 'toWif', + value: function toWif() { + var private_key = this.toBuffer(); + // checksum includes the version + private_key = Buffer.concat([new Buffer([0x80]), private_key]); + var checksum = hash.sha256(private_key); + checksum = hash.sha256(checksum); + checksum = checksum.slice(0, 4); + var private_wif = Buffer.concat([private_key, checksum]); + return encode(private_wif); + } + + /** + @return {Point} + */ + + }, { + key: 'toPublicKeyPoint', + value: function toPublicKeyPoint() { + var Q; + return Q = secp256k1.G.multiply(this.d); + } + }, { + key: 'toPublicKey', + value: function toPublicKey() { + if (this.public_key) { + return this.public_key; + } + return this.public_key = PublicKey.fromPoint(this.toPublicKeyPoint()); + } + }, { + key: 'toBuffer', + value: function toBuffer() { + return this.d.toBuffer(32); + } + + /** ECIES */ + + }, { + key: 'get_shared_secret', + value: function get_shared_secret(public_key) { + var legacy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + public_key = toPublic(public_key); + var KB = public_key.toUncompressed().toBuffer(); + var KBP = Point.fromAffine(secp256k1, BigInteger.fromBuffer(KB.slice(1, 33)), // x + BigInteger.fromBuffer(KB.slice(33, 65)) // y + ); + var r = this.toBuffer(); + var P = KBP.multiply(BigInteger.fromBuffer(r)); + var S = P.affineX.toBuffer({ size: 32 }); + /* + the input to sha512 must be exactly 32-bytes, to match the c++ implementation + of get_shared_secret. Right now S will be shorter if the most significant + byte(s) is zero. Pad it back to the full 32-bytes + */ + if (!legacy && S.length < 32) { + pad = new Buffer(32 - S.length).fill(0); + S = Buffer.concat([pad, S]); + } + + // SHA512 used in ECIES + return hash.sha512(S); + } + + // /** ECIES (does not always match the Point.fromAffine version above) */ + // get_shared_secret(public_key){ + // public_key = toPublic(public_key) + // var P = public_key.Q.multiply( this.d ); + // var S = P.affineX.toBuffer({size: 32}); + // // ECIES, adds an extra sha512 + // return hash.sha512(S); + // } + + /** @throws {Error} - overflow of the key could not be derived */ + + }, { + key: 'child', + value: function child(offset) { + offset = Buffer.concat([this.toPublicKey().toBuffer(), offset]); + offset = hash.sha256(offset); + var c = BigInteger.fromBuffer(offset); + + if (c.compareTo(n) >= 0) throw new Error("Child offset went out of bounds, try again"); + + var derived = this.d.add(c); //.mod(n) + + if (derived.signum() === 0) throw new Error("Child offset derived to an invalid key, try again"); + + return new PrivateKey(derived); + } + + /* */ + + }, { + key: 'toByteBuffer', + value: function toByteBuffer() { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + } + }, { + key: 'toHex', + value: function toHex() { + return this.toBuffer().toString('hex'); + } + + /* */ + + }], [{ + key: 'fromBuffer', + value: function fromBuffer(buf) { + if (!Buffer.isBuffer(buf)) { + throw new Error("Expecting paramter to be a Buffer type"); + } + if (32 !== buf.length) { + console.log('WARN: Expecting 32 bytes, instead got ' + buf.length + ', stack trace:', new Error().stack); + } + if (buf.length === 0) { + throw new Error("Empty buffer"); + } + return new PrivateKey(BigInteger.fromBuffer(buf)); + } + + /** @arg {string} seed - any length string. This is private, the same seed produces the same private key every time. */ + + }, { + key: 'fromSeed', + value: function fromSeed(seed) { + // generate_private_key + if (!(typeof seed === 'string')) { + throw new Error('seed must be of type string'); + } + return PrivateKey.fromBuffer(hash.sha256(seed)); + } + + /** @return {string} Wallet Import Format (still a secret, Not encrypted) */ + + }, { + key: 'fromWif', + value: function fromWif(_private_wif) { + var private_wif = new Buffer(decode(_private_wif)); + var version = private_wif.readUInt8(0); + assert.equal(0x80, version, 'Expected version ' + 0x80 + ', instead got ' + version); + // checksum includes the version + var private_key = private_wif.slice(0, -4); + var checksum = private_wif.slice(-4); + var new_checksum = hash.sha256(private_key); + new_checksum = hash.sha256(new_checksum); + new_checksum = new_checksum.slice(0, 4); + var isEqual = deepEqual(checksum, new_checksum); //, 'Invalid checksum' + if (!isEqual) { + throw new Error("Checksum did not match"); + } + private_key = private_key.slice(1); + private_key = private_key.slice(0, 32); + return PrivateKey.fromBuffer(private_key); + } + }, { + key: 'fromHex', + value: function fromHex(hex) { + return PrivateKey.fromBuffer(new Buffer(hex, 'hex')); + } + }]); + + return PrivateKey; +}(); + +module.exports = PrivateKey; + +var toPublic = function toPublic(data) { + return data == null ? data : data.Q ? data : PublicKey.fromStringOrThrow(data); +}; \ No newline at end of file diff --git a/dist/ecc/src/PublicKey.js b/dist/ecc/src/PublicKey.js new file mode 100644 index 0000000..a04d063 --- /dev/null +++ b/dist/ecc/src/PublicKey.js @@ -0,0 +1,236 @@ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var BigInteger = require('bigi'); + +var _require = require('ecurve'), + Point = _require.Point, + getCurveByName = _require.getCurveByName; + +var secp256k1 = getCurveByName('secp256k1'); + +var _require2 = require('bs58'), + encode = _require2.encode, + decode = _require2.decode; + +var hash = require('./hash'); + +var _require3 = require('peerplaysjs-ws'), + ChainConfig = _require3.ChainConfig; + +var assert = require('assert'); +var deepEqual = require("deep-equal"); + +var G = secp256k1.G, + n = secp256k1.n; + +var PublicKey = function () { + + /** @param {Point} public key */ + function PublicKey(Q) { + _classCallCheck(this, PublicKey); + + this.Q = Q; + } + + _createClass(PublicKey, [{ + key: 'toBuffer', + value: function toBuffer() { + var compressed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.Q ? this.Q.compressed : null; + + if (this.Q === null) return new Buffer('000000000000000000000000000000000000000000000000000000000000000000', 'hex'); + return this.Q.getEncoded(compressed); + } + }, { + key: 'toUncompressed', + value: function toUncompressed() { + var buf = this.Q.getEncoded(false); + var point = Point.decodeFrom(secp256k1, buf); + return PublicKey.fromPoint(point); + } + + /** bts::blockchain::address (unique but not a full public key) */ + + }, { + key: 'toBlockchainAddress', + value: function toBlockchainAddress() { + var pub_buf = this.toBuffer(); + var pub_sha = hash.sha512(pub_buf); + return hash.ripemd160(pub_sha); + } + + /** Alias for {@link toPublicKeyString} */ + + }, { + key: 'toString', + value: function toString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChainConfig.address_prefix; + + return this.toPublicKeyString(address_prefix); + } + + /** + Full public key + {return} string + */ + + }, { + key: 'toPublicKeyString', + value: function toPublicKeyString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChainConfig.address_prefix; + + var pub_buf = this.toBuffer(); + var checksum = hash.ripemd160(pub_buf); + // Slice from the buffer directly, slicing from the checksum Uint8array will return the entire array each time. + var sliced = new Uint8Array(checksum.buffer.slice(0, 4)); + + // concat only accepts buffers so initialize the sliced Uint8array as a Buffer. + var addy = Buffer.concat([pub_buf, Buffer.from(sliced)]); + return address_prefix + encode(addy); + } + + /** + @arg {string} public_key - like GPHXyz... + @arg {string} address_prefix - like GPH + @return PublicKey or `null` (if the public_key string is invalid) + */ + + }, { + key: 'toAddressString', + value: function toAddressString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChainConfig.address_prefix; + + var pub_buf = this.toBuffer(); + var pub_sha = hash.sha512(pub_buf); + var addy = hash.ripemd160(pub_sha); + var checksum = hash.ripemd160(addy); + addy = Buffer.concat([addy, checksum.slice(0, 4)]); + return address_prefix + encode(addy); + } + }, { + key: 'toPtsAddy', + value: function toPtsAddy() { + var pub_buf = this.toBuffer(); + var pub_sha = hash.sha256(pub_buf); + var addy = hash.ripemd160(pub_sha); + addy = Buffer.concat([new Buffer([0x38]), addy]); //version 56(decimal) + + var checksum = hash.sha256(addy); + checksum = hash.sha256(checksum); + + addy = Buffer.concat([addy, checksum.slice(0, 4)]); + return encode(addy); + } + }, { + key: 'child', + value: function child(offset) { + + assert(Buffer.isBuffer(offset), "Buffer required: offset"); + assert.equal(offset.length, 32, "offset length"); + + offset = Buffer.concat([this.toBuffer(), offset]); + offset = hash.sha256(offset); + + var c = BigInteger.fromBuffer(offset); + + if (c.compareTo(n) >= 0) throw new Error("Child offset went out of bounds, try again"); + + var cG = G.multiply(c); + var Qprime = this.Q.add(cG); + + if (secp256k1.isInfinity(Qprime)) throw new Error("Child offset derived to an invalid key, try again"); + + return PublicKey.fromPoint(Qprime); + } + + /* */ + + }, { + key: 'toByteBuffer', + value: function toByteBuffer() { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + } + }, { + key: 'toHex', + value: function toHex() { + return this.toBuffer().toString('hex'); + } + }], [{ + key: 'fromBinary', + value: function fromBinary(bin) { + return PublicKey.fromBuffer(new Buffer(bin, 'binary')); + } + }, { + key: 'fromBuffer', + value: function fromBuffer(buffer) { + if (buffer.toString('hex') === '000000000000000000000000000000000000000000000000000000000000000000') return new PublicKey(null); + return new PublicKey(Point.decodeFrom(secp256k1, buffer)); + } + }, { + key: 'fromPoint', + value: function fromPoint(point) { + return new PublicKey(point); + } + }, { + key: 'fromPublicKeyString', + value: function fromPublicKeyString(public_key) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ChainConfig.address_prefix; + + try { + return PublicKey.fromStringOrThrow(public_key, address_prefix); + } catch (e) { + return null; + } + } + + /** + @arg {string} public_key - like GPHXyz... + @arg {string} address_prefix - like GPH + @throws {Error} if public key is invalid + @return PublicKey + */ + + }, { + key: 'fromStringOrThrow', + value: function fromStringOrThrow(public_key) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ChainConfig.address_prefix; + + var prefix = public_key.slice(0, address_prefix.length); + assert.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix); + public_key = public_key.slice(address_prefix.length); + + public_key = new Buffer(decode(public_key), 'binary'); + var checksum = public_key.slice(-4); + public_key = public_key.slice(0, -4); + var new_checksum = hash.ripemd160(public_key); + new_checksum = new_checksum.slice(0, 4); + var isEqual = deepEqual(checksum, new_checksum); //, 'Invalid checksum' + if (!isEqual) { + throw new Error("Checksum did not match"); + } + return PublicKey.fromBuffer(public_key); + } + }, { + key: 'fromHex', + value: function fromHex(hex) { + return PublicKey.fromBuffer(new Buffer(hex, 'hex')); + } + }, { + key: 'fromPublicKeyStringHex', + value: function fromPublicKeyStringHex(hex) { + return PublicKey.fromPublicKeyString(new Buffer(hex, 'hex')); + } + + /* */ + + }]); + + return PublicKey; +}(); + +module.exports = PublicKey; \ No newline at end of file diff --git a/dist/ecc/src/address.js b/dist/ecc/src/address.js new file mode 100644 index 0000000..919b85d --- /dev/null +++ b/dist/ecc/src/address.js @@ -0,0 +1,95 @@ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var assert = require('assert'); + +var _require = require('peerplaysjs-ws'), + ChainConfig = _require.ChainConfig; + +var hash = require('./hash'); + +var _require2 = require('bs58'), + encode = _require2.encode, + decode = _require2.decode; + +var deepEqual = require("deep-equal"); + +/** Addresses are shortened non-reversable hashes of a public key. The full PublicKey is preferred. + @deprecated +*/ + +var Address = function () { + function Address(addy) { + _classCallCheck(this, Address); + + this.addy = addy; + } + + _createClass(Address, [{ + key: 'toBuffer', + value: function toBuffer() { + return this.addy; + } + }, { + key: 'toString', + value: function toString() { + var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChainConfig.address_prefix; + + var checksum = hash.ripemd160(this.addy); + var addy = Buffer.concat([this.addy, checksum.slice(0, 4)]); + return address_prefix + encode(addy); + } + }], [{ + key: 'fromBuffer', + value: function fromBuffer(buffer) { + var _hash = hash.sha512(buffer); + var addy = hash.ripemd160(_hash); + return new Address(addy); + } + }, { + key: 'fromString', + value: function fromString(string) { + var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ChainConfig.address_prefix; + + var prefix = string.slice(0, address_prefix.length); + assert.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix); + var addy = string.slice(address_prefix.length); + addy = new Buffer(decode(addy), 'binary'); + var checksum = addy.slice(-4); + addy = addy.slice(0, -4); + var new_checksum = hash.ripemd160(addy); + new_checksum = new_checksum.slice(0, 4); + var isEqual = deepEqual(checksum, new_checksum); //, 'Invalid checksum' + if (!isEqual) { + throw new Error("Checksum did not match"); + } + return new Address(addy); + } + }, { + key: 'fromPublic', + + + /** @return Address - Compressed PTS format (by default) */ + value: function fromPublic(public_key) { + var compressed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var version = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 56; + + var sha2 = hash.sha256(public_key.toBuffer(compressed)); + var rep = hash.ripemd160(sha2); + var versionBuffer = new Buffer(1); + versionBuffer.writeUInt8(0xFF & version, 0); + var addr = Buffer.concat([versionBuffer, rep]); + var check = hash.sha256(addr); + check = hash.sha256(check); + var buffer = Buffer.concat([addr, check.slice(0, 4)]); + return new Address(hash.ripemd160(buffer)); + } + }]); + + return Address; +}(); + +module.exports = Address; \ No newline at end of file diff --git a/dist/ecc/src/aes.js b/dist/ecc/src/aes.js new file mode 100644 index 0000000..42f7487 --- /dev/null +++ b/dist/ecc/src/aes.js @@ -0,0 +1,308 @@ +"use strict"; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +// https://code.google.com/p/crypto-js +var AES = require("crypto-js/aes"); +var encHex = require("crypto-js/enc-hex"); +var encBase64 = require("crypto-js/enc-base64"); +var assert = require("assert"); + +var _require = require("bytebuffer"), + Long = _require.Long; + +var hash = require('./hash'); + +/** Provides symetric encrypt and decrypt via AES. */ + +var Aes = function () { + + /** @private */ + function Aes(iv, key) { + _classCallCheck(this, Aes); + + this.iv = iv, this.key = key; + } + + /** This is an excellent way to ensure that all references to Aes can not operate anymore (example: a wallet becomes locked). An application should ensure there is only one Aes object instance for a given secret `seed`. */ + + + _createClass(Aes, [{ + key: "clear", + value: function clear() { + return this.iv = this.key = undefined; + } + + /** @arg {string} seed - secret seed may be used to encrypt or decrypt. */ + + }, { + key: "_decrypt_word_array", + + + /** @private */ + value: function _decrypt_word_array(cipher) { + // https://code.google.com/p/crypto-js/#Custom_Key_and_IV + // see wallet_records.cpp master_key::decrypt_key + return AES.decrypt({ ciphertext: cipher, salt: null }, this.key, { iv: this.iv }); + } + + /** @private */ + + }, { + key: "_encrypt_word_array", + value: function _encrypt_word_array(plaintext) { + //https://code.google.com/p/crypto-js/issues/detail?id=85 + var cipher = AES.encrypt(plaintext, this.key, { iv: this.iv }); + return encBase64.parse(cipher.toString()); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} ciphertext + @return {Buffer} binary + */ + + }, { + key: "decrypt", + value: function decrypt(ciphertext) { + if (typeof ciphertext === "string") { + ciphertext = new Buffer(ciphertext, 'binary'); + } + if (!Buffer.isBuffer(ciphertext)) { + throw new Error("buffer required"); + } + assert(ciphertext, "Missing cipher text"); + // hex is the only common format + var hex = this.decryptHex(ciphertext.toString('hex')); + return new Buffer(hex, 'hex'); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} plaintext + @return {Buffer} binary + */ + + }, { + key: "encrypt", + value: function encrypt(plaintext) { + if (typeof plaintext === "string") { + plaintext = new Buffer(plaintext, 'binary'); + } + if (!Buffer.isBuffer(plaintext)) { + throw new Error("buffer required"); + } + //assert plaintext, "Missing plain text" + // hex is the only common format + var hex = this.encryptHex(plaintext.toString('hex')); + return new Buffer(hex, 'hex'); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string|Buffer} plaintext + @return {string} hex + */ + + }, { + key: "encryptToHex", + value: function encryptToHex(plaintext) { + if (typeof plaintext === "string") { + plaintext = new Buffer(plaintext, 'binary'); + } + if (!Buffer.isBuffer(plaintext)) { + throw new Error("buffer required"); + } + //assert plaintext, "Missing plain text" + // hex is the only common format + return this.encryptHex(plaintext.toString('hex')); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @return {string} binary (could easily be readable text) + */ + + }, { + key: "decryptHex", + value: function decryptHex(cipher) { + assert(cipher, "Missing cipher text"); + // Convert data into word arrays (used by Crypto) + var cipher_array = encHex.parse(cipher); + var plainwords = this._decrypt_word_array(cipher_array); + return encHex.stringify(plainwords); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @return {Buffer} encoded as specified by the parameter + */ + + }, { + key: "decryptHexToBuffer", + value: function decryptHexToBuffer(cipher) { + assert(cipher, "Missing cipher text"); + // Convert data into word arrays (used by Crypto) + var cipher_array = encHex.parse(cipher); + var plainwords = this._decrypt_word_array(cipher_array); + var plainhex = encHex.stringify(plainwords); + return new Buffer(plainhex, 'hex'); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @arg {string} [encoding = 'binary'] - a valid Buffer encoding + @return {String} encoded as specified by the parameter + */ + + }, { + key: "decryptHexToText", + value: function decryptHexToText(cipher) { + var encoding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'binary'; + + return this.decryptHexToBuffer(cipher).toString(encoding); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} plainhex - hex format + @return {String} hex + */ + + }, { + key: "encryptHex", + value: function encryptHex(plainhex) { + var plain_array = encHex.parse(plainhex); + var cipher_array = this._encrypt_word_array(plain_array); + return encHex.stringify(cipher_array); + } + }], [{ + key: "fromSeed", + value: function fromSeed(seed) { + if (seed === undefined) { + throw new Error("seed is required"); + } + var _hash = hash.sha512(seed); + _hash = _hash.toString('hex'); + // DEBUG console.log('... fromSeed _hash',_hash) + return Aes.fromSha512(_hash); + } + }, { + key: "fromSha512", + + + /** @arg {string} hash - A 128 byte hex string, typically one would call {@link fromSeed} instead. */ + value: function fromSha512(hash) { + assert.equal(hash.length, 128, "A Sha512 in HEX should be 128 characters long, instead got " + hash.length); + var iv = encHex.parse(hash.substring(64, 96)); + var key = encHex.parse(hash.substring(0, 64)); + return new Aes(iv, key); + } + }, { + key: "fromBuffer", + value: function fromBuffer(buf) { + assert(Buffer.isBuffer(buf), "Expecting Buffer"); + assert.equal(buf.length, 64, "A Sha512 Buffer should be 64 characters long, instead got " + buf.length); + return Aes.fromSha512(buf.toString("hex")); + } + /** + @throws {Error} - "Invalid Key, ..." + @arg {PrivateKey} private_key - required and used for decryption + @arg {PublicKey} public_key - required and used to calcualte the shared secret + @arg {string} [nonce = ""] optional but should always be provided and be unique when re-using the same private/public keys more than once. This nonce is not a secret. + @arg {string|Buffer} message - Encrypted message containing a checksum + @return {Buffer} + */ + + }, { + key: "decrypt_with_checksum", + value: function decrypt_with_checksum(private_key, public_key, nonce, message) { + var legacy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + + + // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string + if (nonce == null) // null or undefined + nonce = ""; + + if (!Buffer.isBuffer(message)) { + message = new Buffer(message, 'hex'); + } + + var S = private_key.get_shared_secret(public_key, legacy); + // D E B U G + // console.log('decrypt_with_checksum', { + // priv_to_pub: private_key.toPublicKey().toString(), + // pub: public_key.toPublicKeyString(), + // nonce: nonce, + // message: message.length, + // S: S.toString('hex') + // }) + + var aes = Aes.fromSeed(Buffer.concat([ + // A null or empty string nonce will not effect the hash + new Buffer("" + nonce), new Buffer(S.toString('hex'))])); + + var planebuffer = aes.decrypt(message); + if (!(planebuffer.length >= 4)) { + throw new Error("Invalid key, could not decrypt message(1)"); + } + + // DEBUG console.log('... planebuffer',planebuffer) + var checksum = planebuffer.slice(0, 4); + var plaintext = planebuffer.slice(4); + + // console.log('... checksum',checksum.toString('hex')) + // console.log('... plaintext',plaintext.toString()) + + var new_checksum = hash.sha256(plaintext); + new_checksum = new_checksum.slice(0, 4); + new_checksum = new_checksum.toString('hex'); + + if (!(checksum.toString('hex') === new_checksum)) { + throw new Error("Invalid key, could not decrypt message(2)"); + } + + return plaintext; + } + }, { + key: "encrypt_with_checksum", + + + /** Identical to {@link decrypt_with_checksum} but used to encrypt. Should not throw an error. + @return {Buffer} message - Encrypted message which includes a checksum + */ + value: function encrypt_with_checksum(private_key, public_key, nonce, message) { + + // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string + + if (nonce == null) // null or undefined + nonce = ""; + + if (!Buffer.isBuffer(message)) { + message = new Buffer(message, 'binary'); + } + + var S = private_key.get_shared_secret(public_key); + + // D E B U G + // console.log('encrypt_with_checksum', { + // priv_to_pub: private_key.toPublicKey().toString() + // pub: public_key.toPublicKeyString() + // nonce: nonce + // message: message.length + // S: S.toString('hex') + // }) + + var aes = Aes.fromSeed(Buffer.concat([ + // A null or empty string nonce will not effect the hash + new Buffer("" + nonce), new Buffer(S.toString('hex'))])); + // DEBUG console.log('... S',S.toString('hex')) + var checksum = hash.sha256(message).slice(0, 4); + var payload = Buffer.concat([checksum, message]); + // DEBUG console.log('... payload',payload.toString()) + return aes.encrypt(payload); + } + }]); + + return Aes; +}(); + +module.exports = Aes; \ No newline at end of file diff --git a/dist/ecc/src/ecdsa.js b/dist/ecc/src/ecdsa.js new file mode 100644 index 0000000..959a5da --- /dev/null +++ b/dist/ecc/src/ecdsa.js @@ -0,0 +1,219 @@ +'use strict'; + +var assert = require('assert'); // from github.com/bitcoinjs/bitcoinjs-lib from github.com/cryptocoinjs/ecdsa +var crypto = require('./hash'); +var enforceType = require('./enforce_types'); + +var BigInteger = require('bigi'); +var ECSignature = require('./ecsignature'); + +// https://tools.ietf.org/html/rfc6979#section-3.2 +function deterministicGenerateK(curve, hash, d, checkSig, nonce) { + + enforceType('Buffer', hash); + enforceType(BigInteger, d); + + if (nonce) { + hash = crypto.sha256(Buffer.concat([hash, new Buffer(nonce)])); + } + + // sanity check + assert.equal(hash.length, 32, 'Hash must be 256 bit'); + + var x = d.toBuffer(32); + var k = new Buffer(32); + var v = new Buffer(32); + + // Step B + v.fill(1); + + // Step C + k.fill(0); + + // Step D + k = crypto.HmacSHA256(Buffer.concat([v, new Buffer([0]), x, hash]), k); + + // Step E + v = crypto.HmacSHA256(v, k); + + // Step F + k = crypto.HmacSHA256(Buffer.concat([v, new Buffer([1]), x, hash]), k); + + // Step G + v = crypto.HmacSHA256(v, k); + + // Step H1/H2a, ignored as tlen === qlen (256 bit) + // Step H2b + v = crypto.HmacSHA256(v, k); + + var T = BigInteger.fromBuffer(v); + + // Step H3, repeat until T is within the interval [1, n - 1] + while (T.signum() <= 0 || T.compareTo(curve.n) >= 0 || !checkSig(T)) { + k = crypto.HmacSHA256(Buffer.concat([v, new Buffer([0])]), k); + v = crypto.HmacSHA256(v, k); + + // Step H1/H2a, again, ignored as tlen === qlen (256 bit) + // Step H2b again + v = crypto.HmacSHA256(v, k); + + T = BigInteger.fromBuffer(v); + } + + return T; +} + +function sign(curve, hash, d, nonce) { + + var e = BigInteger.fromBuffer(hash); + var n = curve.n; + var G = curve.G; + + var r, s; + var k = deterministicGenerateK(curve, hash, d, function (k) { + // find canonically valid signature + var Q = G.multiply(k); + + if (curve.isInfinity(Q)) return false; + + r = Q.affineX.mod(n); + if (r.signum() === 0) return false; + + s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n); + if (s.signum() === 0) return false; + + return true; + }, nonce); + + var N_OVER_TWO = n.shiftRight(1); + + // enforce low S values, see bip62: 'low s values in signatures' + if (s.compareTo(N_OVER_TWO) > 0) { + s = n.subtract(s); + } + + return new ECSignature(r, s); +} + +function verifyRaw(curve, e, signature, Q) { + var n = curve.n; + var G = curve.G; + + var r = signature.r; + var s = signature.s; + + // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] + if (r.signum() <= 0 || r.compareTo(n) >= 0) return false; + if (s.signum() <= 0 || s.compareTo(n) >= 0) return false; + + // c = s^-1 mod n + var c = s.modInverse(n); + + // 1.4.4 Compute u1 = es^−1 mod n + // u2 = rs^−1 mod n + var u1 = e.multiply(c).mod(n); + var u2 = r.multiply(c).mod(n); + + // 1.4.5 Compute R = (xR, yR) = u1G + u2Q + var R = G.multiplyTwo(u1, Q, u2); + + // 1.4.5 (cont.) Enforce R is not at infinity + if (curve.isInfinity(R)) return false; + + // 1.4.6 Convert the field element R.x to an integer + var xR = R.affineX; + + // 1.4.7 Set v = xR mod n + var v = xR.mod(n); + + // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" + return v.equals(r); +} + +function verify(curve, hash, signature, Q) { + // 1.4.2 H = Hash(M), already done by the user + // 1.4.3 e = H + var e = BigInteger.fromBuffer(hash); + return verifyRaw(curve, e, signature, Q); +} + +/** + * Recover a public key from a signature. + * + * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public + * Key Recovery Operation". + * + * http://www.secg.org/download/aid-780/sec1-v2.pdf + */ +function recoverPubKey(curve, e, signature, i) { + assert.strictEqual(i & 3, i, 'Recovery param is more than two bits'); + + var n = curve.n; + var G = curve.G; + + var r = signature.r; + var s = signature.s; + + assert(r.signum() > 0 && r.compareTo(n) < 0, 'Invalid r value'); + assert(s.signum() > 0 && s.compareTo(n) < 0, 'Invalid s value'); + + // A set LSB signifies that the y-coordinate is odd + var isYOdd = i & 1; + + // The more significant bit specifies whether we should use the + // first or second candidate key. + var isSecondKey = i >> 1; + + // 1.1 Let x = r + jn + var x = isSecondKey ? r.add(n) : r; + var R = curve.pointFromX(isYOdd, x); + + // 1.4 Check that nR is at infinity + var nR = R.multiply(n); + assert(curve.isInfinity(nR), 'nR is not a valid curve point'); + + // Compute -e from e + var eNeg = e.negate().mod(n); + + // 1.6.1 Compute Q = r^-1 (sR - eG) + // Q = r^-1 (sR + -eG) + var rInv = r.modInverse(n); + + var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv); + curve.validate(Q); + + return Q; +} + +/** + * Calculate pubkey extraction parameter. + * + * When extracting a pubkey from a signature, we have to + * distinguish four different cases. Rather than putting this + * burden on the verifier, Bitcoin includes a 2-bit value with the + * signature. + * + * This function simply tries all four cases and returns the value + * that resulted in a successful pubkey recovery. + */ +function calcPubKeyRecoveryParam(curve, e, signature, Q) { + for (var i = 0; i < 4; i++) { + var Qprime = recoverPubKey(curve, e, signature, i); + + // 1.6.2 Verify Q + if (Qprime.equals(Q)) { + return i; + } + } + + throw new Error('Unable to find valid recovery factor'); +} + +module.exports = { + calcPubKeyRecoveryParam: calcPubKeyRecoveryParam, + deterministicGenerateK: deterministicGenerateK, + recoverPubKey: recoverPubKey, + sign: sign, + verify: verify, + verifyRaw: verifyRaw +}; \ No newline at end of file diff --git a/dist/ecc/src/ecsignature.js b/dist/ecc/src/ecsignature.js new file mode 100644 index 0000000..7debd70 --- /dev/null +++ b/dist/ecc/src/ecsignature.js @@ -0,0 +1,128 @@ +'use strict'; + +var assert = require('assert'); // from https://github.com/bitcoinjs/bitcoinjs-lib +var enforceType = require('./enforce_types'); + +var BigInteger = require('bigi'); + +function ECSignature(r, s) { + enforceType(BigInteger, r); + enforceType(BigInteger, s); + + this.r = r; + this.s = s; +} + +// Import operations +ECSignature.parseCompact = function (buffer) { + assert.equal(buffer.length, 65, 'Invalid signature length'); + var i = buffer.readUInt8(0) - 27; + + // At most 3 bits + assert.equal(i, i & 7, 'Invalid signature parameter'); + var compressed = !!(i & 4); + + // Recovery param only + i = i & 3; + + var r = BigInteger.fromBuffer(buffer.slice(1, 33)); + var s = BigInteger.fromBuffer(buffer.slice(33)); + + return { + compressed: compressed, + i: i, + signature: new ECSignature(r, s) + }; +}; + +ECSignature.fromDER = function (buffer) { + assert.equal(buffer.readUInt8(0), 0x30, 'Not a DER sequence'); + assert.equal(buffer.readUInt8(1), buffer.length - 2, 'Invalid sequence length'); + assert.equal(buffer.readUInt8(2), 0x02, 'Expected a DER integer'); + + var rLen = buffer.readUInt8(3); + assert(rLen > 0, 'R length is zero'); + + var offset = 4 + rLen; + assert.equal(buffer.readUInt8(offset), 0x02, 'Expected a DER integer (2)'); + + var sLen = buffer.readUInt8(offset + 1); + assert(sLen > 0, 'S length is zero'); + + var rB = buffer.slice(4, offset); + var sB = buffer.slice(offset + 2); + offset += 2 + sLen; + + if (rLen > 1 && rB.readUInt8(0) === 0x00) { + assert(rB.readUInt8(1) & 0x80, 'R value excessively padded'); + } + + if (sLen > 1 && sB.readUInt8(0) === 0x00) { + assert(sB.readUInt8(1) & 0x80, 'S value excessively padded'); + } + + assert.equal(offset, buffer.length, 'Invalid DER encoding'); + var r = BigInteger.fromDERInteger(rB); + var s = BigInteger.fromDERInteger(sB); + + assert(r.signum() >= 0, 'R value is negative'); + assert(s.signum() >= 0, 'S value is negative'); + + return new ECSignature(r, s); +}; + +// FIXME: 0x00, 0x04, 0x80 are SIGHASH_* boundary constants, importing Transaction causes a circular dependency +ECSignature.parseScriptSignature = function (buffer) { + var hashType = buffer.readUInt8(buffer.length - 1); + var hashTypeMod = hashType & ~0x80; + + assert(hashTypeMod > 0x00 && hashTypeMod < 0x04, 'Invalid hashType'); + + return { + signature: ECSignature.fromDER(buffer.slice(0, -1)), + hashType: hashType + }; +}; + +// Export operations +ECSignature.prototype.toCompact = function (i, compressed) { + if (compressed) i += 4; + i += 27; + + var buffer = new Buffer(65); + buffer.writeUInt8(i, 0); + + this.r.toBuffer(32).copy(buffer, 1); + this.s.toBuffer(32).copy(buffer, 33); + + return buffer; +}; + +ECSignature.prototype.toDER = function () { + var rBa = this.r.toDERInteger(); + var sBa = this.s.toDERInteger(); + + var sequence = []; + + // INTEGER + sequence.push(0x02, rBa.length); + sequence = sequence.concat(rBa); + + // INTEGER + sequence.push(0x02, sBa.length); + sequence = sequence.concat(sBa); + + // SEQUENCE + sequence.unshift(0x30, sequence.length); + + return new Buffer(sequence); +}; + +ECSignature.prototype.toScriptSignature = function (hashType) { + var hashTypeBuffer = new Buffer(1); + hashTypeBuffer.writeUInt8(hashType, 0); + + return Buffer.concat([this.toDER(), hashTypeBuffer]); +}; + +module.exports = ECSignature; \ No newline at end of file diff --git a/dist/ecc/src/enforce_types.js b/dist/ecc/src/enforce_types.js new file mode 100644 index 0000000..f8bf7b7 --- /dev/null +++ b/dist/ecc/src/enforce_types.js @@ -0,0 +1,49 @@ +'use strict'; + +module.exports = function enforce(type, value) { + // Copied from https://github.com/bitcoinjs/bitcoinjs-lib + switch (type) { + case 'Array': + { + if (Array.isArray(value)) return; + break; + } + + case 'Boolean': + { + if (typeof value === 'boolean') return; + break; + } + + case 'Buffer': + { + if (Buffer.isBuffer(value)) return; + break; + } + + case 'Number': + { + if (typeof value === 'number') return; + break; + } + + case 'String': + { + if (typeof value === 'string') return; + break; + } + + default: + { + if (getName(value.constructor) === getName(type)) return; + } + } + + throw new TypeError('Expected ' + (getName(type) || type) + ', got ' + value); +}; + +function getName(fn) { + // Why not fn.name: https://kangax.github.io/compat-table/es6/#function_name_property + var match = fn.toString().match(/function (.*?)\(/); + return match ? match[1] : null; +} \ No newline at end of file diff --git a/dist/ecc/src/hash.js b/dist/ecc/src/hash.js new file mode 100644 index 0000000..5088cec --- /dev/null +++ b/dist/ecc/src/hash.js @@ -0,0 +1,60 @@ +"use strict"; + +var createHash = require("create-hash"); +var createHmac = require("create-hmac"); + +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha1(data, encoding) { + return createHash('sha1').update(data).digest(encoding); +} + +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha256(data, encoding) { + return createHash('sha256').update(data).digest(encoding); +} + +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha512(data, encoding) { + return createHash('sha512').update(data).digest(encoding); +} + +function HmacSHA256(buffer, secret) { + return createHmac('sha256', secret).update(buffer).digest(); +} + +function ripemd160(data) { + return createHash('rmd160').update(data).digest(); +} + +// function hash160(buffer) { +// return ripemd160(sha256(buffer)) +// } +// +// function hash256(buffer) { +// return sha256(sha256(buffer)) +// } + +// +// function HmacSHA512(buffer, secret) { +// return crypto.createHmac('sha512', secret).update(buffer).digest() +// } + +module.exports = { + sha1: sha1, + sha256: sha256, + sha512: sha512, + HmacSHA256: HmacSHA256, + ripemd160: ripemd160 + // hash160: hash160, + // hash256: hash256, + // HmacSHA512: HmacSHA512 +}; \ No newline at end of file diff --git a/dist/ecc/src/signature.js b/dist/ecc/src/signature.js new file mode 100644 index 0000000..2d27835 --- /dev/null +++ b/dist/ecc/src/signature.js @@ -0,0 +1,187 @@ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var ecdsa = require('./ecdsa'); +var hash = require('./hash'); + +var _require = require('ecurve'), + getCurveByName = _require.getCurveByName; + +var secp256k1 = getCurveByName('secp256k1'); +var assert = require('assert'); +var BigInteger = require('bigi'); +var PublicKey = require('./PublicKey'); + +var Signature = function () { + function Signature(r1, s1, i1) { + _classCallCheck(this, Signature); + + this.r = r1; + this.s = s1; + this.i = i1; + assert.equal(this.r != null, true, 'Missing parameter'); + assert.equal(this.s != null, true, 'Missing parameter'); + assert.equal(this.i != null, true, 'Missing parameter'); + } + + _createClass(Signature, [{ + key: 'toBuffer', + value: function toBuffer() { + var buf; + buf = new Buffer(65); + buf.writeUInt8(this.i, 0); + this.r.toBuffer(32).copy(buf, 1); + this.s.toBuffer(32).copy(buf, 33); + return buf; + } + }, { + key: 'recoverPublicKeyFromBuffer', + value: function recoverPublicKeyFromBuffer(buffer) { + return this.recoverPublicKey(hash.sha256(buffer)); + } + }, { + key: 'recoverPublicKey', + + + /** + @return {PublicKey} + */ + value: function recoverPublicKey(sha256_buffer) { + var Q = void 0, + e = void 0, + i = void 0; + e = BigInteger.fromBuffer(sha256_buffer); + i = this.i; + i -= 27; + i = i & 3; + Q = ecdsa.recoverPubKey(secp256k1, e, this, i); + return PublicKey.fromPoint(Q); + } + }, { + key: 'verifyBuffer', + + + /** + @param {Buffer} un-hashed + @param {./PublicKey} + @return {boolean} + */ + value: function verifyBuffer(buf, public_key) { + var _hash = hash.sha256(buf); + return this.verifyHash(_hash, public_key); + } + }, { + key: 'verifyHash', + value: function verifyHash(hash, public_key) { + assert.equal(hash.length, 32, "A SHA 256 should be 32 bytes long, instead got " + hash.length); + return ecdsa.verify(secp256k1, hash, { + r: this.r, + s: this.s + }, public_key.Q); + } + }, { + key: 'toByteBuffer', + + + /* */ + + value: function toByteBuffer() { + var b; + b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + } + }, { + key: 'toHex', + value: function toHex() { + return this.toBuffer().toString("hex"); + } + }, { + key: 'verifyHex', + value: function verifyHex(hex, public_key) { + var buf; + buf = new Buffer(hex, 'hex'); + return this.verifyBuffer(buf, public_key); + } + }], [{ + key: 'fromBuffer', + value: function fromBuffer(buf) { + var i, r, s; + assert.equal(buf.length, 65, 'Invalid signature length'); + i = buf.readUInt8(0); + assert.equal(i - 27, i - 27 & 7, 'Invalid signature parameter'); + r = BigInteger.fromBuffer(buf.slice(1, 33)); + s = BigInteger.fromBuffer(buf.slice(33)); + return new Signature(r, s, i); + } + }, { + key: 'signBuffer', + + + /** + @param {Buffer} buf + @param {PrivateKey} private_key + @return {Signature} + */ + value: function signBuffer(buf, private_key) { + var _hash = hash.sha256(buf); + return Signature.signBufferSha256(_hash, private_key); + } + + /** Sign a buffer of exactally 32 bytes in size (sha256(text)) + @param {Buffer} buf - 32 bytes binary + @param {PrivateKey} private_key + @return {Signature} + */ + + }, { + key: 'signBufferSha256', + value: function signBufferSha256(buf_sha256, private_key) { + if (buf_sha256.length !== 32 || !Buffer.isBuffer(buf_sha256)) throw new Error("buf_sha256: 32 byte buffer requred"); + var der, e, ecsignature, i, lenR, lenS, nonce; + i = null; + nonce = 0; + e = BigInteger.fromBuffer(buf_sha256); + while (true) { + ecsignature = ecdsa.sign(secp256k1, buf_sha256, private_key.d, nonce++); + der = ecsignature.toDER(); + lenR = der[3]; + lenS = der[5 + lenR]; + if (lenR === 32 && lenS === 32) { + i = ecdsa.calcPubKeyRecoveryParam(secp256k1, e, ecsignature, private_key.toPublicKey().Q); + i += 4; // compressed + i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) + break; + } + if (nonce % 10 === 0) { + console.log("WARN: " + nonce + " attempts to find canonical signature"); + } + } + return new Signature(ecsignature.r, ecsignature.s, i); + } + }, { + key: 'sign', + value: function sign(string, private_key) { + return Signature.signBuffer(new Buffer(string), private_key); + } + }, { + key: 'fromHex', + value: function fromHex(hex) { + return Signature.fromBuffer(new Buffer(hex, "hex")); + } + }, { + key: 'signHex', + value: function signHex(hex, private_key) { + var buf; + buf = new Buffer(hex, 'hex'); + return Signature.signBuffer(buf, private_key); + } + }]); + + return Signature; +}(); + +module.exports = Signature; \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..88076da --- /dev/null +++ b/dist/index.js @@ -0,0 +1,3 @@ +"use strict"; + +module.exports = Object.assign(require("./chain"), require("./ecc"), require("./serializer")); \ No newline at end of file diff --git a/dist/serializer/index.js b/dist/serializer/index.js new file mode 100644 index 0000000..2059055 --- /dev/null +++ b/dist/serializer/index.js @@ -0,0 +1,22 @@ +'use strict'; + +module.exports = { + + // Primary class for creating operations + Serializer: require('./src/serializer'), + + // helper functions for creating operations + fp: require('./src/FastParser'), + + // Low level types + types: require('./src/types'), + + // Higher level operations (made out of generic types) + ops: require('./src/operations'), + + // Utility that generates JSON examples + template: require('./src/template'), + + // Serializer validation + SerializerValidation: require('./src/SerializerValidation') +}; \ No newline at end of file diff --git a/dist/serializer/src/FastParser.js b/dist/serializer/src/FastParser.js new file mode 100644 index 0000000..ee30cf4 --- /dev/null +++ b/dist/serializer/src/FastParser.js @@ -0,0 +1,90 @@ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PublicKey = require("../../ecc/src/PublicKey"); + +var FastParser = function () { + function FastParser() { + _classCallCheck(this, FastParser); + } + + _createClass(FastParser, null, [{ + key: 'fixed_data', + value: function fixed_data(b, len, buffer) { + if (!b) { + return; + } + if (buffer) { + var data = buffer.slice(0, len).toString('binary'); + b.append(data, 'binary'); + while (len-- > data.length) { + b.writeUint8(0); + } + } else { + var b_copy = b.copy(b.offset, b.offset + len); + b.skip(len); + return new Buffer(b_copy.toBinary(), 'binary'); + } + } + }, { + key: 'public_key', + value: function public_key(b, _public_key) { + if (!b) { + return; + } + if (_public_key) { + var buffer = _public_key.toBuffer(); + b.append(buffer.toString('binary'), 'binary'); + return; + } else { + buffer = FastParser.fixed_data(b, 33); + return PublicKey.fromBuffer(buffer); + } + } + }, { + key: 'ripemd160', + value: function ripemd160(b, _ripemd) { + if (!b) { + return; + } + if (_ripemd) { + FastParser.fixed_data(b, 20, _ripemd); + return; + } else { + return FastParser.fixed_data(b, 20); + } + } + }, { + key: 'sha256', + value: function sha256(b, _sha) { + if (!b) { + return; + } + if (_sha) { + FastParser.fixed_data(b, 32, _sha); + return; + } else { + return FastParser.fixed_data(b, 32); + } + } + }, { + key: 'time_point_sec', + value: function time_point_sec(b, epoch) { + if (epoch) { + epoch = Math.ceil(epoch / 1000); + b.writeInt32(epoch); + return; + } else { + epoch = b.readInt32(); // fc::time_point_sec + return new Date(epoch * 1000); + } + } + }]); + + return FastParser; +}(); + +module.exports = FastParser; \ No newline at end of file diff --git a/dist/serializer/src/SerializerValidation.js b/dist/serializer/src/SerializerValidation.js new file mode 100644 index 0000000..334d8c7 --- /dev/null +++ b/dist/serializer/src/SerializerValidation.js @@ -0,0 +1,363 @@ +'use strict'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _require = require('bytebuffer'), + Long = _require.Long; + +var ChainTypes = require('../../chain/src/ChainTypes'); + +var MAX_SAFE_INT = 9007199254740991; +var MIN_SAFE_INT = -9007199254740991; + +/** + Most validations are skipped and the value returned unchanged when an empty string, null, or undefined is encountered (except "required"). + + Validations support a string format for dealing with large numbers. +*/ +var _my = { + + is_empty: function is_empty(value) { + return value === null || value === undefined; + }, + + required: function required(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (this.is_empty(value)) { + throw new Error('value required ' + field_name + ' ' + value); + } + return value; + }, + require_long: function require_long(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (!Long.isLong(value)) { + throw new Error('Long value required ' + field_name + ' ' + value); + } + return value; + }, + string: function string(value) { + if (this.is_empty(value)) { + return value; + } + if (typeof value !== "string") { + throw new Error('string required: ' + value); + } + return value; + }, + number: function number(value) { + if (this.is_empty(value)) { + return value; + } + if (typeof value !== "number") { + throw new Error('number required: ' + value); + } + return value; + }, + whole_number: function whole_number(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (this.is_empty(value)) { + return value; + } + if (/\./.test(value)) { + throw new Error('whole number required ' + field_name + ' ' + value); + } + return value; + }, + unsigned: function unsigned(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (this.is_empty(value)) { + return value; + } + if (/-/.test(value)) { + throw new Error('unsigned required ' + field_name + ' ' + value); + } + return value; + }, + + + is_digits: function is_digits(value) { + if (typeof value === "numeric") { + return true; + } + return (/^[0-9]+$/.test(value) + ); + }, + + to_number: function to_number(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (this.is_empty(value)) { + return value; + } + this.no_overflow53(value, field_name); + var int_value = function () { + if (typeof value === "number") { + return value; + } else { + return parseInt(value); + } + }(); + return int_value; + }, + + to_long: function to_long(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (this.is_empty(value)) { + return value; + } + if (Long.isLong(value)) { + return value; + } + + this.no_overflow64(value, field_name); + if (typeof value === "number") { + value = "" + value; + } + return Long.fromString(value); + }, + to_ulong: function to_ulong(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (this.is_empty(value)) { + return value; + } + if (Long.isLong(value)) { + return value; + } + + this.no_overflow64(value, field_name, true); + if (typeof value === "number") { + value = "" + value; + } + return Long.fromString(value, true); + }, + to_string: function to_string(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (this.is_empty(value)) { + return value; + } + if (typeof value === "string") { + return value; + } + if (typeof value === "number") { + this.no_overflow53(value, field_name); + return "" + value; + } + if (Long.isLong(value)) { + return value.toString(); + } + throw 'unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value; + }, + require_test: function require_test(regex, value) { + var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; + + if (this.is_empty(value)) { + return value; + } + if (!regex.test(value)) { + throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value); + } + return value; + }, + + + require_match: function require_match(regex, value) { + var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; + + if (this.is_empty(value)) { + return value; + } + var match = value.match(regex); + if (match === null) { + throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value); + } + return match; + }, + + require_object_id: function require_object_id(value, field_name) { + return require_match(/^([0-9]+)\.([0-9]+)\.([0-9]+)$/, value, field_name); + }, + + // Does not support over 53 bits + require_range: function require_range(min, max, value) { + var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ""; + + if (this.is_empty(value)) { + return value; + } + var number = this.to_number(value); + if (value < min || value > max) { + throw new Error('out of range ' + value + ' ' + field_name + ' ' + value); + } + return value; + }, + + + require_object_type: function require_object_type() { + var reserved_spaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + var type = arguments[1]; + var value = arguments[2]; + var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ""; + + if (this.is_empty(value)) { + return value; + } + var object_type = ChainTypes.object_type[type]; + if (!object_type) { + throw new Error('Unknown object type ' + type + ' ' + field_name + ' ' + value); + } + var re = new RegExp(reserved_spaces + '.' + object_type + '.[0-9]+$'); + if (!re.test(value)) { + throw new Error('Expecting ' + type + ' in format ' + (reserved_spaces + '.' + object_type + '.[0-9]+ ') + ('instead of ' + value + ' ' + field_name + ' ' + value)); + } + return value; + }, + + get_instance: function get_instance(reserve_spaces, type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_type(reserve_spaces, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, + + require_relative_type: function require_relative_type(type, value, field_name) { + this.require_object_type(0, type, value, field_name); + return value; + }, + + get_relative_instance: function get_relative_instance(type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_type(0, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, + + require_protocol_type: function require_protocol_type(type, value, field_name) { + this.require_object_type(1, type, value, field_name); + return value; + }, + + get_protocol_instance: function get_protocol_instance(type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_type(1, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, + + get_protocol_type: function get_protocol_type(value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_id(value, field_name); + var values = value.split('.'); + return this.to_number(values[1]); + }, + + get_protocol_type_name: function get_protocol_type_name(value, field_name) { + if (this.is_empty(value)) { + return value; + } + var type_id = this.get_protocol_type(value, field_name); + return Object.keys(ChainTypes.object_type)[type_id]; + }, + + + require_implementation_type: function require_implementation_type(type, value, field_name) { + this.require_object_type(2, type, value, field_name); + return value; + }, + + get_implementation_instance: function get_implementation_instance(type, value, field_name) { + if (this.is_empty(value)) { + return value; + } + this.require_object_type(2, type, value, field_name); + return this.to_number(value.split('.')[2]); + }, + + // signed / unsigned decimal + no_overflow53: function no_overflow53(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + + if (typeof value === "number") { + if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { + throw new Error('overflow ' + field_name + ' ' + value); + } + return; + } + if (typeof value === "string") { + var int = parseInt(value); + if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { + throw new Error('overflow ' + field_name + ' ' + value); + } + return; + } + if (Long.isLong(value)) { + // typeof value.toInt() is 'number' + this.no_overflow53(value.toInt(), field_name); + return; + } + throw 'unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value; + }, + + + // signed / unsigned whole numbers only + no_overflow64: function no_overflow64(value) { + var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + var unsigned = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + // https://github.com/dcodeIO/Long.js/issues/20 + if (Long.isLong(value)) { + return; + } + + // BigInteger#isBigInteger https://github.com/cryptocoinjs/bigi/issues/20 + if (value.t !== undefined && value.s !== undefined) { + this.no_overflow64(value.toString(), field_name, unsigned); + + return; + } + + if (typeof value === "string") { + // remove leading zeros, will cause a false positive + value = value.replace(/^0+/, ''); + // remove trailing zeros + while (/0$/.test(value)) { + value = value.substring(0, value.length - 1); + } + if (/\.$/.test(value)) { + // remove trailing dot + value = value.substring(0, value.length - 1); + } + if (value === "") { + value = "0"; + } + + var long_string = Long.fromString(value, unsigned).toString(); + + if (long_string !== value.trim()) { + throw new Error('overflow ' + field_name + ' ' + value); + } + return; + } + if (typeof value === "number") { + if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { + throw new Error('overflow ' + field_name + ' ' + value); + } + return; + } + + throw 'unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value; + } +}; + +module.exports = _my; \ No newline at end of file diff --git a/dist/serializer/src/convert.js b/dist/serializer/src/convert.js new file mode 100644 index 0000000..e9b43ef --- /dev/null +++ b/dist/serializer/src/convert.js @@ -0,0 +1,37 @@ +'use strict'; + +var ByteBuffer = require('bytebuffer'); + +module.exports = function (type) { + + return { + fromHex: function fromHex(hex) { + var b = ByteBuffer.fromHex(hex, ByteBuffer.LITTLE_ENDIAN); + return type.fromByteBuffer(b); + }, + toHex: function toHex(object) { + var b = toByteBuffer(type, object); + return b.toHex(); + }, + fromBuffer: function fromBuffer(buffer) { + var b = ByteBuffer.fromBinary(buffer.toString(), ByteBuffer.LITTLE_ENDIAN); + return type.fromByteBuffer(b); + }, + toBuffer: function toBuffer(object) { + return new Buffer(toByteBuffer(type, object).toBinary(), 'binary'); + }, + fromBinary: function fromBinary(string) { + var b = ByteBuffer.fromBinary(string, ByteBuffer.LITTLE_ENDIAN); + return type.fromByteBuffer(b); + }, + toBinary: function toBinary(object) { + return toByteBuffer(type, object).toBinary(); + } + }; +}; + +var toByteBuffer = function toByteBuffer(type, object) { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + type.appendByteBuffer(b, object); + return b.copy(0, b.offset); +}; \ No newline at end of file diff --git a/dist/serializer/src/error_with_cause.js b/dist/serializer/src/error_with_cause.js new file mode 100644 index 0000000..e36aa85 --- /dev/null +++ b/dist/serializer/src/error_with_cause.js @@ -0,0 +1,42 @@ +"use strict"; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** Exception nesting. */ +var ErrorWithCause = function () { + function ErrorWithCause(message, cause) { + _classCallCheck(this, ErrorWithCause); + + this.message = message; + if (typeof cause !== "undefined" && cause !== null ? cause.message : undefined) { + this.message = "cause\t" + cause.message + "\t" + this.message; + } + + var stack = ""; //(new Error).stack + if (typeof cause !== "undefined" && cause !== null ? cause.stack : undefined) { + stack = "caused by\n\t" + cause.stack + "\t" + stack; + } + + this.stack = this.message + "\n" + stack; + } + + _createClass(ErrorWithCause, null, [{ + key: "throw", + value: function _throw(message, cause) { + var msg = message; + if (typeof cause !== "undefined" && cause !== null ? cause.message : undefined) { + msg += "\t cause: " + cause.message + " "; + } + if (typeof cause !== "undefined" && cause !== null ? cause.stack : undefined) { + msg += "\n stack: " + cause.stack + " "; + } + throw new Error(msg); + } + }]); + + return ErrorWithCause; +}(); + +module.exports = ErrorWithCause; \ No newline at end of file diff --git a/dist/serializer/src/operations.js b/dist/serializer/src/operations.js new file mode 100644 index 0000000..1c82d8c --- /dev/null +++ b/dist/serializer/src/operations.js @@ -0,0 +1,709 @@ +"use strict"; + +var types = require("./types"); +var SerializerImpl = require("./serializer"); + +var uint8 = types.uint8, + uint16 = types.uint16, + uint32 = types.uint32, + int64 = types.int64, + uint64 = types.uint64, + string = types.string, + bytes = types.bytes, + bool = types.bool, + array = types.array, + fixed_array = types.fixed_array, + protocol_id_type = types.protocol_id_type, + object_id_type = types.object_id_type, + vote_id = types.vote_id, + future_extensions = types.future_extensions, + static_variant = types.static_variant, + map = types.map, + set = types.set, + public_key = types.public_key, + address = types.address, + time_point_sec = types.time_point_sec, + optional = types.optional, + variant = types.variant, + variant_object = types.variant_object, + enumeration = types.enumeration, + sha256 = types.sha256; + + +future_extensions = types.void; + +/* +When updating generated code +Replace: operation = static_variant [ +with: operation.st_operations = [ + +Delete: +public_key = new Serializer( + "public_key" + key_data: bytes 33 +) + +*/ +// Place-holder, their are dependencies on "operation" .. The final list of +// operations is not avialble until the very end of the generated code. +// See: operation.st_operations = ... +var operation = static_variant(); +module.exports["operation"] = operation; + +// For module.exports +var Serializer = function Serializer(operation_name, serilization_types_object) { + var s = new SerializerImpl(operation_name, serilization_types_object); + return module.exports[operation_name] = s; +}; + +// Custom-types follow Generated code: + +// ## Generated code follows +// # programs/js_operation_serializer > npm i -g decaffeinate +// ## ------------------------------- +var transfer_operation_fee_parameters = new Serializer("transfer_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); + +var limit_order_create_operation_fee_parameters = new Serializer("limit_order_create_operation_fee_parameters", { fee: uint64 }); + +var limit_order_cancel_operation_fee_parameters = new Serializer("limit_order_cancel_operation_fee_parameters", { fee: uint64 }); + +var call_order_update_operation_fee_parameters = new Serializer("call_order_update_operation_fee_parameters", { fee: uint64 }); + +var fill_order_operation_fee_parameters = new Serializer("fill_order_operation_fee_parameters"); + +var account_create_operation_fee_parameters = new Serializer("account_create_operation_fee_parameters", { basic_fee: uint64, + premium_fee: uint64, + price_per_kbyte: uint32 }); + +var account_update_operation_fee_parameters = new Serializer("account_update_operation_fee_parameters", { fee: int64, + price_per_kbyte: uint32 }); + +var account_whitelist_operation_fee_parameters = new Serializer("account_whitelist_operation_fee_parameters", { fee: int64 }); + +var account_upgrade_operation_fee_parameters = new Serializer("account_upgrade_operation_fee_parameters", { membership_annual_fee: uint64, + membership_lifetime_fee: uint64 }); + +var account_transfer_operation_fee_parameters = new Serializer("account_transfer_operation_fee_parameters", { fee: uint64 }); + +var asset_create_operation_fee_parameters = new Serializer("asset_create_operation_fee_parameters", { symbol3: uint64, + symbol4: uint64, + long_symbol: uint64, + price_per_kbyte: uint32 }); + +var asset_update_operation_fee_parameters = new Serializer("asset_update_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); + +var asset_update_bitasset_operation_fee_parameters = new Serializer("asset_update_bitasset_operation_fee_parameters", { fee: uint64 }); + +var asset_update_feed_producers_operation_fee_parameters = new Serializer("asset_update_feed_producers_operation_fee_parameters", { fee: uint64 }); + +var asset_issue_operation_fee_parameters = new Serializer("asset_issue_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); + +var asset_reserve_operation_fee_parameters = new Serializer("asset_reserve_operation_fee_parameters", { fee: uint64 }); + +var asset_fund_fee_pool_operation_fee_parameters = new Serializer("asset_fund_fee_pool_operation_fee_parameters", { fee: uint64 }); + +var asset_settle_operation_fee_parameters = new Serializer("asset_settle_operation_fee_parameters", { fee: uint64 }); + +var asset_global_settle_operation_fee_parameters = new Serializer("asset_global_settle_operation_fee_parameters", { fee: uint64 }); + +var asset_publish_feed_operation_fee_parameters = new Serializer("asset_publish_feed_operation_fee_parameters", { fee: uint64 }); + +var witness_create_operation_fee_parameters = new Serializer("witness_create_operation_fee_parameters", { fee: uint64 }); + +var witness_update_operation_fee_parameters = new Serializer("witness_update_operation_fee_parameters", { fee: int64 }); + +var proposal_create_operation_fee_parameters = new Serializer("proposal_create_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); + +var proposal_update_operation_fee_parameters = new Serializer("proposal_update_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); + +var proposal_delete_operation_fee_parameters = new Serializer("proposal_delete_operation_fee_parameters", { fee: uint64 }); + +var withdraw_permission_create_operation_fee_parameters = new Serializer("withdraw_permission_create_operation_fee_parameters", { fee: uint64 }); + +var withdraw_permission_update_operation_fee_parameters = new Serializer("withdraw_permission_update_operation_fee_parameters", { fee: uint64 }); + +var withdraw_permission_claim_operation_fee_parameters = new Serializer("withdraw_permission_claim_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); + +var withdraw_permission_delete_operation_fee_parameters = new Serializer("withdraw_permission_delete_operation_fee_parameters", { fee: uint64 }); + +var committee_member_create_operation_fee_parameters = new Serializer("committee_member_create_operation_fee_parameters", { fee: uint64 }); + +var committee_member_update_operation_fee_parameters = new Serializer("committee_member_update_operation_fee_parameters", { fee: uint64 }); + +var committee_member_update_global_parameters_operation_fee_parameters = new Serializer("committee_member_update_global_parameters_operation_fee_parameters", { fee: uint64 }); + +var vesting_balance_create_operation_fee_parameters = new Serializer("vesting_balance_create_operation_fee_parameters", { fee: uint64 }); + +var vesting_balance_withdraw_operation_fee_parameters = new Serializer("vesting_balance_withdraw_operation_fee_parameters", { fee: uint64 }); + +var worker_create_operation_fee_parameters = new Serializer("worker_create_operation_fee_parameters", { fee: uint64 }); + +var custom_operation_fee_parameters = new Serializer("custom_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); + +var assert_operation_fee_parameters = new Serializer("assert_operation_fee_parameters", { fee: uint64 }); + +var balance_claim_operation_fee_parameters = new Serializer("balance_claim_operation_fee_parameters"); + +var override_transfer_operation_fee_parameters = new Serializer("override_transfer_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); + +var transfer_to_blind_operation_fee_parameters = new Serializer("transfer_to_blind_operation_fee_parameters", { fee: uint64, + price_per_output: uint32 }); + +var blind_transfer_operation_fee_parameters = new Serializer("blind_transfer_operation_fee_parameters", { fee: uint64, + price_per_output: uint32 }); + +var transfer_from_blind_operation_fee_parameters = new Serializer("transfer_from_blind_operation_fee_parameters", { fee: uint64 }); + +var asset_settle_cancel_operation_fee_parameters = new Serializer("asset_settle_cancel_operation_fee_parameters"); + +var asset_claim_fees_operation_fee_parameters = new Serializer("asset_claim_fees_operation_fee_parameters", { fee: uint64 }); + +var fba_distribute_operation_fee_parameters = new Serializer("fba_distribute_operation_fee_parameters", {}); + +var tournament_create_operation_fee_parameters = new Serializer("tournament_create_operation_fee_parameters", { fee: uint64, + price_per_kbyte: uint32 }); + +var tournament_join_operation_fee_parameters = new Serializer("tournament_join_operation_fee_parameters", { fee: uint64 }); + +var fee_parameters = static_variant([transfer_operation_fee_parameters, limit_order_create_operation_fee_parameters, limit_order_cancel_operation_fee_parameters, call_order_update_operation_fee_parameters, fill_order_operation_fee_parameters, account_create_operation_fee_parameters, account_update_operation_fee_parameters, account_whitelist_operation_fee_parameters, account_upgrade_operation_fee_parameters, account_transfer_operation_fee_parameters, asset_create_operation_fee_parameters, asset_update_operation_fee_parameters, asset_update_bitasset_operation_fee_parameters, asset_update_feed_producers_operation_fee_parameters, asset_issue_operation_fee_parameters, asset_reserve_operation_fee_parameters, asset_fund_fee_pool_operation_fee_parameters, asset_settle_operation_fee_parameters, asset_global_settle_operation_fee_parameters, asset_publish_feed_operation_fee_parameters, witness_create_operation_fee_parameters, witness_update_operation_fee_parameters, proposal_create_operation_fee_parameters, proposal_update_operation_fee_parameters, proposal_delete_operation_fee_parameters, withdraw_permission_create_operation_fee_parameters, withdraw_permission_update_operation_fee_parameters, withdraw_permission_claim_operation_fee_parameters, withdraw_permission_delete_operation_fee_parameters, committee_member_create_operation_fee_parameters, committee_member_update_operation_fee_parameters, committee_member_update_global_parameters_operation_fee_parameters, vesting_balance_create_operation_fee_parameters, vesting_balance_withdraw_operation_fee_parameters, worker_create_operation_fee_parameters, custom_operation_fee_parameters, assert_operation_fee_parameters, balance_claim_operation_fee_parameters, override_transfer_operation_fee_parameters, transfer_to_blind_operation_fee_parameters, blind_transfer_operation_fee_parameters, transfer_from_blind_operation_fee_parameters, asset_settle_cancel_operation_fee_parameters, asset_claim_fees_operation_fee_parameters, fba_distribute_operation_fee_parameters, tournament_create_operation_fee_parameters, tournament_join_operation_fee_parameters]); + +var fee_schedule = new Serializer("fee_schedule", { parameters: set(fee_parameters), + scale: uint32 }); + +var void_result = new Serializer("void_result"); + +var asset = new Serializer("asset", { amount: int64, + asset_id: protocol_id_type("asset") }); + +var operation_result = static_variant([void_result, object_id_type, asset]); + +var processed_transaction = new Serializer("processed_transaction", { ref_block_num: uint16, + ref_block_prefix: uint32, + expiration: time_point_sec, + operations: array(operation), + extensions: set(future_extensions), + signatures: array(bytes(65)), + operation_results: array(operation_result) }); + +var signed_block = new Serializer("signed_block", { previous: bytes(20), + timestamp: time_point_sec, + witness: protocol_id_type("witness"), + transaction_merkle_root: bytes(20), + extensions: set(future_extensions), + witness_signature: bytes(65), + transactions: array(processed_transaction) }); + +var block_header = new Serializer("block_header", { previous: bytes(20), + timestamp: time_point_sec, + witness: protocol_id_type("witness"), + transaction_merkle_root: bytes(20), + extensions: set(future_extensions) }); + +var signed_block_header = new Serializer("signed_block_header", { previous: bytes(20), + timestamp: time_point_sec, + witness: protocol_id_type("witness"), + transaction_merkle_root: bytes(20), + extensions: set(future_extensions), + witness_signature: bytes(65) }); + +var memo_data = new Serializer("memo_data", { from: public_key, + to: public_key, + nonce: uint64, + message: bytes() }); + +var transfer = new Serializer("transfer", { fee: asset, + from: protocol_id_type("account"), + to: protocol_id_type("account"), + amount: asset, + memo: optional(memo_data), + extensions: set(future_extensions) }); + +var limit_order_create = new Serializer("limit_order_create", { fee: asset, + seller: protocol_id_type("account"), + amount_to_sell: asset, + min_to_receive: asset, + expiration: time_point_sec, + fill_or_kill: bool, + extensions: set(future_extensions) }); + +var limit_order_cancel = new Serializer("limit_order_cancel", { fee: asset, + fee_paying_account: protocol_id_type("account"), + order: protocol_id_type("limit_order"), + extensions: set(future_extensions) }); + +var call_order_update = new Serializer("call_order_update", { fee: asset, + funding_account: protocol_id_type("account"), + delta_collateral: asset, + delta_debt: asset, + extensions: set(future_extensions) }); + +var fill_order = new Serializer("fill_order", { fee: asset, + order_id: object_id_type, + account_id: protocol_id_type("account"), + pays: asset, + receives: asset }); + +var authority = new Serializer("authority", { weight_threshold: uint32, + account_auths: map(protocol_id_type("account"), uint16), + key_auths: map(public_key, uint16), + address_auths: map(address, uint16) }); + +var account_options = new Serializer("account_options", { memo_key: public_key, + voting_account: protocol_id_type("account"), + num_witness: uint16, + num_committee: uint16, + votes: set(vote_id), + extensions: set(future_extensions) }); + +var account_create = new Serializer("account_create", { fee: asset, + registrar: protocol_id_type("account"), + referrer: protocol_id_type("account"), + referrer_percent: uint16, + name: string, + owner: authority, + active: authority, + options: account_options, + extensions: set(future_extensions) }); + +var account_update = new Serializer("account_update", { fee: asset, + account: protocol_id_type("account"), + owner: optional(authority), + active: optional(authority), + new_options: optional(account_options), + extensions: set(future_extensions) }); + +var account_whitelist = new Serializer("account_whitelist", { fee: asset, + authorizing_account: protocol_id_type("account"), + account_to_list: protocol_id_type("account"), + new_listing: uint8, + extensions: set(future_extensions) }); + +var account_upgrade = new Serializer("account_upgrade", { fee: asset, + account_to_upgrade: protocol_id_type("account"), + upgrade_to_lifetime_member: bool, + extensions: set(future_extensions) }); + +var account_transfer = new Serializer("account_transfer", { fee: asset, + account_id: protocol_id_type("account"), + new_owner: protocol_id_type("account"), + extensions: set(future_extensions) }); + +var price = new Serializer("price", { base: asset, + quote: asset }); + +var asset_options = new Serializer("asset_options", { max_supply: int64, + market_fee_percent: uint16, + max_market_fee: int64, + issuer_permissions: uint16, + flags: uint16, + core_exchange_rate: price, + whitelist_authorities: set(protocol_id_type("account")), + blacklist_authorities: set(protocol_id_type("account")), + whitelist_markets: set(protocol_id_type("asset")), + blacklist_markets: set(protocol_id_type("asset")), + description: string, + extensions: set(future_extensions) }); + +var bitasset_options = new Serializer("bitasset_options", { feed_lifetime_sec: uint32, + minimum_feeds: uint8, + force_settlement_delay_sec: uint32, + force_settlement_offset_percent: uint16, + maximum_force_settlement_volume: uint16, + short_backing_asset: protocol_id_type("asset"), + extensions: set(future_extensions) }); + +var asset_create = new Serializer("asset_create", { fee: asset, + issuer: protocol_id_type("account"), + symbol: string, + precision: uint8, + common_options: asset_options, + bitasset_opts: optional(bitasset_options), + is_prediction_market: bool, + extensions: set(future_extensions) }); + +var asset_update = new Serializer("asset_update", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_update: protocol_id_type("asset"), + new_issuer: optional(protocol_id_type("account")), + new_options: asset_options, + extensions: set(future_extensions) }); + +var asset_update_bitasset = new Serializer("asset_update_bitasset", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_update: protocol_id_type("asset"), + new_options: bitasset_options, + extensions: set(future_extensions) }); + +var asset_update_feed_producers = new Serializer("asset_update_feed_producers", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_update: protocol_id_type("asset"), + new_feed_producers: set(protocol_id_type("account")), + extensions: set(future_extensions) }); + +var asset_issue = new Serializer("asset_issue", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_issue: asset, + issue_to_account: protocol_id_type("account"), + memo: optional(memo_data), + extensions: set(future_extensions) }); + +var asset_reserve = new Serializer("asset_reserve", { fee: asset, + payer: protocol_id_type("account"), + amount_to_reserve: asset, + extensions: set(future_extensions) }); + +var asset_fund_fee_pool = new Serializer("asset_fund_fee_pool", { fee: asset, + from_account: protocol_id_type("account"), + asset_id: protocol_id_type("asset"), + amount: int64, + extensions: set(future_extensions) }); + +var asset_settle = new Serializer("asset_settle", { fee: asset, + account: protocol_id_type("account"), + amount: asset, + extensions: set(future_extensions) }); + +var asset_global_settle = new Serializer("asset_global_settle", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_settle: protocol_id_type("asset"), + settle_price: price, + extensions: set(future_extensions) }); + +var price_feed = new Serializer("price_feed", { settlement_price: price, + maintenance_collateral_ratio: uint16, + maximum_short_squeeze_ratio: uint16, + core_exchange_rate: price }); + +var asset_publish_feed = new Serializer("asset_publish_feed", { fee: asset, + publisher: protocol_id_type("account"), + asset_id: protocol_id_type("asset"), + feed: price_feed, + extensions: set(future_extensions) }); + +var witness_create = new Serializer("witness_create", { fee: asset, + witness_account: protocol_id_type("account"), + url: string, + block_signing_key: public_key }); + +var witness_update = new Serializer("witness_update", { fee: asset, + witness: protocol_id_type("witness"), + witness_account: protocol_id_type("account"), + new_url: optional(string), + new_signing_key: optional(public_key) }); + +var op_wrapper = new Serializer("op_wrapper", { op: operation }); + +var proposal_create = new Serializer("proposal_create", { fee: asset, + fee_paying_account: protocol_id_type("account"), + expiration_time: time_point_sec, + proposed_ops: array(op_wrapper), + review_period_seconds: optional(uint32), + extensions: set(future_extensions) }); + +var proposal_update = new Serializer("proposal_update", { fee: asset, + fee_paying_account: protocol_id_type("account"), + proposal: protocol_id_type("proposal"), + active_approvals_to_add: set(protocol_id_type("account")), + active_approvals_to_remove: set(protocol_id_type("account")), + owner_approvals_to_add: set(protocol_id_type("account")), + owner_approvals_to_remove: set(protocol_id_type("account")), + key_approvals_to_add: set(public_key), + key_approvals_to_remove: set(public_key), + extensions: set(future_extensions) }); + +var proposal_delete = new Serializer("proposal_delete", { fee: asset, + fee_paying_account: protocol_id_type("account"), + using_owner_authority: bool, + proposal: protocol_id_type("proposal"), + extensions: set(future_extensions) }); + +var withdraw_permission_create = new Serializer("withdraw_permission_create", { fee: asset, + withdraw_from_account: protocol_id_type("account"), + authorized_account: protocol_id_type("account"), + withdrawal_limit: asset, + withdrawal_period_sec: uint32, + periods_until_expiration: uint32, + period_start_time: time_point_sec }); + +var withdraw_permission_update = new Serializer("withdraw_permission_update", { fee: asset, + withdraw_from_account: protocol_id_type("account"), + authorized_account: protocol_id_type("account"), + permission_to_update: protocol_id_type("withdraw_permission"), + withdrawal_limit: asset, + withdrawal_period_sec: uint32, + period_start_time: time_point_sec, + periods_until_expiration: uint32 }); + +var withdraw_permission_claim = new Serializer("withdraw_permission_claim", { fee: asset, + withdraw_permission: protocol_id_type("withdraw_permission"), + withdraw_from_account: protocol_id_type("account"), + withdraw_to_account: protocol_id_type("account"), + amount_to_withdraw: asset, + memo: optional(memo_data) }); + +var withdraw_permission_delete = new Serializer("withdraw_permission_delete", { fee: asset, + withdraw_from_account: protocol_id_type("account"), + authorized_account: protocol_id_type("account"), + withdrawal_permission: protocol_id_type("withdraw_permission") }); + +var committee_member_create = new Serializer("committee_member_create", { fee: asset, + committee_member_account: protocol_id_type("account"), + url: string }); + +var committee_member_update = new Serializer("committee_member_update", { fee: asset, + committee_member: protocol_id_type("committee_member"), + committee_member_account: protocol_id_type("account"), + new_url: optional(string) }); + +var chain_parameters = new Serializer("chain_parameters", { current_fees: fee_schedule, + block_interval: uint8, + maintenance_interval: uint32, + maintenance_skip_slots: uint8, + committee_proposal_review_period: uint32, + maximum_transaction_size: uint32, + maximum_block_size: uint32, + maximum_time_until_expiration: uint32, + maximum_proposal_lifetime: uint32, + maximum_asset_whitelist_authorities: uint8, + maximum_asset_feed_publishers: uint8, + maximum_witness_count: uint16, + maximum_committee_count: uint16, + maximum_authority_membership: uint16, + reserve_percent_of_fee: uint16, + network_percent_of_fee: uint16, + lifetime_referrer_percent_of_fee: uint16, + cashback_vesting_period_seconds: uint32, + cashback_vesting_threshold: int64, + count_non_member_votes: bool, + allow_non_member_whitelists: bool, + witness_pay_per_block: int64, + worker_budget_per_day: int64, + max_predicate_opcode: uint16, + fee_liquidation_threshold: int64, + accounts_per_fee_scale: uint16, + account_fee_scale_bitshifts: uint8, + max_authority_depth: uint8, + extensions: set(future_extensions) }); + +var committee_member_update_global_parameters = new Serializer("committee_member_update_global_parameters", { fee: asset, + new_parameters: chain_parameters }); + +var linear_vesting_policy_initializer = new Serializer("linear_vesting_policy_initializer", { begin_timestamp: time_point_sec, + vesting_cliff_seconds: uint32, + vesting_duration_seconds: uint32 }); + +var cdd_vesting_policy_initializer = new Serializer("cdd_vesting_policy_initializer", { start_claim: time_point_sec, + vesting_seconds: uint32 }); + +var vesting_policy_initializer = static_variant([linear_vesting_policy_initializer, cdd_vesting_policy_initializer]); + +var vesting_balance_create = new Serializer("vesting_balance_create", { fee: asset, + creator: protocol_id_type("account"), + owner: protocol_id_type("account"), + amount: asset, + policy: vesting_policy_initializer }); + +var vesting_balance_withdraw = new Serializer("vesting_balance_withdraw", { fee: asset, + vesting_balance: protocol_id_type("vesting_balance"), + owner: protocol_id_type("account"), + amount: asset }); + +var refund_worker_initializer = new Serializer("refund_worker_initializer"); + +var vesting_balance_worker_initializer = new Serializer("vesting_balance_worker_initializer", { pay_vesting_period_days: uint16 }); + +var burn_worker_initializer = new Serializer("burn_worker_initializer"); + +var worker_initializer = static_variant([refund_worker_initializer, vesting_balance_worker_initializer, burn_worker_initializer]); + +var worker_create = new Serializer("worker_create", { fee: asset, + owner: protocol_id_type("account"), + work_begin_date: time_point_sec, + work_end_date: time_point_sec, + daily_pay: int64, + name: string, + url: string, + initializer: worker_initializer }); + +var custom = new Serializer("custom", { fee: asset, + payer: protocol_id_type("account"), + required_auths: set(protocol_id_type("account")), + id: uint16, + data: bytes() }); + +var account_name_eq_lit_predicate = new Serializer("account_name_eq_lit_predicate", { account_id: protocol_id_type("account"), + name: string }); + +var asset_symbol_eq_lit_predicate = new Serializer("asset_symbol_eq_lit_predicate", { asset_id: protocol_id_type("asset"), + symbol: string }); + +var block_id_predicate = new Serializer("block_id_predicate", { id: bytes(20) }); + +var predicate = static_variant([account_name_eq_lit_predicate, asset_symbol_eq_lit_predicate, block_id_predicate]); + +var assert = new Serializer("assert", { fee: asset, + fee_paying_account: protocol_id_type("account"), + predicates: array(predicate), + required_auths: set(protocol_id_type("account")), + extensions: set(future_extensions) }); + +var balance_claim = new Serializer("balance_claim", { fee: asset, + deposit_to_account: protocol_id_type("account"), + balance_to_claim: protocol_id_type("balance"), + balance_owner_key: public_key, + total_claimed: asset }); + +var override_transfer = new Serializer("override_transfer", { fee: asset, + issuer: protocol_id_type("account"), + from: protocol_id_type("account"), + to: protocol_id_type("account"), + amount: asset, + memo: optional(memo_data), + extensions: set(future_extensions) }); + +var stealth_confirmation = new Serializer("stealth_confirmation", { one_time_key: public_key, + to: optional(public_key), + encrypted_memo: bytes() }); + +var blind_output = new Serializer("blind_output", { commitment: bytes(33), + range_proof: bytes(), + owner: authority, + stealth_memo: optional(stealth_confirmation) }); + +var transfer_to_blind = new Serializer("transfer_to_blind", { fee: asset, + amount: asset, + from: protocol_id_type("account"), + blinding_factor: bytes(32), + outputs: array(blind_output) }); + +var blind_input = new Serializer("blind_input", { commitment: bytes(33), + owner: authority }); + +var blind_transfer = new Serializer("blind_transfer", { fee: asset, + inputs: array(blind_input), + outputs: array(blind_output) }); + +var transfer_from_blind = new Serializer("transfer_from_blind", { fee: asset, + amount: asset, + to: protocol_id_type("account"), + blinding_factor: bytes(32), + inputs: array(blind_input) }); + +var asset_settle_cancel = new Serializer("asset_settle_cancel", { fee: asset, + settlement: protocol_id_type("force_settlement"), + account: protocol_id_type("account"), + amount: asset, + extensions: set(future_extensions) }); + +var asset_claim_fees = new Serializer("asset_claim_fees", { fee: asset, + issuer: protocol_id_type("account"), + amount_to_claim: asset, + extensions: set(future_extensions) }); + +var fba_distribute = new Serializer("fba_distribute", { fee: asset, + account_id: protocol_id_type("account"), + fba_id: protocol_id_type("fba_accumulator"), + amount: int64 }); + +var dividend_asset_options = new Serializer("dividend_asset_options", { next_payout_time: optional(time_point_sec), + payout_interval: optional(uint32), + minimum_fee_percentage: uint64, + minimum_distribution_interval: optional(uint32), + extensions: set(future_extensions) }); + +var asset_update_dividend = new Serializer("asset_update_dividend", { fee: asset, + issuer: protocol_id_type("account"), + asset_to_update: protocol_id_type("asset"), + new_options: dividend_asset_options, + extensions: set(future_extensions) }); + +var rock_paper_scissors_game_options = new Serializer("rock_paper_scissors_game_options", { insurance_enabled: bool, + time_per_commit_move: uint32, + time_per_reveal_move: uint32, + number_of_gestures: uint8 }); + +var game_specific_details = static_variant([rock_paper_scissors_game_options]); + +var tournament_options = new Serializer("tournament_options", { + type_of_game: uint16, + registration_deadline: time_point_sec, + number_of_players: uint32, + buy_in: asset, + whitelist: set(protocol_id_type("account")), + start_time: optional(time_point_sec), + start_delay: optional(uint32), + round_delay: uint32, + number_of_wins: uint32, + meta: variant_object, + game_options: game_specific_details +}); + +var tournament_create = new Serializer("tournament_create", { fee: asset, + creator: protocol_id_type("account"), + options: tournament_options, + extensions: set(future_extensions) }); + +var tournament_join = new Serializer("tournament_join", { fee: asset, + payer_account_id: protocol_id_type("account"), + player_account_id: protocol_id_type("account"), + tournament_id: protocol_id_type("tournament"), + buy_in: asset, + extensions: set(future_extensions) }); + +var rock_paper_scissors_gesture = enumeration(["rock", "paper", "scissors", "spock", "lizard"]); + +var rock_paper_scissors_throw_commit = new Serializer("rock_paper_scissors_throw_commit", { nonce1: uint64, + throw_hash: sha256 }); + +var rock_paper_scissors_throw_reveal = new Serializer("rock_paper_scissors_throw_reveal", { nonce2: uint64, + gesture: rock_paper_scissors_gesture }); + +var game_specific_moves = static_variant([rock_paper_scissors_throw_commit, rock_paper_scissors_throw_reveal]); + +var game_move = new Serializer("game_move", { fee: asset, + game_id: protocol_id_type("game"), + player_account_id: protocol_id_type("account"), + move: game_specific_moves, + extensions: set(future_extensions) }); + +operation.st_operations = [transfer, limit_order_create, limit_order_cancel, call_order_update, fill_order, account_create, account_update, account_whitelist, account_upgrade, account_transfer, asset_create, asset_update, asset_update_bitasset, asset_update_feed_producers, asset_issue, asset_reserve, asset_fund_fee_pool, asset_settle, asset_global_settle, asset_publish_feed, witness_create, witness_update, proposal_create, proposal_update, proposal_delete, withdraw_permission_create, withdraw_permission_update, withdraw_permission_claim, withdraw_permission_delete, committee_member_create, committee_member_update, committee_member_update_global_parameters, vesting_balance_create, vesting_balance_withdraw, worker_create, custom, assert, balance_claim, override_transfer, transfer_to_blind, blind_transfer, transfer_from_blind, asset_settle_cancel, asset_claim_fees, fba_distribute, tournament_create, tournament_join, game_move, asset_update_dividend]; + +var transaction = new Serializer("transaction", { ref_block_num: uint16, + ref_block_prefix: uint32, + expiration: time_point_sec, + operations: array(operation), + extensions: set(future_extensions) }); + +var signed_transaction = new Serializer("signed_transaction", { ref_block_num: uint16, + ref_block_prefix: uint32, + expiration: time_point_sec, + operations: array(operation), + extensions: set(future_extensions), + signatures: array(bytes(65)) }); +//# ------------------------------- +//# Generated code end +//# ------------------------------- + +// Custom Types + +var stealth_memo_data = new Serializer("stealth_memo_data", { + from: optional(public_key), + amount: asset, + blinding_factor: bytes(32), + commitment: bytes(33), + check: uint32 +}); +// var stealth_confirmation = new Serializer( +// "stealth_confirmation", { +// one_time_key: public_key, +// to: optional( public_key ), +// encrypted_memo: stealth_memo_data +// }) \ No newline at end of file diff --git a/dist/serializer/src/precision.js b/dist/serializer/src/precision.js new file mode 100644 index 0000000..81e7ab3 --- /dev/null +++ b/dist/serializer/src/precision.js @@ -0,0 +1,95 @@ +'use strict'; + +var _my; +var _internal; +var v = require('./SerializerValidation'); +var BigInteger = require('bigi'); + +module.exports = _my = + +// Result may be used for int64 types (like transfer amount). Asset's +// precision is used to convert the number to a whole number with an implied +// decimal place. + +// "1.01" with a precision of 2 returns long 101 +// See http://cryptocoinjs.com/modules/misc/bigi/#example +{ + to_bigint64: function to_bigint64(number_or_string, precision) { + var error_info = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; + + var long = _internal.to_long64(number_or_string, precision, error_info); + return BigInteger(long.toString()); + }, + + + // 101 string or long with a precision of 2 returns "1.01" + to_string64: function to_string64(number_or_string, precision) { + var error_info = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; + + v.required(number_or_string, error_info); + v.number(precision, error_info); + var number_long = v.to_long(number_or_string, error_info); + var string64 = _internal.decimal_precision_string(number_long, precision, error_info); + v.no_overflow64(string64, error_info); + return string64; + } +}; + +// _internal is for low-level transaction code +module.exports._internal = _internal = + +// Warning: Long operations may over-flow without detection +{ + to_long64: function to_long64(number_or_string, precision) { + var error_info = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; + + v.required(number_or_string, "number_or_string " + error_info); + v.required(precision, "precision " + error_info); + return v.to_long(_internal.decimal_precision_string(number_or_string, precision, error_info)); + }, + decimal_precision_string: function decimal_precision_string(number, precision) { + var error_info = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; + + v.required(number, "number " + error_info); + v.required(precision, "precision " + error_info); + + var number_string = v.to_string(number); + number_string = number_string.trim(); + precision = v.to_number(precision); + + // remove leading zeros (not suffixing) + var number_parts = number_string.match(/^-?0*([0-9]*)\.?([0-9]*)$/); + if (!number_parts) { + throw new Error('Invalid number: ' + number_string + ' ' + error_info); + } + + var sign = number_string.charAt(0) === '-' ? '-' : ''; + var int_part = number_parts[1]; + var decimal_part = number_parts[2]; + if (!decimal_part) { + decimal_part = ""; + } + + // remove trailing zeros + while (/0$/.test(decimal_part)) { + decimal_part = decimal_part.substring(0, decimal_part.length - 1); + } + + var zero_pad_count = precision - decimal_part.length; + if (zero_pad_count < 0) { + throw new Error('overflow, up to ' + precision + ' decimals may be used ' + error_info); + } + + if (sign === "-" && !/[1-9]/.test(int_part + decimal_part)) { + sign = ""; + } + if (int_part === "") { + int_part = "0"; + } + for (var i = 0; 0 < zero_pad_count ? i < zero_pad_count : i > zero_pad_count; 0 < zero_pad_count ? i++ : i++) { + decimal_part += "0"; + } + + return sign + int_part + decimal_part; + } +}; \ No newline at end of file diff --git a/dist/serializer/src/serializer.js b/dist/serializer/src/serializer.js new file mode 100644 index 0000000..161ca14 --- /dev/null +++ b/dist/serializer/src/serializer.js @@ -0,0 +1,207 @@ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var ByteBuffer = require('bytebuffer'); +var EC = require('./error_with_cause'); + +var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; + +var Serializer = function () { + function Serializer(operation_name, types) { + _classCallCheck(this, Serializer); + + this.operation_name = operation_name; + this.types = types; + if (this.types) this.keys = Object.keys(this.types); + + Serializer.printDebug = true; + } + + _createClass(Serializer, [{ + key: 'fromByteBuffer', + value: function fromByteBuffer(b) { + var object = {}; + var field = null; + try { + var iterable = this.keys; + for (var i = 0, field; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + try { + if (HEX_DUMP) { + if (type.operation_name) { + console.error(type.operation_name); + } else { + var o1 = b.offset; + type.fromByteBuffer(b); + var o2 = b.offset; + b.offset = o1; + //b.reset() + var _b = b.copy(o1, o2); + console.error(this.operation_name + '.' + field + '\t', _b.toHex()); + } + } + object[field] = type.fromByteBuffer(b); + } catch (e) { + if (Serializer.printDebug) { + console.error('Error reading ' + this.operation_name + '.' + field + ' in data:'); + b.printDebug(); + } + throw e; + } + } + } catch (error) { + EC.throw(this.operation_name + '.' + field, error); + } + + return object; + } + }, { + key: 'appendByteBuffer', + value: function appendByteBuffer(b, object) { + var field = null; + try { + var iterable = this.keys; + for (var i = 0, field; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + type.appendByteBuffer(b, object[field]); + } + } catch (error) { + try { + EC.throw(this.operation_name + '.' + field + " = " + JSON.stringify(object[field]), error); + } catch (e) { + // circular ref + EC.throw(this.operation_name + '.' + field + " = " + object[field], error); + } + } + return; + } + }, { + key: 'fromObject', + value: function fromObject(serialized_object) { + var result = {}; + var field = null; + try { + var iterable = this.keys; + for (var i = 0, field; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + var value = serialized_object[field]; + //DEBUG value = value.resolve if value.resolve + //DEBUG console.log('... value',field,value) + var object = type.fromObject(value); + result[field] = object; + } + } catch (error) { + EC.throw(this.operation_name + '.' + field, error); + } + + return result; + } + + /** + @arg {boolean} [debug.use_default = false] - more template friendly + @arg {boolean} [debug.annotate = false] - add user-friendly information + */ + + }, { + key: 'toObject', + value: function toObject() { + var serialized_object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { use_default: false, annotate: false }; + + var result = {}; + var field = null; + try { + if (!this.types) return result; + + var iterable = this.keys; + for (var i = 0, field; i < iterable.length; i++) { + field = iterable[i]; + var type = this.types[field]; + var object = type.toObject(typeof serialized_object !== "undefined" && serialized_object !== null ? serialized_object[field] : undefined, debug); + result[field] = object; + if (HEX_DUMP) { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + type.appendByteBuffer(b, typeof serialized_object !== "undefined" && serialized_object !== null ? serialized_object[field] : undefined); + b = b.copy(0, b.offset); + console.error(this.operation_name + '.' + field, b.toHex()); + } + } + } catch (error) { + EC.throw(this.operation_name + '.' + field, error); + } + + return result; + } + + /** Sort by the first element in a operation */ + + }, { + key: 'compare', + value: function compare(a, b) { + + var first_key = this.keys[0]; + var first_type = this.types[first_key]; + + var valA = a[first_key]; + var valB = b[first_key]; + + if (first_type.compare) return first_type.compare(valA, valB); + + if (typeof valA === "number" && typeof valB === "number") return valA - valB; + + var encoding = void 0; + if (Buffer.isBuffer(valA) && Buffer.isBuffer(valB)) { + // A binary string compare does not work. If localeCompare is well supported that could replace HEX. Performanance is very good so comparing HEX works. + encoding = "hex"; + } + + var strA = valA.toString(encoding); + var strB = valB.toString(encoding); + return strA > strB ? 1 : strA < strB ? -1 : 0; + } + + // + + }, { + key: 'fromHex', + value: function fromHex(hex) { + var b = ByteBuffer.fromHex(hex, ByteBuffer.LITTLE_ENDIAN); + return this.fromByteBuffer(b); + } + }, { + key: 'fromBuffer', + value: function fromBuffer(buffer) { + var b = ByteBuffer.fromBinary(buffer.toString("binary"), ByteBuffer.LITTLE_ENDIAN); + return this.fromByteBuffer(b); + } + }, { + key: 'toHex', + value: function toHex(object) { + // return this.toBuffer(object).toString("hex") + var b = this.toByteBuffer(object); + return b.toHex(); + } + }, { + key: 'toByteBuffer', + value: function toByteBuffer(object) { + var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); + this.appendByteBuffer(b, object); + return b.copy(0, b.offset); + } + }, { + key: 'toBuffer', + value: function toBuffer(object) { + return new Buffer(this.toByteBuffer(object).toBinary(), 'binary'); + } + }]); + + return Serializer; +}(); + +module.exports = Serializer; \ No newline at end of file diff --git a/dist/serializer/src/template.js b/dist/serializer/src/template.js new file mode 100644 index 0000000..d1e5d0d --- /dev/null +++ b/dist/serializer/src/template.js @@ -0,0 +1,17 @@ +"use strict"; + +/** Console print any transaction object with zero default values. */ +module.exports = function template(op) { + + var object = op.toObject(void 0, { use_default: true, annotate: true }); + + // visual (with descriptions) + console.error(JSON.stringify(object, null, 4)); + + // usable in a copy-paste + + object = op.toObject(void 0, { use_default: true, annotate: false }); + + // copy-paste one-lineer + console.error(JSON.stringify(object)); +}; \ No newline at end of file diff --git a/dist/serializer/src/types.js b/dist/serializer/src/types.js new file mode 100644 index 0000000..45a0225 --- /dev/null +++ b/dist/serializer/src/types.js @@ -0,0 +1,1024 @@ +'use strict'; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; 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"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +// Low-level types that make up operations + +var v = require('./SerializerValidation'); +var fp = require('./FastParser'); + +var ChainTypes = require("../../chain/src/ChainTypes"); +var ObjectId = require("../../chain/src/ObjectId"); + +var _require = require("../../ecc"), + PublicKey = _require.PublicKey, + Address = _require.Address; + +var _require2 = require("peerplaysjs-ws"), + ChainConfig = _require2.ChainConfig; + +var Types = {}; +module.exports = Types; + +var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; + +Types.uint8 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint8(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.require_range(0, 0xFF, object, 'uint8 ' + object); + b.writeUint8(object); + return; + }, + fromObject: function fromObject(object) { + v.require_range(0, 0xFF, object, 'uint8 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return 0; + } + v.require_range(0, 0xFF, object, 'uint8 ' + object); + return parseInt(object); + } +}; + +Types.uint16 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint16(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.require_range(0, 0xFFFF, object, 'uint16 ' + object); + b.writeUint16(object); + return; + }, + fromObject: function fromObject(object) { + v.require_range(0, 0xFFFF, object, 'uint16 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return 0; + } + v.require_range(0, 0xFFFF, object, 'uint16 ' + object); + return parseInt(object); + } +}; + +Types.uint32 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.require_range(0, 0xFFFFFFFF, object, 'uint32 ' + object); + b.writeUint32(object); + return; + }, + fromObject: function fromObject(object) { + v.require_range(0, 0xFFFFFFFF, object, 'uint32 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return 0; + } + v.require_range(0, 0xFFFFFFFF, object, 'uint32 ' + object); + return parseInt(object); + } +}; + +var MIN_SIGNED_32 = -1 * Math.pow(2, 31); +var MAX_SIGNED_32 = Math.pow(2, 31) - 1; + +Types.varint32 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readVarint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); + b.writeVarint32(object); + return; + }, + fromObject: function fromObject(object) { + v.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return 0; + } + v.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object); + return parseInt(object); + } +}; + +Types.int64 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readInt64(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + b.writeInt64(v.to_long(object)); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + return v.to_long(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return "0"; + } + v.required(object); + return v.to_long(object).toString(); + } +}; + +Types.uint64 = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint64(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + b.writeUint64(v.to_ulong(v.unsigned(object))); + return; + }, + fromObject: function fromObject(object) { + return v.to_ulong(v.unsigned(object)); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return "0"; + } + return v.to_ulong(object).toString(); + } +}; + +Types.string = { + fromByteBuffer: function fromByteBuffer(b) { + var b_copy; + var len = b.readVarint32(); + b_copy = b.copy(b.offset, b.offset + len), b.skip(len); + return new Buffer(b_copy.toBinary(), 'binary'); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + b.writeVarint32(object.length); + b.append(object.toString('binary'), 'binary'); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + return new Buffer(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return ""; + } + return object.toString(); + } +}; + +Types.bytes = function (size) { + return { + fromByteBuffer: function fromByteBuffer(b) { + if (size === undefined) { + var b_copy; + var len = b.readVarint32(); + b_copy = b.copy(b.offset, b.offset + len), b.skip(len); + return new Buffer(b_copy.toBinary(), 'binary'); + } else { + b_copy = b.copy(b.offset, b.offset + size), b.skip(size); + return new Buffer(b_copy.toBinary(), 'binary'); + } + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + if (typeof object === "string") object = new Buffer(object, "hex"); + + if (size === undefined) { + b.writeVarint32(object.length); + } + b.append(object.toString('binary'), 'binary'); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + if (Buffer.isBuffer(object)) return object; + + return new Buffer(object, 'hex'); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + var zeros = function zeros(num) { + return new Array(num).join("00"); + }; + return zeros(size); + } + v.required(object); + return object.toString('hex'); + } + }; +}; + +Types.bool = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint8() === 1; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + // supports boolean or integer + b.writeUint8(JSON.parse(object) ? 1 : 0); + return; + }, + fromObject: function fromObject(object) { + return JSON.parse(object) ? true : false; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return false; + } + return JSON.parse(object) ? true : false; + } +}; + +Types.void = { + fromByteBuffer: function fromByteBuffer(b) { + throw new Error("(void) undefined type"); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + throw new Error("(void) undefined type"); + }, + fromObject: function fromObject(object) { + throw new Error("(void) undefined type"); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return undefined; + } + throw new Error("(void) undefined type"); + } +}; + +Types.array = function (st_operation) { + return { + fromByteBuffer: function fromByteBuffer(b) { + var size = b.readVarint32(); + if (HEX_DUMP) { + console.log("varint32 size = " + size.toString(16)); + } + var result = []; + for (var i = 0; 0 < size ? i < size : i > size; 0 < size ? i++ : i++) { + result.push(st_operation.fromByteBuffer(b)); + } + return sortOperation(result, st_operation); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + object = sortOperation(object, st_operation); + b.writeVarint32(object.length); + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + st_operation.appendByteBuffer(b, o); + } + }, + fromObject: function fromObject(object) { + v.required(object); + object = sortOperation(object, st_operation); + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push(st_operation.fromObject(o)); + } + return result; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [st_operation.toObject(object, debug)]; + } + v.required(object); + object = sortOperation(object, st_operation); + + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push(st_operation.toObject(o, debug)); + } + return result; + } + }; +}; + +Types.time_point_sec = { + fromByteBuffer: function fromByteBuffer(b) { + return b.readUint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (typeof object !== "number") object = Types.time_point_sec.fromObject(object); + + b.writeUint32(object); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + + if (typeof object === "number") return object; + + if (object.getTime) return Math.floor(object.getTime() / 1000); + + if (typeof object !== "string") throw new Error("Unknown date type: " + object); + + // if(typeof object === "string" && !/Z$/.test(object)) + // object = object + "Z" + + return Math.floor(new Date(object).getTime() / 1000); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) return new Date(0).toISOString().split('.')[0]; + + v.required(object); + + if (typeof object === "string") return object; + + if (object.getTime) return object.toISOString().split('.')[0]; + + var int = parseInt(object); + v.require_range(0, 0xFFFFFFFF, int, 'uint32 ' + object); + return new Date(int * 1000).toISOString().split('.')[0]; + } +}; + +Types.set = function (st_operation) { + return { + validate: function validate(array) { + var dup_map = {}; + for (var i = 0, o; i < array.length; i++) { + o = array[i]; + var ref; + if (ref = typeof o === 'undefined' ? 'undefined' : _typeof(o), ['string', 'number'].indexOf(ref) >= 0) { + if (dup_map[o] !== undefined) { + throw new Error("duplicate (set)"); + } + dup_map[o] = true; + } + } + return sortOperation(array, st_operation); + }, + fromByteBuffer: function fromByteBuffer(b) { + var size = b.readVarint32(); + if (HEX_DUMP) { + console.log("varint32 size = " + size.toString(16)); + } + return this.validate(function () { + var result = []; + for (var i = 0; 0 < size ? i < size : i > size; 0 < size ? i++ : i++) { + result.push(st_operation.fromByteBuffer(b)); + } + return result; + }()); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (!object) { + object = []; + } + b.writeVarint32(object.length); + var iterable = this.validate(object); + for (var i = 0, o; i < iterable.length; i++) { + o = iterable[i]; + st_operation.appendByteBuffer(b, o); + } + return; + }, + fromObject: function fromObject(object) { + if (!object) { + object = []; + } + return this.validate(function () { + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push(st_operation.fromObject(o)); + } + return result; + }()); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [st_operation.toObject(object, debug)]; + } + if (!object) { + object = []; + } + return this.validate(function () { + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push(st_operation.toObject(o, debug)); + } + return result; + }()); + } + }; +}; + +// global_parameters_update_operation current_fees +Types.fixed_array = function (count, st_operation) { + return { + fromByteBuffer: function fromByteBuffer(b) { + var i, j, ref, results; + results = []; + for (i = j = 0, ref = count; j < ref; i = j += 1) { + results.push(st_operation.fromByteBuffer(b)); + } + return sortOperation(results, st_operation); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + var i, j, ref; + if (count !== 0) { + v.required(object); + object = sortOperation(object, st_operation); + } + for (i = j = 0, ref = count; j < ref; i = j += 1) { + st_operation.appendByteBuffer(b, object[i]); + } + }, + fromObject: function fromObject(object) { + var i, j, ref, results; + if (count !== 0) { + v.required(object); + } + results = []; + for (i = j = 0, ref = count; j < ref; i = j += 1) { + results.push(st_operation.fromObject(object[i])); + } + return results; + }, + toObject: function toObject(object, debug) { + var i, j, k, ref, ref1, results, results1; + if (debug == null) { + debug = {}; + } + if (debug.use_default && object === void 0) { + results = []; + for (i = j = 0, ref = count; j < ref; i = j += 1) { + results.push(st_operation.toObject(void 0, debug)); + } + return results; + } + if (count !== 0) { + v.required(object); + } + results1 = []; + for (i = k = 0, ref1 = count; k < ref1; i = k += 1) { + results1.push(st_operation.toObject(object[i], debug)); + } + return results1; + } + }; +}; + +/* Supports instance numbers (11) or object types (1.2.11). Object type +Validation is enforced when an object type is used. */ +var id_type = function id_type(reserved_spaces, object_type) { + v.required(reserved_spaces, "reserved_spaces"); + v.required(object_type, "object_type"); + return { + fromByteBuffer: function fromByteBuffer(b) { + return b.readVarint32(); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + // convert 1.2.n into just n + if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { + object = v.get_instance(reserved_spaces, object_type, object); + } + b.writeVarint32(v.to_number(object)); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + if (v.is_digits(object)) { + return v.to_number(object); + } + return v.get_instance(reserved_spaces, object_type, object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var object_type_id = ChainTypes.object_type[object_type]; + if (debug.use_default && object === undefined) { + return reserved_spaces + '.' + object_type_id + '.0'; + } + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { + object = v.get_instance(reserved_spaces, object_type, object); + } + + return reserved_spaces + '.' + object_type_id + '.' + object; + } + }; +}; + +Types.protocol_id_type = function (name) { + v.required(name, "name"); + return id_type(ChainTypes.reserved_spaces.protocol_ids, name); +}; + +Types.object_id_type = { + fromByteBuffer: function fromByteBuffer(b) { + return ObjectId.fromByteBuffer(b); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + object = ObjectId.fromString(object); + object.appendByteBuffer(b); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + return ObjectId.fromString(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return "0.0.0"; + } + v.required(object); + if (object.resolve !== undefined) { + object = object.resolve; + } + object = ObjectId.fromString(object); + return object.toString(); + } +}; + +Types.vote_id = { TYPE: 0x000000FF, + ID: 0xFFFFFF00, + fromByteBuffer: function fromByteBuffer(b) { + var value = b.readUint32(); + return { + type: value & this.TYPE, + id: value & this.ID + }; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + if (object === "string") object = Types.vote_id.fromObject(object); + + var value = object.id << 8 | object.type; + b.writeUint32(value); + return; + }, + fromObject: function fromObject(object) { + v.required(object, "(type vote_id)"); + if ((typeof object === 'undefined' ? 'undefined' : _typeof(object)) === "object") { + v.required(object.type, "type"); + v.required(object.id, "id"); + return object; + } + v.require_test(/^[0-9]+:[0-9]+$/, object, 'vote_id format ' + object); + + var _object$split = object.split(':'), + _object$split2 = _slicedToArray(_object$split, 2), + type = _object$split2[0], + id = _object$split2[1]; + + v.require_range(0, 0xff, type, 'vote type ' + object); + v.require_range(0, 0xffffff, id, 'vote id ' + object); + return { type: type, id: id }; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return "0:0"; + } + v.required(object); + if (typeof object === "string") object = Types.vote_id.fromObject(object); + + return object.type + ":" + object.id; + }, + compare: function compare(a, b) { + if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) !== "object") a = Types.vote_id.fromObject(a); + if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) !== "object") b = Types.vote_id.fromObject(b); + return parseInt(a.id) - parseInt(b.id); + } +}; + +Types.optional = function (st_operation) { + v.required(st_operation, "st_operation"); + return { + fromByteBuffer: function fromByteBuffer(b) { + if (!(b.readUint8() === 1)) { + return undefined; + } + return st_operation.fromByteBuffer(b); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (object !== null && object !== undefined) { + b.writeUint8(1); + st_operation.appendByteBuffer(b, object); + } else { + b.writeUint8(0); + } + return; + }, + fromObject: function fromObject(object) { + if (object === undefined) { + return undefined; + } + return st_operation.fromObject(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + // toObject is only null save if use_default is true + var result_object = function () { + if (!debug.use_default && object === undefined) { + return undefined; + } else { + return st_operation.toObject(object, debug); + } + }(); + + if (debug.annotate) { + if ((typeof result_object === 'undefined' ? 'undefined' : _typeof(result_object)) === "object") { + result_object.__optional = "parent is optional"; + } else { + result_object = { __optional: result_object }; + } + } + return result_object; + } + }; +}; + +Types.static_variant = function (_st_operations) { + return { + nosort: true, + st_operations: _st_operations, + fromByteBuffer: function fromByteBuffer(b) { + var type_id = b.readVarint32(); + var st_operation = this.st_operations[type_id]; + if (HEX_DUMP) { + console.error('static_variant id 0x' + type_id.toString(16) + ' (' + type_id + ')'); + } + v.required(st_operation, 'operation ' + type_id); + return [type_id, st_operation.fromByteBuffer(b)]; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + var type_id = object[0]; + var st_operation = this.st_operations[type_id]; + v.required(st_operation, 'operation ' + type_id); + b.writeVarint32(type_id); + st_operation.appendByteBuffer(b, object[1]); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + var type_id = object[0]; + var st_operation = this.st_operations[type_id]; + v.required(st_operation, 'operation ' + type_id); + return [type_id, st_operation.fromObject(object[1])]; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [0, this.st_operations[0].toObject(undefined, debug)]; + } + v.required(object); + var type_id = object[0]; + var st_operation = this.st_operations[type_id]; + v.required(st_operation, 'operation ' + type_id); + return [type_id, st_operation.toObject(object[1], debug)]; + } + }; +}; + +Types.map = function (key_st_operation, value_st_operation) { + return { + validate: function validate(array) { + if (!Array.isArray(array)) { + throw new Error("expecting array"); + } + var dup_map = {}; + for (var i = 0, o; i < array.length; i++) { + o = array[i]; + var ref; + if (!(o.length === 2)) { + throw new Error("expecting two elements"); + } + if (ref = _typeof(o[0]), ['number', 'string'].indexOf(ref) >= 0) { + if (dup_map[o[0]] !== undefined) { + throw new Error("duplicate (map)"); + } + dup_map[o[0]] = true; + } + } + return sortOperation(array, key_st_operation); + }, + fromByteBuffer: function fromByteBuffer(b) { + var result = []; + var end = b.readVarint32(); + for (var i = 0; 0 < end ? i < end : i > end; 0 < end ? i++ : i++) { + result.push([key_st_operation.fromByteBuffer(b), value_st_operation.fromByteBuffer(b)]); + } + return this.validate(result); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + this.validate(object); + b.writeVarint32(object.length); + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + key_st_operation.appendByteBuffer(b, o[0]); + value_st_operation.appendByteBuffer(b, o[1]); + } + return; + }, + fromObject: function fromObject(object) { + v.required(object); + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push([key_st_operation.fromObject(o[0]), value_st_operation.fromObject(o[1])]); + } + return this.validate(result); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return [[key_st_operation.toObject(undefined, debug), value_st_operation.toObject(undefined, debug)]]; + } + v.required(object); + object = this.validate(object); + var result = []; + for (var i = 0, o; i < object.length; i++) { + o = object[i]; + result.push([key_st_operation.toObject(o[0], debug), value_st_operation.toObject(o[1], debug)]); + } + return result; + } + }; +}; + +Types.public_key = { + toPublic: function toPublic(object) { + if (object.resolve !== undefined) { + object = object.resolve; + } + + if (object instanceof PublicKey) { + return object; + } + + return object == null ? object : object.Q ? object : PublicKey.fromStringOrThrow(object); + }, + fromByteBuffer: function fromByteBuffer(b) { + return fp.public_key(b); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + v.required(object); + fp.public_key(b, Types.public_key.toPublic(object)); + return; + }, + fromObject: function fromObject(object) { + v.required(object); + if (object.Q) { + return object; + } + return Types.public_key.toPublic(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return ChainConfig.address_prefix + "859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2HqhToVM"; + } + v.required(object); + return object.toString(); + }, + compare: function compare(a, b) { + return strCmp(a.toAddressString(), b.toAddressString()); + } +}; + +Types.address = { + _to_address: function _to_address(object) { + v.required(object); + if (object.addy) { + return object; + } + return Address.fromString(object); + }, + fromByteBuffer: function fromByteBuffer(b) { + return new Address(fp.ripemd160(b)); + }, + appendByteBuffer: function appendByteBuffer(b, object) { + fp.ripemd160(b, Types.address._to_address(object).toBuffer()); + return; + }, + fromObject: function fromObject(object) { + return Types.address._to_address(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return ChainConfig.address_prefix + "664KmHxSuQyDsfwo4WEJvWpzg1QKdg67S"; + } + return Types.address._to_address(object).toString(); + }, + compare: function compare(a, b) { + return strCmp(a.toString(), b.toString()); + } +}; + +Types.variant = { + fromByteBuffer: function fromByteBuffer(b) { + var type = b.readUint8(); + switch (type) { + case 0: + return null; + case 1: + return Types.int64.fromByteBuffer(b); + case 2: + return Types.uint64.fromByteBuffer(b); + case 3: + return b.readDouble(); + case 4: + return Types.bool.fromByteBuffer(b); + case 5: + return Types.string.fromByteBuffer(b); + case 6: + return Types.array(Types.variant).fromByteBuffer(b); + case 7: + default: + return Types.variant_object.fromByteBuffer(b); + }; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + if (typeof object == 'number') { + if (Number.isInteger(object)) { + if (object >= 0) { + b.writeUint8(2); + Types.uint64.appendByteBuffer(b, object); + } else { + b.writeUint8(1); + Types.int64.appendByteBuffer(b, object); + } + } else { + b.writeUint8(3); + b.writeDouble(Number.parseFloat(object)); + } + } else if (typeof object == 'boolean') { + b.writeUint8(4); + Types.bool.appendByteBuffer(b, object); + } else if (typeof object == 'string') { + b.writeUint8(5); + Types.string.appendByteBuffer(b, object); + } else if (typeof object == 'array') { + b.writeUint8(6); + Types.array(Types.variant).appendByteBuffer(b, object); + } else { + b.writeUint8(7); + Types.variant_object.appendByteBuffer(b, object); + } + }, + fromObject: function fromObject(object) { + return JSON.parse(object); + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + return null; + } + return JSON.parse(object); + } +}; + +Types.variant_object = { + fromByteBuffer: function fromByteBuffer(b) { + var count = b.readVarint32(); + var result = {}; + for (var i = 0; i < count; ++i) { + var key = Types.string.fromByteBuffer(b); + result[key] = Types.variant.fromByteBuffer(b); + } + return result; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + var count = 0; + for (var key in object) { + if (object.hasOwnProperty(key)) ++count; + }b.writeVarint32(count); // number of key/value pairs + for (var key in object) { + if (object.hasOwnProperty(key)) { + Types.string.appendByteBuffer(b, key); + Types.variant.appendByteBuffer(b, object[key]); + } + }return; + }, + fromObject: function fromObject(object) { + var newObject = {}; + for (var key in object) { + if (object.hasOwnProperty(key)) newObject[key] = object[key]; + }return newObject; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var newObject = {}; + for (var key in object) { + if (object.hasOwnProperty(key)) newObject[key] = object[key]; + }return newObject; + } +}; + +Types.enumeration = function (values) { + return { + fromByteBuffer: function fromByteBuffer(b) { + return values[b.readVarint32ZigZag()]; + }, + appendByteBuffer: function appendByteBuffer(b, object) { + b.writeVarint32ZigZag(values.indexOf(object)); + return; + }, + fromObject: function fromObject(object) { + return object; + }, + toObject: function toObject(object) { + var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (debug.use_default && object === undefined) { + values[0]; + } + return object; + } + }; +}; + +Types.sha256 = Types.bytes(32); + +var strCmp = function strCmp(a, b) { + return a > b ? 1 : a < b ? -1 : 0; +}; +var firstEl = function firstEl(el) { + return Array.isArray(el) ? el[0] : el; +}; +var sortOperation = function sortOperation(array, st_operation) { + return st_operation.nosort ? array : st_operation.compare ? array.sort(function (a, b) { + return st_operation.compare(firstEl(a), firstEl(b)); + }) : // custom compare operation + array.sort(function (a, b) { + return typeof firstEl(a) === "number" && typeof firstEl(b) === "number" ? firstEl(a) - firstEl(b) : + // A binary string compare does not work. Performanance is very good so HEX is used.. localeCompare is another option. + Buffer.isBuffer(firstEl(a)) && Buffer.isBuffer(firstEl(b)) ? strCmp(firstEl(a).toString("hex"), firstEl(b).toString("hex")) : strCmp(firstEl(a).toString(), firstEl(b).toString()); + }); +}; \ No newline at end of file From b42ece9a953aebb246d85920fe31814767f7be95 Mon Sep 17 00:00:00 2001 From: mseaward Date: Fri, 1 Feb 2019 16:00:09 -0400 Subject: [PATCH 10/15] Update get all witnesses function. --- dist/chain/src/ChainStore.js | 7 +++---- lib/chain/src/ChainStore.js | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/dist/chain/src/ChainStore.js b/dist/chain/src/ChainStore.js index a00b15e..eeb79ca 100644 --- a/dist/chain/src/ChainStore.js +++ b/dist/chain/src/ChainStore.js @@ -812,7 +812,6 @@ var ChainStore = function () { }, { key: "fetchWitnessAccounts", value: function fetchWitnessAccounts() { - var _this24 = this; return new Promise(function (resolve, reject) { Apis.instance().db_api().exec("lookup_witness_accounts", [0, 1000]).then(function (w) { if (w) { @@ -822,9 +821,9 @@ var ChainStore = function () { witnessArr.push(w[i][1]); // ids only } - _this24.witnesses = _this24.witnesses.merge(witnessArr); - _this24._updateObject(witnessArr, true); - resolve(_this24.witnesses); + this.witnesses = this.witnesses.merge(witnessArr); + this._updateObject(witnessArr, true); + resolve(this.witnesses); } else { resolve(null); } diff --git a/lib/chain/src/ChainStore.js b/lib/chain/src/ChainStore.js index 180b156..c8d5640 100644 --- a/lib/chain/src/ChainStore.js +++ b/lib/chain/src/ChainStore.js @@ -742,7 +742,6 @@ class ChainStore { * @memberof ChainStore */ fetchWitnessAccounts() { - var _this24 = this; return new Promise((resolve, reject) => { Apis.instance().db_api().exec("lookup_witness_accounts", [0, 1000]).then(function (w) { if (w) { @@ -752,9 +751,9 @@ class ChainStore { witnessArr.push(w[i][1]); // ids only } - _this24.witnesses = _this24.witnesses.merge(witnessArr); - _this24._updateObject(witnessArr, true); - resolve(_this24.witnesses); + this.witnesses = this.witnesses.merge(witnessArr); + this._updateObject(witnessArr, true); + resolve(this.witnesses); } else { resolve(null); } From 9cb0c63d75a4940e73c8aa3240f84c0b24d3180a Mon Sep 17 00:00:00 2001 From: mseaward Date: Fri, 1 Feb 2019 16:14:52 -0400 Subject: [PATCH 11/15] Rebuild --- dist/chain/src/ChainStore.js | 6 +++--- lib/chain/src/ChainStore.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/chain/src/ChainStore.js b/dist/chain/src/ChainStore.js index eeb79ca..a700bea 100644 --- a/dist/chain/src/ChainStore.js +++ b/dist/chain/src/ChainStore.js @@ -821,9 +821,9 @@ var ChainStore = function () { witnessArr.push(w[i][1]); // ids only } - this.witnesses = this.witnesses.merge(witnessArr); - this._updateObject(witnessArr, true); - resolve(this.witnesses); + this.witnesses = this.witnesses.set(witnessArr); + var witnesses_object = this._updateObject(witnessArr, true); + resolve(witnesses_object); } else { resolve(null); } diff --git a/lib/chain/src/ChainStore.js b/lib/chain/src/ChainStore.js index c8d5640..f5bcf22 100644 --- a/lib/chain/src/ChainStore.js +++ b/lib/chain/src/ChainStore.js @@ -751,9 +751,9 @@ class ChainStore { witnessArr.push(w[i][1]); // ids only } - this.witnesses = this.witnesses.merge(witnessArr); - this._updateObject(witnessArr, true); - resolve(this.witnesses); + this.witnesses = this.witnesses.set(witnessArr); + let witnesses_object = this._updateObject(witnessArr, true); + resolve(witnesses_object); } else { resolve(null); } From 877a0ce59f0eac7dacca4b626f34e740a50e02a6 Mon Sep 17 00:00:00 2001 From: mseaward Date: Mon, 4 Feb 2019 09:13:04 -0400 Subject: [PATCH 12/15] Rebuild --- dist/chain/src/ChainStore.js | 149 ++++++++++++++++++----------------- lib/chain/src/ChainStore.js | 5 +- 2 files changed, 79 insertions(+), 75 deletions(-) diff --git a/dist/chain/src/ChainStore.js b/dist/chain/src/ChainStore.js index a700bea..a8cfec2 100644 --- a/dist/chain/src/ChainStore.js +++ b/dist/chain/src/ChainStore.js @@ -97,6 +97,7 @@ var ChainStore = function () { this.get_account_refs_of_keys_calls = Immutable.Set(); this.account_history_requests = new Map(); ///< tracks pending history requests this.witness_by_account_id = new Map(); + this.witnesses = new Map(); this.account_by_witness_id = new Map(); this.committee_by_account_id = new Map(); this.objects_by_vote_id = new Map(); @@ -812,6 +813,8 @@ var ChainStore = function () { }, { key: "fetchWitnessAccounts", value: function fetchWitnessAccounts() { + var _this13 = this; + return new Promise(function (resolve, reject) { Apis.instance().db_api().exec("lookup_witness_accounts", [0, 1000]).then(function (w) { if (w) { @@ -821,8 +824,8 @@ var ChainStore = function () { witnessArr.push(w[i][1]); // ids only } - this.witnesses = this.witnesses.set(witnessArr); - var witnesses_object = this._updateObject(witnessArr, true); + _this13.witnesses = _this13.witnesses.set(witnessArr); + var witnesses_object = _this13._updateObject(witnessArr, true); resolve(witnesses_object); } else { resolve(null); @@ -839,17 +842,17 @@ var ChainStore = function () { }, { key: "fetchWitnessByAccount", value: function fetchWitnessByAccount(account_id) { - var _this13 = this; + var _this14 = this; return new Promise(function (resolve, reject) { Apis.instance().db_api().exec("get_witness_by_account", [account_id]).then(function (optional_witness_object) { if (optional_witness_object) { - _this13.witness_by_account_id = _this13.witness_by_account_id.set(optional_witness_object.witness_account, optional_witness_object.id); - var witness_object = _this13._updateObject(optional_witness_object, true); + _this14.witness_by_account_id = _this14.witness_by_account_id.set(optional_witness_object.witness_account, optional_witness_object.id); + var witness_object = _this14._updateObject(optional_witness_object, true); resolve(witness_object); } else { - _this13.witness_by_account_id = _this13.witness_by_account_id.set(account_id, null); - _this13.notifySubscribers(); + _this14.witness_by_account_id = _this14.witness_by_account_id.set(account_id, null); + _this14.notifySubscribers(); resolve(null); } }, reject); @@ -864,17 +867,17 @@ var ChainStore = function () { }, { key: "fetchCommitteeMemberByAccount", value: function fetchCommitteeMemberByAccount(account_id) { - var _this14 = this; + var _this15 = this; return new Promise(function (resolve, reject) { Apis.instance().db_api().exec("get_committee_member_by_account", [account_id]).then(function (optional_committee_object) { if (optional_committee_object) { - _this14.committee_by_account_id = _this14.committee_by_account_id.set(optional_committee_object.committee_member_account, optional_committee_object.id); - var committee_object = _this14._updateObject(optional_committee_object, true); + _this15.committee_by_account_id = _this15.committee_by_account_id.set(optional_committee_object.committee_member_account, optional_committee_object.id); + var committee_object = _this15._updateObject(optional_committee_object, true); resolve(committee_object); } else { - _this14.committee_by_account_id = _this14.committee_by_account_id.set(account_id, null); - _this14.notifySubscribers(); + _this15.committee_by_account_id = _this15.committee_by_account_id.set(account_id, null); + _this15.notifySubscribers(); resolve(null); } }, reject); @@ -894,7 +897,7 @@ var ChainStore = function () { }, { key: "fetchFullAccount", value: function fetchFullAccount(name_or_id) { - var _this15 = this; + var _this16 = this; if (DEBUG) console.log("Fetch full account: ", name_or_id); @@ -917,8 +920,8 @@ var ChainStore = function () { Apis.instance().db_api().exec("get_full_accounts", [[name_or_id], true]).then(function (results) { if (results.length === 0) { if (ChainValidation.is_object_id(name_or_id)) { - _this15.objects_by_id = _this15.objects_by_id.set(name_or_id, null); - _this15.notifySubscribers(); + _this16.objects_by_id = _this16.objects_by_id.set(name_or_id, null); + _this16.notifySubscribers(); } return; } @@ -938,7 +941,7 @@ var ChainStore = function () { proposals = full_account.proposals; - _this15.accounts_by_name = _this15.accounts_by_name.set(account.name, account.id); + _this16.accounts_by_name = _this16.accounts_by_name.set(account.name, account.id); account.referrer_name = referrer_name; account.lifetime_referrer_name = lifetime_referrer_name; account.registrar_name = registrar_name; @@ -951,57 +954,57 @@ var ChainStore = function () { account.proposals = new Immutable.Set(); account.vesting_balances = account.vesting_balances.withMutations(function (set) { vesting_balances.forEach(function (vb) { - _this15._updateObject(vb, false); + _this16._updateObject(vb, false); set.add(vb.id); }); }); votes.forEach(function (v) { - return _this15._updateObject(v, false); + return _this16._updateObject(v, false); }); account.balances = account.balances.withMutations(function (map) { full_account.balances.forEach(function (b) { - _this15._updateObject(b, false); + _this16._updateObject(b, false); map.set(b.asset_type, b.id); }); }); account.orders = account.orders.withMutations(function (set) { limit_orders.forEach(function (order) { - _this15._updateObject(order, false); + _this16._updateObject(order, false); set.add(order.id); }); }); account.pending_dividend_payments = account.pending_dividend_payments.withMutations(function (set) { pending_dividend_payments.forEach(function (payments) { - _this15._updateObject(payments, false); + _this16._updateObject(payments, false); set.add(payments); }); }); account.call_orders = account.call_orders.withMutations(function (set) { call_orders.forEach(function (co) { - _this15._updateObject(co, false); + _this16._updateObject(co, false); set.add(co.id); }); }); account.proposals = account.proposals.withMutations(function (set) { proposals.forEach(function (p) { - _this15._updateObject(p, false); + _this16._updateObject(p, false); set.add(p.id); }); }); - _this15._updateObject(statistics, false); - var updated_account = _this15._updateObject(account, false); - _this15.fetchRecentHistory(updated_account); - _this15.notifySubscribers(); + _this16._updateObject(statistics, false); + var updated_account = _this16._updateObject(account, false); + _this16.fetchRecentHistory(updated_account); + _this16.notifySubscribers(); }, function (error) { console.log("Error: ", error); - if (ChainValidation.is_object_id(name_or_id)) _this15.objects_by_id = _this15.objects_by_id.delete(name_or_id);else _this15.accounts_by_name = _this15.accounts_by_name.delete(name_or_id); + if (ChainValidation.is_object_id(name_or_id)) _this16.objects_by_id = _this16.objects_by_id.delete(name_or_id);else _this16.accounts_by_name = _this16.accounts_by_name.delete(name_or_id); }); } return undefined; @@ -1044,7 +1047,7 @@ var ChainStore = function () { }, { key: "fetchRecentHistory", value: function fetchRecentHistory(account) { - var _this16 = this; + var _this17 = this; var limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100; @@ -1076,7 +1079,7 @@ var ChainStore = function () { pending_request.promise = new Promise(function (resolve, reject) { Apis.instance().history_api().exec("get_account_history", [account_id, most_recent, limit, start]).then(function (operations) { - var current_account = _this16.objects_by_id.get(account_id); + var current_account = _this17.objects_by_id.get(account_id); var current_history = current_account.get('history'); if (!current_history) current_history = Immutable.List(); var updated_history = Immutable.fromJS(operations); @@ -1086,18 +1089,18 @@ var ChainStore = function () { } }); var updated_account = current_account.set('history', updated_history); - _this16.objects_by_id = _this16.objects_by_id.set(account_id, updated_account); + _this17.objects_by_id = _this17.objects_by_id.set(account_id, updated_account); //if( current_history != updated_history ) // this._notifyAccountSubscribers( account_id ) - var pending_request = _this16.account_history_requests.get(account_id); - _this16.account_history_requests.delete(account_id); + var pending_request = _this17.account_history_requests.get(account_id); + _this17.account_history_requests.delete(account_id); if (pending_request.requests > 0) { // it looks like some more history may have come in while we were // waiting on the result, lets fetch anything new before we resolve // this query. - _this16.fetchRecentHistory(updated_account, limit).then(resolve, reject); + _this17.fetchRecentHistory(updated_account, limit).then(resolve, reject); } else resolve(updated_account); }); // end then }); @@ -1403,7 +1406,7 @@ var ChainStore = function () { }, { key: "getTournaments", value: function getTournaments(last_tournament_id) { - var _this17 = this; + var _this18 = this; var limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5; var start_tournament_id = arguments[2]; @@ -1412,17 +1415,17 @@ var ChainStore = function () { return Apis.instance().db_api().exec("get_tournaments", [last_tournament_id, limit, start_tournament_id]).then(function (tournaments) { var list = Immutable.List(); - _this17.setLastTournamentId(null); + _this18.setLastTournamentId(null); if (tournaments && tournaments.length) { list = list.withMutations(function (l) { tournaments.forEach(function (tournament) { - if (!_this17.objects_by_id.has(tournament.id)) { - _this17._updateObject(tournament, false); + if (!_this18.objects_by_id.has(tournament.id)) { + _this18._updateObject(tournament, false); } - l.unshift(_this17.objects_by_id.get(tournament.id)); + l.unshift(_this18.objects_by_id.get(tournament.id)); }); }); } @@ -1433,34 +1436,34 @@ var ChainStore = function () { }, { key: "getLastTournamentId", value: function getLastTournamentId() { - var _this18 = this; + var _this19 = this; return new Promise(function (resolve, reject) { - if (_this18.last_tournament_id === undefined) { + if (_this19.last_tournament_id === undefined) { Apis.instance().db_api().exec("get_tournaments", [tournament_prefix + '0', 1, tournament_prefix + '0']).then(function (tournaments) { - _this18.setLastTournamentId(null); + _this19.setLastTournamentId(null); if (tournaments && tournaments.length) { tournaments.forEach(function (tournament) { - _this18._updateObject(tournament, false); + _this19._updateObject(tournament, false); }); } - resolve(_this18.last_tournament_id); + resolve(_this19.last_tournament_id); }); } else { - resolve(_this18.last_tournament_id); + resolve(_this19.last_tournament_id); } }); } }, { key: "getObjectsByVoteIds", value: function getObjectsByVoteIds(vote_ids) { - var _this19 = this; + var _this20 = this; var result = []; var missing = []; @@ -1479,7 +1482,7 @@ var ChainStore = function () { console.log("vote objects ===========> ", vote_obj_array); for (var _i2 = 0; _i2 < vote_obj_array.length; ++_i2) { if (vote_obj_array[_i2]) { - _this19._updateObject(vote_obj_array[_i2]); + _this20._updateObject(vote_obj_array[_i2]); } } }, function (error) { @@ -1513,17 +1516,17 @@ var ChainStore = function () { }, { key: "addProposalData", value: function addProposalData(approvals, objectId) { - var _this20 = this; + var _this21 = this; approvals.forEach(function (id) { - var impactedAccount = _this20.objects_by_id.get(id); + var impactedAccount = _this21.objects_by_id.get(id); if (impactedAccount) { var proposals = impactedAccount.get("proposals"); if (!proposals.includes(objectId)) { proposals = proposals.add(objectId); impactedAccount = impactedAccount.set("proposals", proposals); - _this20._updateObject(impactedAccount.toJS(), false); + _this21._updateObject(impactedAccount.toJS(), false); } } }); @@ -1540,16 +1543,16 @@ var ChainStore = function () { }, { key: "__getBlocksForScan", value: function __getBlocksForScan(lastBlock) { - var _this21 = this; + var _this22 = this; var db_api = Apis.instance().db_api(); return new Promise(function (success, fail) { - var scanToBlock = _this21.last_processed_block; + var scanToBlock = _this22.last_processed_block; if (lastBlock) return success({ lastBlock: lastBlock, scanToBlock: scanToBlock }); db_api.exec("get_dynamic_global_properties", []).then(function (globalProperties) { - lastBlock = _this21.last_processed_block = globalProperties['head_block_number']; + lastBlock = _this22.last_processed_block = globalProperties['head_block_number']; scanToBlock = globalProperties['head_block_number'] - 2000; scanToBlock = scanToBlock < 0 ? 1 : scanToBlock; return success({ lastBlock: lastBlock, scanToBlock: scanToBlock }); @@ -1559,7 +1562,7 @@ var ChainStore = function () { }, { key: "__bindBlock", value: function __bindBlock(lastBlock, scanToBlock, isInit) { - var _this22 = this; + var _this23 = this; var db_api = Apis.instance().db_api(); return new Promise(function (success, fail) { @@ -1567,22 +1570,22 @@ var ChainStore = function () { block.id = lastBlock; if (typeof block.timestamp === "string") block.timestamp += "+00:00"; block.timestamp = new Date(block.timestamp); - _this22.getWitnessAccount(block.witness).then(function (witness) { + _this23.getWitnessAccount(block.witness).then(function (witness) { block.witness_account_name = witness.name; - if (!_this22.recent_blocks_by_id.get(lastBlock)) { + if (!_this23.recent_blocks_by_id.get(lastBlock)) { - _this22.recent_blocks_by_id = _this22.recent_blocks_by_id.set(lastBlock, block); + _this23.recent_blocks_by_id = _this23.recent_blocks_by_id.set(lastBlock, block); - if (_this22.last_processed_block < lastBlock) _this22.last_processed_block = lastBlock; + if (_this23.last_processed_block < lastBlock) _this23.last_processed_block = lastBlock; if (!isInit) { - _this22.recent_blocks = _this22.recent_blocks.unshift(block); - if (_this22.recent_blocks.size > block_stack_size) { - _this22.recent_blocks = _this22.recent_blocks.pop(); + _this23.recent_blocks = _this23.recent_blocks.unshift(block); + if (_this23.recent_blocks.size > block_stack_size) { + _this23.recent_blocks = _this23.recent_blocks.pop(); } - } else if (_this22.recent_blocks.size < block_stack_size) { - _this22.recent_blocks = _this22.recent_blocks.push(block); + } else if (_this23.recent_blocks.size < block_stack_size) { + _this23.recent_blocks = _this23.recent_blocks.push(block); } block.transactions.forEach(function (tx) { @@ -1590,17 +1593,17 @@ var ChainStore = function () { op[1].block_id = lastBlock; op[1].created_at = block.timestamp; if (!isInit) { - _this22.recent_operations = _this22.recent_operations.unshift(op); + _this23.recent_operations = _this23.recent_operations.unshift(op); } else { - if (_this22.recent_operations.size < operations_stack_size) { - _this22.recent_operations = _this22.recent_operations.push(op); + if (_this23.recent_operations.size < operations_stack_size) { + _this23.recent_operations = _this23.recent_operations.push(op); } - if (_this22.recent_operations.size >= operations_stack_size && _this22.recent_blocks.size >= block_stack_size) { + if (_this23.recent_operations.size >= operations_stack_size && _this23.recent_blocks.size >= block_stack_size) { scanToBlock = lastBlock; } } - if (_this22.recent_operations.size > operations_stack_size) { - _this22.recent_operations = _this22.recent_operations.pop(); + if (_this23.recent_operations.size > operations_stack_size) { + _this23.recent_operations = _this23.recent_operations.pop(); } }); }); @@ -1609,7 +1612,7 @@ var ChainStore = function () { if (lastBlock <= scanToBlock) { return success(); } - _this22.__bindBlock(lastBlock, scanToBlock, isInit).then(function () { + _this23.__bindBlock(lastBlock, scanToBlock, isInit).then(function () { return success(); }); }); @@ -1619,7 +1622,7 @@ var ChainStore = function () { }, { key: "fetchRecentOperations", value: function fetchRecentOperations() { - var _this23 = this; + var _this24 = this; var lastBlock = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; @@ -1630,9 +1633,9 @@ var ChainStore = function () { var lastBlock = _ref.lastBlock, scanToBlock = _ref.scanToBlock; - _this23.__bindBlock(lastBlock, scanToBlock, isInit).then(function () { + _this24.__bindBlock(lastBlock, scanToBlock, isInit).then(function () { if (isInit) { - _this23.store_initialized = true; + _this24.store_initialized = true; } }); }); diff --git a/lib/chain/src/ChainStore.js b/lib/chain/src/ChainStore.js index f5bcf22..d399a59 100644 --- a/lib/chain/src/ChainStore.js +++ b/lib/chain/src/ChainStore.js @@ -75,7 +75,8 @@ class ChainStore { this.balance_objects_by_address = Immutable.Map(); this.get_account_refs_of_keys_calls = Immutable.Set(); this.account_history_requests = new Map(); ///< tracks pending history requests - this.witness_by_account_id = new Map(); + this.witness_by_account_id = new Map(); + this.witnesses = new Map(); this.account_by_witness_id = new Map(); this.committee_by_account_id = new Map(); this.objects_by_vote_id = new Map(); @@ -743,7 +744,7 @@ class ChainStore { */ fetchWitnessAccounts() { return new Promise((resolve, reject) => { - Apis.instance().db_api().exec("lookup_witness_accounts", [0, 1000]).then(function (w) { + Apis.instance().db_api().exec("lookup_witness_accounts", [0, 1000]).then((w) => { if (w) { let witnessArr = []; From 251ecfb3e32a101f182a318fa88190720b7d25c5 Mon Sep 17 00:00:00 2001 From: mseaward Date: Mon, 4 Feb 2019 09:22:26 -0400 Subject: [PATCH 13/15] Update to merge instead of set. --- dist/chain/src/ChainStore.js | 2 +- lib/chain/src/ChainStore.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/chain/src/ChainStore.js b/dist/chain/src/ChainStore.js index a8cfec2..870f2c5 100644 --- a/dist/chain/src/ChainStore.js +++ b/dist/chain/src/ChainStore.js @@ -824,7 +824,7 @@ var ChainStore = function () { witnessArr.push(w[i][1]); // ids only } - _this13.witnesses = _this13.witnesses.set(witnessArr); + _this13.witnesses = _this13.witnesses.merge(witnessArr); var witnesses_object = _this13._updateObject(witnessArr, true); resolve(witnesses_object); } else { diff --git a/lib/chain/src/ChainStore.js b/lib/chain/src/ChainStore.js index d399a59..cd3a3f4 100644 --- a/lib/chain/src/ChainStore.js +++ b/lib/chain/src/ChainStore.js @@ -752,7 +752,7 @@ class ChainStore { witnessArr.push(w[i][1]); // ids only } - this.witnesses = this.witnesses.set(witnessArr); + this.witnesses = this.witnesses.merge(witnessArr); let witnesses_object = this._updateObject(witnessArr, true); resolve(witnesses_object); } else { From 92c367adfd8d9ef0c6be900d32efc104c36582a9 Mon Sep 17 00:00:00 2001 From: mseaward Date: Mon, 4 Feb 2019 10:17:51 -0400 Subject: [PATCH 14/15] Change witnesses to Immutable Set instead of a Map --- dist/chain/src/ChainStore.js | 2 +- lib/chain/src/ChainStore.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/chain/src/ChainStore.js b/dist/chain/src/ChainStore.js index 870f2c5..58a11bd 100644 --- a/dist/chain/src/ChainStore.js +++ b/dist/chain/src/ChainStore.js @@ -97,7 +97,7 @@ var ChainStore = function () { this.get_account_refs_of_keys_calls = Immutable.Set(); this.account_history_requests = new Map(); ///< tracks pending history requests this.witness_by_account_id = new Map(); - this.witnesses = new Map(); + this.witnesses = Immutable.Set(); this.account_by_witness_id = new Map(); this.committee_by_account_id = new Map(); this.objects_by_vote_id = new Map(); diff --git a/lib/chain/src/ChainStore.js b/lib/chain/src/ChainStore.js index cd3a3f4..f6bc7f1 100644 --- a/lib/chain/src/ChainStore.js +++ b/lib/chain/src/ChainStore.js @@ -76,7 +76,7 @@ class ChainStore { this.get_account_refs_of_keys_calls = Immutable.Set(); this.account_history_requests = new Map(); ///< tracks pending history requests this.witness_by_account_id = new Map(); - this.witnesses = new Map(); + this.witnesses = Immutable.Set(); this.account_by_witness_id = new Map(); this.committee_by_account_id = new Map(); this.objects_by_vote_id = new Map(); From e3e296a5e689031cf98a96466901d4666acd2e7e Mon Sep 17 00:00:00 2001 From: mseaward Date: Mon, 4 Feb 2019 10:25:00 -0400 Subject: [PATCH 15/15] Update object updating after retrieving the list of all witnesses. --- dist/chain/src/ChainStore.js | 4 ++-- lib/chain/src/ChainStore.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/chain/src/ChainStore.js b/dist/chain/src/ChainStore.js index 58a11bd..7cd3a6e 100644 --- a/dist/chain/src/ChainStore.js +++ b/dist/chain/src/ChainStore.js @@ -825,8 +825,8 @@ var ChainStore = function () { } _this13.witnesses = _this13.witnesses.merge(witnessArr); - var witnesses_object = _this13._updateObject(witnessArr, true); - resolve(witnesses_object); + _this13._updateObject(witnessArr, true); + resolve(_this13.witnesses); } else { resolve(null); } diff --git a/lib/chain/src/ChainStore.js b/lib/chain/src/ChainStore.js index f6bc7f1..7a21360 100644 --- a/lib/chain/src/ChainStore.js +++ b/lib/chain/src/ChainStore.js @@ -753,8 +753,8 @@ class ChainStore { } this.witnesses = this.witnesses.merge(witnessArr); - let witnesses_object = this._updateObject(witnessArr, true); - resolve(witnesses_object); + this._updateObject(witnessArr, true); + resolve(this.witnesses); } else { resolve(null); }